From eccd9596d68d2de3d2d27b4c0be327296a2fedf9 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Fri, 29 Oct 2021 11:20:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../excel/analysis/v07/StyleWrapper.java | 14 ++++ .../analysis/v07/handlers/CellTagHandler.java | 38 +++++---- .../excel/metadata/format/DataFormatter.java | 6 +- .../holder/xlsx/XlsxReadWorkbookHolder.java | 31 ++++++- .../com/alibaba/excel/util/PositionUtils.java | 83 ++++++++++++++----- .../test/core/large/LargeDataTest.java | 13 ++- 6 files changed, 142 insertions(+), 43 deletions(-) create mode 100644 src/main/java/com/alibaba/excel/analysis/v07/StyleWrapper.java diff --git a/src/main/java/com/alibaba/excel/analysis/v07/StyleWrapper.java b/src/main/java/com/alibaba/excel/analysis/v07/StyleWrapper.java new file mode 100644 index 00000000..378d78f1 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/StyleWrapper.java @@ -0,0 +1,14 @@ +package com.alibaba.excel.analysis.v07; + +import com.alibaba.excel.metadata.data.DataFormatData; + +import lombok.Data; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; + +@Data +public class StyleWrapper { + + private XSSFCellStyle xssfCellStyle; + private DataFormatData dataFormatData; + +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java index a6fd5340..66afa565 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java @@ -2,19 +2,16 @@ package com.alibaba.excel.analysis.v07.handlers; import java.math.BigDecimal; -import com.alibaba.excel.constant.BuiltinFormats; +import com.alibaba.excel.analysis.v07.StyleWrapper; import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.enums.CellDataTypeEnum; -import com.alibaba.excel.metadata.data.DataFormatData; import com.alibaba.excel.metadata.data.ReadCellData; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder; import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.util.PositionUtils; import com.alibaba.excel.util.StringUtils; -import org.apache.poi.xssf.model.StylesTable; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.xml.sax.Attributes; /** @@ -51,17 +48,28 @@ public class CellTagHandler extends AbstractXlsxTagHandler { } else { dateFormatIndexInteger = Integer.parseInt(dateFormatIndex); } - StylesTable stylesTable = xlsxReadContext.xlsxReadWorkbookHolder().getStylesTable(); - if (stylesTable == null) { - return; - } - XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); - short dataFormat = xssfCellStyle.getDataFormat(); - DataFormatData dataFormatData = new DataFormatData(); - dataFormatData.setIndex(dataFormat); - dataFormatData.setFormat(BuiltinFormats.getBuiltinFormat(dataFormat, - xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale())); - xlsxReadSheetHolder.getTempCellData().setDataFormatData(dataFormatData); + + + + StyleWrapper styleWrapper = xlsxReadContext.xlsxReadWorkbookHolder().styleWrapper(dateFormatIndexInteger); + + + + //XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); + //short dataFormat = xssfCellStyle.getDataFormat(); + //DataFormatData dataFormatData = new DataFormatData(); + //dataFormatData.setIndex(dataFormat); + //dataFormatData.setFormat(BuiltinFormats.getBuiltinFormat(dataFormat, + // xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale())); + //xlsxReadSheetHolder.getTempCellData().setDataFormatData(dataFormatData); + // + //XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); + //short dataFormat = xssfCellStyle.getDataFormat(); + //DataFormatData dataFormatData = new DataFormatData(); + //dataFormatData.setIndex(dataFormat); + //dataFormatData.setFormat(BuiltinFormats.getBuiltinFormat(dataFormat, + // xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale())); + xlsxReadSheetHolder.getTempCellData().setDataFormatData(styleWrapper.getDataFormatData()); } @Override diff --git a/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java b/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java index bf76404f..feb42522 100644 --- a/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java +++ b/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java @@ -642,10 +642,14 @@ public class DataFormatter { * @param dataFormatString * @return a formatted number string */ + + private static final Pattern CELL_REF_PATTERN = Pattern.compile("E(\\d)"); + private String getFormattedNumberString(BigDecimal data, Short dataFormat, String dataFormatString) { Format numberFormat = getFormat(data.doubleValue(), dataFormat, dataFormatString); String formatted = numberFormat.format(data); - return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation + return CELL_REF_PATTERN.matcher(formatted).replaceFirst("E+$1"); + //return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation } /** diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java index 066131d3..ee8155a0 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java @@ -1,13 +1,20 @@ package com.alibaba.excel.read.metadata.holder.xlsx; -import javax.xml.parsers.SAXParserFactory; +import java.util.Map; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.xssf.model.StylesTable; +import javax.xml.parsers.SAXParserFactory; +import com.alibaba.excel.analysis.v07.StyleWrapper; +import com.alibaba.excel.constant.BuiltinFormats; +import com.alibaba.excel.metadata.data.DataFormatData; import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.util.MapUtils; + +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.xssf.model.StylesTable; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; /** * Workbook holder @@ -35,6 +42,8 @@ public class XlsxReadWorkbookHolder extends ReadWorkbookHolder { */ private StylesTable stylesTable; + private Map map = MapUtils.newHashMap(); + public XlsxReadWorkbookHolder(ReadWorkbook readWorkbook) { super(readWorkbook); this.saxParserFactoryName = readWorkbook.getXlsxSAXParserFactoryName(); @@ -64,4 +73,20 @@ public class XlsxReadWorkbookHolder extends ReadWorkbookHolder { public void setStylesTable(StylesTable stylesTable) { this.stylesTable = stylesTable; } + + public StyleWrapper styleWrapper(int dateFormatIndexInteger) { + return map.computeIfAbsent(dateFormatIndexInteger, key -> { + StyleWrapper s = new StyleWrapper(); + if (stylesTable == null) { + return s; + } + XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); + DataFormatData dataFormatData = new DataFormatData(); + dataFormatData.setIndex(xssfCellStyle.getDataFormat()); + dataFormatData.setFormat(BuiltinFormats.getBuiltinFormat(dataFormatData.getIndex(), + xssfCellStyle.getDataFormatString(), globalConfiguration().getLocale())); + return s; + }); + + } } diff --git a/src/main/java/com/alibaba/excel/util/PositionUtils.java b/src/main/java/com/alibaba/excel/util/PositionUtils.java index 48c5cde5..66c5b516 100644 --- a/src/main/java/com/alibaba/excel/util/PositionUtils.java +++ b/src/main/java/com/alibaba/excel/util/PositionUtils.java @@ -4,8 +4,6 @@ import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.poi.ss.util.CellReference; - /** * @author jipengfei */ @@ -54,30 +52,73 @@ public class PositionUtils { return -1; } + private static final char ABSOLUTE_REFERENCE_MARKER = '$'; + private static final int COL_RADIX = 'Z' - 'A' + 1; + + public static int getCol(String currentCellIndex, Integer before) { - if (currentCellIndex != null) { - int plingPos = currentCellIndex.lastIndexOf(SHEET_NAME_DELIMITER); - String cell = currentCellIndex.substring(plingPos + 1).toUpperCase(Locale.ROOT); - Matcher matcher = CELL_REF_PATTERN.matcher(cell); - if (!matcher.matches()) { - throw new IllegalArgumentException("Invalid CellReference: " + currentCellIndex); - } - String col = matcher.group(1); + final int length = currentCellIndex.length(); - if (col.length() > 0 && col.charAt(0) == REDUNDANT_CHARACTERS) { - col = col.substring(1); + int offset = currentCellIndex.charAt(0) == ABSOLUTE_REFERENCE_MARKER ? 1 : 0; + int col = 0; + for (; offset < length; offset++) { + final char c = currentCellIndex.charAt(offset); + if (c == ABSOLUTE_REFERENCE_MARKER) { + offset++; + break; //next there must be digits } - if (col.length() == 0) { - return -1; - } else { - return CellReference.convertColStringToIndex(col); - } - } else { - if (before == null) { - before = -1; + if (isAsciiDigit(c)) { + break; } - return before + 1; + col = col * COL_RADIX + toUpperCase(c) - (int) 'A' + 1; } + return col - 1; + + //if (currentCellIndex != null) { + // int plingPos = currentCellIndex.lastIndexOf(SHEET_NAME_DELIMITER); + // String cell = currentCellIndex.substring(plingPos + 1).toUpperCase(Locale.ROOT); + // Matcher matcher = CELL_REF_PATTERN.matcher(cell); + // if (!matcher.matches()) { + // throw new IllegalArgumentException("Invalid CellReference: " + currentCellIndex); + // } + // String col = matcher.group(1); + // + // if (col.length() > 0 && col.charAt(0) == REDUNDANT_CHARACTERS) { + // col = col.substring(1); + // } + // if (col.length() == 0) { + // return -1; + // } else { + // return CellReference.convertColStringToIndex(col); + // } + //} else { + // if (before == null) { + // before = -1; + // } + // return before + 1; + //} + } + + private static final boolean isAsciiDigit(char c) { + return '0' <= c && c <= '9'; + } + + private final static char toUpperCase(char c) { + if (isAsciiUpperCase(c)) { + return c; + } + if (isAsciiLowerCase(c)) { + return (char) (c + ('A' - 'a')); + } + throw new IllegalArgumentException("Unexpected char: " + c); + } + + private static final boolean isAsciiLowerCase(char c) { + return 'a' <= c && c <= 'z'; + } + + private static final boolean isAsciiUpperCase(char c) { + return 'A' <= c && c <= 'Z'; } } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java index 682772fb..af3c2e31 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/large/LargeDataTest.java @@ -51,7 +51,9 @@ public class LargeDataTest { } @Test - public void t01Read() { + public void t01Read() throws Exception{ + Thread.sleep(10*1000L); + long start = System.currentTimeMillis(); EasyExcel.read(TestFileUtil.getPath() + "large" + File.separator + "large07.xlsx", LargeData.class, new LargeDataListener()).headRowNumber(2).sheet().doRead(); @@ -59,14 +61,19 @@ public class LargeDataTest { } @Test - public void t02Fill() { + public void t02Fill() throws Exception{ + Thread.sleep(10*1000L); + long start = System.currentTimeMillis(); + ExcelWriter excelWriter = EasyExcel.write(fileFill07).withTemplate(template07).build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); - for (int j = 0; j < 100; j++) { + for (int j = 0; j < 50; j++) { excelWriter.fill(data(), writeSheet); LOGGER.info("{} fill success.", j); } excelWriter.finish(); + LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start); + } @Test