diff --git a/README.md b/README.md index 9b4fec78..9664d654 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,18 @@ EasyExcel [QQ2群: 1097936804](https://jq.qq.com/?_wv=1027&k=j5zEy6Xl) [钉钉1群(已满): 21960511](https://qr.dingtalk.com/action/joingroup?code=v1,k1,cchz6k12ci9B08NNqhNRFGXocNVHrZtW0kaOtTKg/Rk=&_dt_no_comment=1&origin=11) [钉钉2群(已满): 32796397](https://qr.dingtalk.com/action/joingroup?code=v1,k1,jyU9GtEuNU5S0QTyklqYcYJ8qDZtUuTPMM7uPZTS8Hs=&_dt_no_comment=1&origin=11) -[钉钉3群: 33797247](https://qr.dingtalk.com/action/joingroup?code=v1,k1,3UGlEScTGQaHpW2cIRo+gkxJ9EVZ5fz26M6nW3uFP30=&_dt_no_comment=1&origin=11) - +[钉钉3群(已满): 33797247](https://qr.dingtalk.com/action/joingroup?code=v1,k1,3UGlEScTGQaHpW2cIRo+gkxJ9EVZ5fz26M6nW3uFP30=&_dt_no_comment=1&origin=11) +[钉钉4群: 33491624](https://qr.dingtalk.com/action/joingroup?code=v1,k1,V14Pb65Too70rQkEaJ9ohb6lZBZbtp6jIL/q9EWh9vA=&_dt_no_comment=1&origin=11) [官方网站: https://yuque.com/easyexcel](https://www.yuque.com/easyexcel/doc/easyexcel) [常见问题](https://www.yuque.com/easyexcel/faq) #### 因为公司不方便用QQ,所以建议加钉钉群 # JAVA解析Excel工具EasyExcel -Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便 +Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便 ## 64M内存1分钟内读取75M(46W行25列)的Excel -当然还有急速模式能更快,但是内存占用会在100M多一点 +当然还有极速模式能更快,但是内存占用会在100M多一点 ![img](img/readme/large.png) ## 相关文档 @@ -81,7 +81,7 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja @GetMapping("download") public void download(HttpServletResponse response) throws IOException { // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman - response.setContentType("application/vnd.ms-excel"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20"); diff --git a/pom.xml b/pom.xml index 641dd476..b5ae5cbf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 2.2.7 + 3.0.0-beta1 jar easyexcel @@ -16,7 +16,7 @@ UTF-8 - 1.6 + 1.8 true true @@ -60,22 +60,22 @@ org.apache.poi poi - 3.17 + 4.1.2 org.apache.poi poi-ooxml - 3.17 + 4.1.2 org.apache.poi poi-ooxml-schemas - 3.17 + 4.1.2 cglib cglib - 3.1 + 3.3.0 org.slf4j @@ -85,8 +85,15 @@ org.ehcache ehcache - 3.4.0 + 3.8.1 + + org.projectlombok + lombok + 1.18.20 + provided + + ch.qos.logback @@ -100,12 +107,6 @@ 1.2.71 test - - org.projectlombok - lombok - 1.18.8 - test - org.springframework.boot spring-boot @@ -121,7 +122,7 @@ junit junit - 4.12 + 4.13.1 test @@ -187,8 +188,8 @@ org.apache.maven.plugins maven-compiler-plugin - 1.6 - 1.6 + 1.8 + 1.8 @@ -232,6 +233,19 @@ + + org.projectlombok + lombok-maven-plugin + 1.18.20.0 + + + generate-sources + + delombok + + + + diff --git a/src/main/java/com/alibaba/excel/ExcelWriter.java b/src/main/java/com/alibaba/excel/ExcelWriter.java index 0eafecde..2f5b61d2 100644 --- a/src/main/java/com/alibaba/excel/ExcelWriter.java +++ b/src/main/java/com/alibaba/excel/ExcelWriter.java @@ -3,6 +3,8 @@ package com.alibaba.excel; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import org.slf4j.Logger; @@ -142,7 +144,7 @@ public class ExcelWriter { * Write to this sheet * @return this current writer */ - public ExcelWriter write(List data, WriteSheet writeSheet) { + public ExcelWriter write(Collection data, WriteSheet writeSheet) { return write(data, writeSheet, null); } @@ -157,7 +159,7 @@ public class ExcelWriter { * Write to this table * @return this */ - public ExcelWriter write(List data, WriteSheet writeSheet, WriteTable writeTable) { + public ExcelWriter write(Collection data, WriteSheet writeSheet, WriteTable writeTable) { excelBuilder.addContent(data, writeSheet, writeTable); return this; } @@ -194,7 +196,7 @@ public class ExcelWriter { * @param sheet * Write to this sheet * @return this current writer - * @deprecated please use {@link ExcelWriter#write(List, WriteSheet)} + * @deprecated please use {@link ExcelWriter#write(Collection, WriteSheet)} */ @Deprecated public ExcelWriter write(List data, Sheet sheet) { @@ -211,7 +213,7 @@ public class ExcelWriter { * @param table * Write to this table * @return this - * @deprecated * @deprecated please use {@link ExcelWriter#write(List, WriteSheet,WriteTable)} + * @deprecated * @deprecated please use {@link ExcelWriter#write(Collection, WriteSheet,WriteTable)} */ @Deprecated public ExcelWriter write(List data, Sheet sheet, Table table) { @@ -246,7 +248,7 @@ public class ExcelWriter { * @param sheet * Write to this sheet * @return this current writer - * @deprecated please use {@link ExcelWriter#write(List, WriteSheet)} + * @deprecated please use {@link ExcelWriter#write(Collection, WriteSheet)} */ @Deprecated public ExcelWriter write0(List data, Sheet sheet) { @@ -263,7 +265,7 @@ public class ExcelWriter { * @param table * Write to this table * @return this - * @deprecated * @deprecated please use {@link ExcelWriter#write(List, WriteSheet,WriteTable)} + * @deprecated * @deprecated please use {@link ExcelWriter#write(Collection, WriteSheet,WriteTable)} */ @Deprecated public ExcelWriter write0(List data, Sheet sheet, Table table) { @@ -278,7 +280,7 @@ public class ExcelWriter { * @param sheet * Write to this sheet * @return this current writer - * @deprecated please use {@link ExcelWriter#write(List, WriteSheet)} + * @deprecated please use {@link ExcelWriter#write(Collection, WriteSheet)} */ @Deprecated public ExcelWriter write1(List data, Sheet sheet) { @@ -295,7 +297,7 @@ public class ExcelWriter { * @param table * Write to this table * @return this - * @deprecated * @deprecated please use {@link ExcelWriter#write(List, WriteSheet,WriteTable)} + * @deprecated * @deprecated please use {@link ExcelWriter#write(Collection, WriteSheet,WriteTable)} */ @Deprecated public ExcelWriter write1(List data, Sheet sheet, Table table) { diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java index 5487ee10..e049dbfc 100644 --- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java @@ -3,6 +3,7 @@ package com.alibaba.excel.analysis; import java.io.InputStream; import java.util.List; +import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; import org.apache.poi.poifs.crypt.Decryptor; import org.apache.poi.poifs.filesystem.DocumentFactoryHelper; @@ -26,7 +27,6 @@ import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder; import com.alibaba.excel.support.ExcelTypeEnum; -import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.DateUtils; import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.NumberDataFormatterUtils; diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java index f78d4102..5f18b841 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java @@ -3,14 +3,6 @@ package com.alibaba.excel.analysis.v03.handlers; import java.math.BigDecimal; import java.util.Map; -import com.alibaba.excel.enums.RowTypeEnum; -import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.ss.usermodel.CellType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.context.xls.XlsReadContext; @@ -19,6 +11,13 @@ import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.metadata.Cell; import com.alibaba.excel.metadata.CellData; +import org.apache.poi.hssf.model.HSSFFormulaParser; +import org.apache.poi.hssf.record.FormulaRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.ss.usermodel.CellType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Record handler * @@ -32,7 +31,7 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig public void processRecord(XlsReadContext xlsReadContext, Record record) { FormulaRecord frec = (FormulaRecord)record; Map cellMap = xlsReadContext.xlsReadSheetHolder().getCellMap(); - CellData tempCellData = new CellData(); + CellData tempCellData = new CellData<>(); tempCellData.setRowIndex(frec.getRow()); tempCellData.setColumnIndex((int)frec.getColumn()); CellType cellType = CellType.forInt(frec.getCachedResultType()); @@ -58,8 +57,9 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler implements Ig tempCellData.setNumberValue(BigDecimal.valueOf(frec.getValue())); Integer dataFormat = xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(frec); - tempCellData.setDataFormat(dataFormat); - tempCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, + Short dataFormatShort = dataFormat.shortValue(); + tempCellData.setDataFormat(dataFormatShort); + tempCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormatShort, xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(frec), xlsReadContext.readSheetHolder().getGlobalConfiguration().getLocale())); cellMap.put((int)frec.getColumn(), tempCellData); diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java index 50608095..f9e27c7a 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java @@ -2,15 +2,15 @@ package com.alibaba.excel.analysis.v03.handlers; import java.math.BigDecimal; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.Record; - import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler; import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.context.xls.XlsReadContext; import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.metadata.CellData; +import org.apache.poi.hssf.record.NumberRecord; +import org.apache.poi.hssf.record.Record; + /** * Record handler * @@ -21,8 +21,9 @@ public class NumberRecordHandler extends AbstractXlsRecordHandler implements Ign @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { NumberRecord nr = (NumberRecord)record; - CellData cellData = CellData.newInstance(BigDecimal.valueOf(nr.getValue()), nr.getRow(), (int)nr.getColumn()); - Integer dataFormat = xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(nr); + CellDatacellData = CellData.newInstance(BigDecimal.valueOf(nr.getValue()), nr.getRow(), (int)nr.getColumn()); + short dataFormat = (short)xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex( + nr); cellData.setDataFormat(dataFormat); cellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(nr), diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/StringRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/StringRecordHandler.java index 3b95cfdb..2408d219 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/StringRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/StringRecordHandler.java @@ -23,7 +23,7 @@ public class StringRecordHandler extends AbstractXlsRecordHandler implements Ign // String for formula StringRecord srec = (StringRecord)record; XlsReadSheetHolder xlsReadSheetHolder = xlsReadContext.xlsReadSheetHolder(); - CellData tempCellData = xlsReadSheetHolder.getTempCellData(); + CellDatatempCellData = xlsReadSheetHolder.getTempCellData(); if (tempCellData == null) { LOGGER.warn("String type formula but no value found."); return; diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java index a0a9af0e..1b6e6a8b 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -9,9 +9,26 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import com.alibaba.excel.analysis.ExcelReadExecutor; +import com.alibaba.excel.analysis.v07.handlers.sax.SharedStringsTableHandler; +import com.alibaba.excel.analysis.v07.handlers.sax.XlsxRowHandler; +import com.alibaba.excel.cache.ReadCache; +import com.alibaba.excel.context.xlsx.XlsxReadContext; +import com.alibaba.excel.enums.CellExtraTypeEnum; +import com.alibaba.excel.exception.ExcelAnalysisException; +import com.alibaba.excel.metadata.CellExtra; +import com.alibaba.excel.read.metadata.ReadSheet; +import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder; +import com.alibaba.excel.util.FileUtils; +import com.alibaba.excel.util.SheetUtils; +import com.alibaba.excel.util.StringUtils; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackagePart; @@ -25,26 +42,13 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; +import org.xml.sax.SAXException; import org.xml.sax.XMLReader; -import com.alibaba.excel.analysis.ExcelReadExecutor; -import com.alibaba.excel.analysis.v07.handlers.sax.SharedStringsTableHandler; -import com.alibaba.excel.analysis.v07.handlers.sax.XlsxRowHandler; -import com.alibaba.excel.cache.ReadCache; -import com.alibaba.excel.context.xlsx.XlsxReadContext; -import com.alibaba.excel.enums.CellExtraTypeEnum; -import com.alibaba.excel.exception.ExcelAnalysisException; -import com.alibaba.excel.metadata.CellExtra; -import com.alibaba.excel.read.metadata.ReadSheet; -import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder; -import com.alibaba.excel.util.CollectionUtils; -import com.alibaba.excel.util.FileUtils; -import com.alibaba.excel.util.SheetUtils; -import com.alibaba.excel.util.StringUtils; - /** * @author jipengfei */ +@Slf4j public class XlsxSaxAnalyser implements ExcelReadExecutor { private XlsxReadContext xlsxReadContext; @@ -78,7 +82,9 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { XSSFReader xssfReader = new XSSFReader(pkg); analysisUse1904WindowDate(xssfReader, xlsxReadWorkbookHolder); - xlsxReadWorkbookHolder.setStylesTable(xssfReader.getStylesTable()); + // set style table + setStylesTable(xlsxReadWorkbookHolder, xssfReader); + sheetList = new ArrayList(); sheetMap = new HashMap(); commentsTableMap = new HashMap(); @@ -101,6 +107,17 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { } } + private void setStylesTable(XlsxReadWorkbookHolder xlsxReadWorkbookHolder, XSSFReader xssfReader) { + try { + xlsxReadWorkbookHolder.setStylesTable(xssfReader.getStylesTable()); + } catch (Exception e) { + log.warn( + "Currently excel cannot get style information, but it doesn't affect the data analysis.You can try to" + + " save the file with office again or ignore the current error.", + e); + } + } + private void defaultReadCache(XlsxReadWorkbookHolder xlsxReadWorkbookHolder, PackagePart sharedStringsTablePackagePart) { ReadCache readCache = xlsxReadWorkbookHolder.getReadCacheSelector().readCache(sharedStringsTablePackagePart); @@ -147,9 +164,10 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { xlsxReadWorkbookHolder.setTempFile(readTempFile); File tempFile = new File(readTempFile.getPath(), UUID.randomUUID().toString() + ".xlsx"); if (decryptedStream != null) { - FileUtils.writeToFile(tempFile, decryptedStream); + FileUtils.writeToFile(tempFile, decryptedStream, false); } else { - FileUtils.writeToFile(tempFile, xlsxReadWorkbookHolder.getInputStream()); + FileUtils.writeToFile(tempFile, xlsxReadWorkbookHolder.getInputStream(), + xlsxReadWorkbookHolder.getAutoCloseStream()); } return OPCPackage.open(tempFile, PackageAccess.READ); } @@ -177,9 +195,7 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { xmlReader.setContentHandler(handler); xmlReader.parse(inputSource); inputStream.close(); - } catch (ExcelAnalysisException e) { - throw e; - } catch (Exception e) { + } catch (IOException | ParserConfigurationException | SAXException e) { throw new ExcelAnalysisException(e); } finally { if (inputStream != null) { diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java index 3521e46a..770355b0 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java @@ -7,6 +7,7 @@ import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder; import com.alibaba.excel.util.BooleanUtils; +import com.alibaba.excel.util.StringUtils; /** * Cell Value Handler @@ -20,6 +21,7 @@ public abstract class AbstractCellValueTagHandler extends AbstractXlsxTagHandler XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder(); CellData tempCellData = xlsxReadSheetHolder.getTempCellData(); StringBuilder tempData = xlsxReadSheetHolder.getTempData(); + String tempDataString = tempData.toString(); CellDataTypeEnum oldType = tempCellData.getType(); switch (oldType) { case DIRECT_STRING: @@ -28,10 +30,18 @@ public abstract class AbstractCellValueTagHandler extends AbstractXlsxTagHandler tempCellData.setStringValue(tempData.toString()); break; case BOOLEAN: + if(StringUtils.isEmpty(tempDataString)){ + tempCellData.setType(CellDataTypeEnum.EMPTY); + break; + } tempCellData.setBooleanValue(BooleanUtils.valueOf(tempData.toString())); break; case NUMBER: case EMPTY: + if(StringUtils.isEmpty(tempDataString)){ + tempCellData.setType(CellDataTypeEnum.EMPTY); + break; + } tempCellData.setType(CellDataTypeEnum.NUMBER); tempCellData.setNumberValue(new BigDecimal(tempData.toString())); break; @@ -44,7 +54,7 @@ public abstract class AbstractCellValueTagHandler extends AbstractXlsxTagHandler if (tempCellData.getStringValue() != null && xlsxReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) { - tempCellData.setStringValue(tempCellData.getStringValue()); + tempCellData.setStringValue(tempCellData.getStringValue().trim()); } tempCellData.checkEmpty(); diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java index 277348a7..3058e8e8 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java @@ -15,7 +15,7 @@ public class CellInlineStringValueTagHandler extends AbstractCellValueTagHandler @Override protected void setStringValue(XlsxReadContext xlsxReadContext) { // This is a special form of string - CellData tempCellData = xlsxReadContext.xlsxReadSheetHolder().getTempCellData(); + CellData tempCellData = xlsxReadContext.xlsxReadSheetHolder().getTempCellData(); XSSFRichTextString richTextString = new XSSFRichTextString(tempCellData.getStringValue()); tempCellData.setStringValue(richTextString.toString()); } 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 fe5a6421..135153e0 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 @@ -1,8 +1,5 @@ package com.alibaba.excel.analysis.v07.handlers; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.xml.sax.Attributes; - import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.context.xlsx.XlsxReadContext; @@ -12,6 +9,10 @@ import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder; 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; + /** * Cell Handler * @@ -46,9 +47,12 @@ public class CellTagHandler extends AbstractXlsxTagHandler { } else { dateFormatIndexInteger = Integer.parseInt(dateFormatIndex); } - XSSFCellStyle xssfCellStyle = - xlsxReadContext.xlsxReadWorkbookHolder().getStylesTable().getStyleAt(dateFormatIndexInteger); - int dataFormat = xssfCellStyle.getDataFormat(); + StylesTable stylesTable = xlsxReadContext.xlsxReadWorkbookHolder().getStylesTable(); + if (stylesTable == null) { + return; + } + XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger); + short dataFormat = xssfCellStyle.getDataFormat(); xlsxReadSheetHolder.getTempCellData().setDataFormat(dataFormat); xlsxReadSheetHolder.getTempCellData().setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale())); diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java index 09c9264e..7e685c97 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java @@ -3,6 +3,7 @@ package com.alibaba.excel.analysis.v07.handlers; import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.util.StringUtils; /** * Cell Value Handler @@ -17,6 +18,10 @@ public class CellValueTagHandler extends AbstractCellValueTagHandler { CellData tempCellData = xlsxReadContext.xlsxReadSheetHolder().getTempCellData(); switch (tempCellData.getType()) { case STRING: + // In some cases, although cell type is a string, it may be an empty tag + if(StringUtils.isEmpty(tempCellData.getStringValue())){ + break; + } String stringValue = xlsxReadContext.readWorkbookHolder().getReadCache() .get(Integer.valueOf(tempCellData.getStringValue())); if (stringValue != null && xlsxReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) { diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java index 877c6a5f..37965254 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java @@ -2,17 +2,17 @@ package com.alibaba.excel.analysis.v07.handlers; import java.util.LinkedHashMap; -import org.xml.sax.Attributes; - import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.context.xlsx.XlsxReadContext; import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.metadata.Cell; import com.alibaba.excel.read.metadata.holder.ReadRowHolder; import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder; -import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.PositionUtils; +import org.apache.commons.collections4.MapUtils; +import org.xml.sax.Attributes; + /** * Cell Handler * @@ -40,13 +40,12 @@ public class RowTagHandler extends AbstractXlsxTagHandler { @Override public void endElement(XlsxReadContext xlsxReadContext, String name) { XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder(); - RowTypeEnum rowType = - CollectionUtils.isEmpty(xlsxReadSheetHolder.getCellMap()) ? RowTypeEnum.EMPTY : RowTypeEnum.DATA; + RowTypeEnum rowType = MapUtils.isEmpty(xlsxReadSheetHolder.getCellMap()) ? RowTypeEnum.EMPTY : RowTypeEnum.DATA; xlsxReadContext.readRowHolder(new ReadRowHolder(xlsxReadSheetHolder.getRowIndex(), rowType, xlsxReadSheetHolder.getGlobalConfiguration(), xlsxReadSheetHolder.getCellMap())); xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext); xlsxReadSheetHolder.setColumnIndex(null); - xlsxReadSheetHolder.setCellMap(new LinkedHashMap()); + xlsxReadSheetHolder.setCellMap(new LinkedHashMap<>()); } } diff --git a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java index 5c778a84..e2b169e3 100644 --- a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java +++ b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java @@ -23,7 +23,7 @@ public @interface ExcelProperty { *

* write: It automatically merges when you have more than one head *

- * read: When you have multiple heads, take the first one + * read: When you have multiple heads, take the last one * * @return The name of the sheet header */ diff --git a/src/main/java/com/alibaba/excel/cache/Ehcache.java b/src/main/java/com/alibaba/excel/cache/Ehcache.java index 4e757fcd..a5250900 100644 --- a/src/main/java/com/alibaba/excel/cache/Ehcache.java +++ b/src/main/java/com/alibaba/excel/cache/Ehcache.java @@ -1,50 +1,49 @@ package com.alibaba.excel.cache; import java.io.File; -import java.util.HashMap; +import java.util.ArrayList; import java.util.UUID; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.util.FileUtils; +import com.alibaba.excel.util.ListUtils; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; import org.ehcache.CacheManager; import org.ehcache.config.CacheConfiguration; import org.ehcache.config.builders.CacheConfigurationBuilder; import org.ehcache.config.builders.CacheManagerBuilder; import org.ehcache.config.builders.ResourcePoolsBuilder; import org.ehcache.config.units.MemoryUnit; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.util.CollectionUtils; -import com.alibaba.excel.util.FileUtils; /** * Default cache * * @author Jiaju Zhuang */ +@Slf4j public class Ehcache implements ReadCache { - - private static final Logger LOGGER = LoggerFactory.getLogger(Ehcache.class); - private static final int BATCH_COUNT = 1000; - private static final int DEBUG_WRITE_SIZE = 100 * 10000; - private static final int DEBUG_CACHE_MISS_SIZE = 1000; + public static final int BATCH_COUNT = 1000; /** * Key index */ - private int index = 0; - private HashMap dataMap = new HashMap(BATCH_COUNT * 4 / 3 + 1); - private static CacheManager fileCacheManager; - private static CacheConfiguration fileCacheConfiguration; - private static CacheManager activeCacheManager; - private CacheConfiguration activeCacheConfiguration; + private int activeIndex = 0; + public static final int DEBUG_CACHE_MISS_SIZE = 1000; + public static final int DEBUG_WRITE_SIZE = 100 * 10000; + private ArrayList dataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + private static final CacheManager FILE_CACHE_MANAGER; + private static final CacheConfiguration FILE_CACHE_CONFIGURATION; + private static final CacheManager ACTIVE_CACHE_MANAGER; + private final CacheConfiguration activeCacheConfiguration; /** * Bulk storage data */ - private org.ehcache.Cache fileCache; + private org.ehcache.Cache fileCache; /** * Currently active cache */ - private org.ehcache.Cache activeCache; + private org.ehcache.Cache activeCache; private String cacheAlias; /** * Count the number of cache misses @@ -53,7 +52,7 @@ public class Ehcache implements ReadCache { public Ehcache(int maxCacheActivateSize) { activeCacheConfiguration = CacheConfigurationBuilder - .newCacheConfigurationBuilder(Integer.class, HashMap.class, + .newCacheConfigurationBuilder(Integer.class, ArrayList.class, ResourcePoolsBuilder.newResourcePoolsBuilder().heap(maxCacheActivateSize, MemoryUnit.MB)) .withSizeOfMaxObjectGraph(1000 * 1000L).withSizeOfMaxObjectSize(maxCacheActivateSize, MemoryUnit.MB) .build(); @@ -61,11 +60,11 @@ public class Ehcache implements ReadCache { static { File cacheFile = FileUtils.createCacheTmpFile(); - fileCacheManager = + FILE_CACHE_MANAGER = CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(cacheFile)).build(true); - activeCacheManager = CacheManagerBuilder.newCacheManagerBuilder().build(true); - fileCacheConfiguration = CacheConfigurationBuilder - .newCacheConfigurationBuilder(Integer.class, HashMap.class, + ACTIVE_CACHE_MANAGER = CacheManagerBuilder.newCacheManagerBuilder().build(true); + FILE_CACHE_CONFIGURATION = CacheConfigurationBuilder + .newCacheConfigurationBuilder(Integer.class, ArrayList.class, ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10, MemoryUnit.GB)) .withSizeOfMaxObjectGraph(1000 * 1000L).withSizeOfMaxObjectSize(10, MemoryUnit.GB).build(); } @@ -73,21 +72,22 @@ public class Ehcache implements ReadCache { @Override public void init(AnalysisContext analysisContext) { cacheAlias = UUID.randomUUID().toString(); - fileCache = fileCacheManager.createCache(cacheAlias, fileCacheConfiguration); - activeCache = activeCacheManager.createCache(cacheAlias, activeCacheConfiguration); + fileCache = FILE_CACHE_MANAGER.createCache(cacheAlias, FILE_CACHE_CONFIGURATION); + activeCache = ACTIVE_CACHE_MANAGER.createCache(cacheAlias, activeCacheConfiguration); } @Override public void put(String value) { - dataMap.put(index, value); - if ((index + 1) % BATCH_COUNT == 0) { - fileCache.put(index / BATCH_COUNT, dataMap); - dataMap = new HashMap(BATCH_COUNT * 4 / 3 + 1); + dataList.add(value); + if (dataList.size() >= BATCH_COUNT) { + fileCache.put(activeIndex, dataList); + activeIndex++; + dataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); } - index++; - if (LOGGER.isDebugEnabled()) { - if (index % DEBUG_WRITE_SIZE == 0) { - LOGGER.debug("Already put :{}", index); + if (log.isDebugEnabled()) { + int alreadyPut = activeIndex * BATCH_COUNT + dataList.size(); + if (alreadyPut % DEBUG_WRITE_SIZE == 0) { + log.debug("Already put :{}", alreadyPut); } } } @@ -98,31 +98,31 @@ public class Ehcache implements ReadCache { return null; } int route = key / BATCH_COUNT; - HashMap dataMap = activeCache.get(route); - if (dataMap == null) { - dataMap = fileCache.get(route); - activeCache.put(route, dataMap); - if (LOGGER.isDebugEnabled()) { + ArrayList dataList = activeCache.get(route); + if (dataList == null) { + dataList = fileCache.get(route); + activeCache.put(route, dataList); + if (log.isDebugEnabled()) { if (cacheMiss++ % DEBUG_CACHE_MISS_SIZE == 0) { - LOGGER.debug("Cache misses count:{}", cacheMiss); + log.debug("Cache misses count:{}", cacheMiss); } } } - return dataMap.get(key); + return dataList.get(key % BATCH_COUNT); } @Override public void putFinished() { - if (CollectionUtils.isEmpty(dataMap)) { + if (CollectionUtils.isEmpty(dataList)) { return; } - fileCache.put(index / BATCH_COUNT, dataMap); + fileCache.put(activeIndex, dataList); } @Override public void destroy() { - fileCacheManager.removeCache(cacheAlias); - activeCacheManager.removeCache(cacheAlias); + FILE_CACHE_MANAGER.removeCache(cacheAlias); + ACTIVE_CACHE_MANAGER.removeCache(cacheAlias); } } diff --git a/src/main/java/com/alibaba/excel/cache/MapCache.java b/src/main/java/com/alibaba/excel/cache/MapCache.java index ae948fbc..f83a1233 100644 --- a/src/main/java/com/alibaba/excel/cache/MapCache.java +++ b/src/main/java/com/alibaba/excel/cache/MapCache.java @@ -1,26 +1,24 @@ package com.alibaba.excel.cache; -import java.util.HashMap; -import java.util.Map; +import java.util.ArrayList; +import java.util.List; import com.alibaba.excel.context.AnalysisContext; /** - * * Putting temporary data directly into a map is a little more efficient but very memory intensive * * @author Jiaju Zhuang */ public class MapCache implements ReadCache { - private Map cache = new HashMap(); - private int index = 0; + private List cache = new ArrayList<>(); @Override public void init(AnalysisContext analysisContext) {} @Override public void put(String value) { - cache.put(index++, value); + cache.add(value); } @Override diff --git a/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java b/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java index 95eb0b8f..b742cb6c 100644 --- a/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java +++ b/src/main/java/com/alibaba/excel/constant/BuiltinFormats.java @@ -17,7 +17,9 @@ import java.util.Locale; **/ public class BuiltinFormats { - private static final String[] BUILTIN_FORMATS_CN = { + public static short GENERAL = 0; + + public static final String[] BUILTIN_FORMATS_CN = { // 0 "General", // 1 @@ -189,7 +191,7 @@ public class BuiltinFormats { // end }; - private static final String[] BUILTIN_FORMATS_US = { + public static final String[] BUILTIN_FORMATS_US = { // 0 "General", // 1 @@ -361,7 +363,7 @@ public class BuiltinFormats { // end }; - public static String getBuiltinFormat(Integer index, String defaultFormat, Locale locale) { + public static String getBuiltinFormat(Short index, String defaultFormat, Locale locale) { String[] builtinFormat = switchBuiltinFormats(locale); if (index == null || index < 0 || index >= builtinFormat.length) { return defaultFormat; diff --git a/src/main/java/com/alibaba/excel/constant/OrderConstant.java b/src/main/java/com/alibaba/excel/constant/OrderConstant.java new file mode 100644 index 00000000..a955025c --- /dev/null +++ b/src/main/java/com/alibaba/excel/constant/OrderConstant.java @@ -0,0 +1,13 @@ +package com.alibaba.excel.constant; + +/** + * Order constant. + * + * @author Jiaju Zhuang + */ +public class OrderConstant { + /** + * Sorting of styles written to cells. + */ + public static final int FILL_DATA_FORMAT = 10000; +} diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index c1f89f02..648a7fe9 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -6,22 +6,6 @@ import java.io.OutputStream; import java.util.Map; import java.util.UUID; -import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackageAccess; -import org.apache.poi.poifs.crypt.EncryptionInfo; -import org.apache.poi.poifs.crypt.EncryptionMode; -import org.apache.poi.poifs.crypt.Encryptor; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.alibaba.excel.enums.WriteTypeEnum; import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.metadata.CellData; @@ -42,6 +26,22 @@ import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.alibaba.excel.write.property.ExcelWriteHeadProperty; +import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.PackageAccess; +import org.apache.poi.poifs.crypt.EncryptionInfo; +import org.apache.poi.poifs.crypt.EncryptionMode; +import org.apache.poi.poifs.crypt.Encryptor; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * A context is the main anchorage point of a excel writer. * @@ -50,6 +50,7 @@ import com.alibaba.excel.write.property.ExcelWriteHeadProperty; public class WriteContextImpl implements WriteContext { private static final Logger LOGGER = LoggerFactory.getLogger(WriteContextImpl.class); + private static final String NO_SHEETS="no sheets"; /** * The Workbook currently written @@ -178,8 +179,12 @@ public class WriteContextImpl implements WriteContext { writeSheetHolder .setCachedSheet(writeWorkbookHolder.getCachedWorkbook().getSheet(writeSheetHolder.getSheetName())); } - } catch (Exception e) { - currentSheet = createSheet(); + } catch (IllegalArgumentException e) { + if (e.getMessage() != null && e.getMessage().contains(NO_SHEETS)) { + currentSheet = createSheet(); + } else { + throw e; + } } if (currentSheet == null) { currentSheet = createSheet(); diff --git a/src/main/java/com/alibaba/excel/converters/AutoConverter.java b/src/main/java/com/alibaba/excel/converters/AutoConverter.java index 800d2d85..07ad471f 100644 --- a/src/main/java/com/alibaba/excel/converters/AutoConverter.java +++ b/src/main/java/com/alibaba/excel/converters/AutoConverter.java @@ -10,10 +10,10 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; * * @author Jiaju Zhuang */ -public class AutoConverter implements Converter { +public class AutoConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return null; } @@ -23,13 +23,13 @@ public class AutoConverter implements Converter { } @Override - public Object convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Object convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return null; } @Override - public CellData convertToExcelData(Object value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Object value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return null; } diff --git a/src/main/java/com/alibaba/excel/converters/Converter.java b/src/main/java/com/alibaba/excel/converters/Converter.java index 8700d127..3d1a369d 100644 --- a/src/main/java/com/alibaba/excel/converters/Converter.java +++ b/src/main/java/com/alibaba/excel/converters/Converter.java @@ -4,12 +4,16 @@ import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteHolder; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; /** * Convert between Java objects and excel objects * - * @author Dan Zheng * @param + * @author Dan Zheng */ public interface Converter { @@ -18,44 +22,72 @@ public interface Converter { * * @return Support for Java class */ - Class supportJavaTypeKey(); + default Class supportJavaTypeKey() { + throw new UnsupportedOperationException("The current operation is not supported by the current converter."); + } /** * Back to object enum in excel * * @return Support for {@link CellDataTypeEnum} */ - CellDataTypeEnum supportExcelTypeKey(); + default CellDataTypeEnum supportExcelTypeKey() { + throw new UnsupportedOperationException("The current operation is not supported by the current converter."); + } + + /** + * Convert excel objects to Java objects + * + * @param cellData Excel cell data.NotNull. + * @param contentProperty Content property.Nullable. + * @param globalConfiguration Global configuration.NotNull. + * @return Data to put into a Java object + * @throws Exception Exception. + */ + default T convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + throw new UnsupportedOperationException("The current operation is not supported by the current converter."); + } /** * Convert excel objects to Java objects * - * @param cellData - * Excel cell data.NotNull. - * @param contentProperty - * Content property.Nullable. - * @param globalConfiguration - * Global configuration.NotNull. + * @param cellData Excel cell data.NotNull. + * @param contentProperty Content property.Nullable. + * @param readSheetHolder .NotNull. * @return Data to put into a Java object - * @throws Exception - * Exception. + * @throws Exception Exception. + */ + default T convertToJavaData(CellData cellData, + ExcelContentProperty contentProperty, ReadSheetHolder readSheetHolder) throws Exception { + return convertToJavaData(cellData, contentProperty, readSheetHolder.globalConfiguration()); + } + + /** + * Convert Java objects to excel objects + * + * @param value Java Data.NotNull. + * @param contentProperty Content property.Nullable. + * @param globalConfiguration Global configuration.NotNull. + * @return Data to put into a Excel + * @throws Exception Exception. */ - T convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) throws Exception; + default CellData convertToExcelData(T value, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) throws Exception { + throw new UnsupportedOperationException("The current operation is not supported by the current converter."); + } /** * Convert Java objects to excel objects * - * @param value - * Java Data.NotNull. - * @param contentProperty - * Content property.Nullable. - * @param globalConfiguration - * Global configuration.NotNull. + * @param value Java Data.NotNull. + * @param contentProperty Content property.Nullable. + * @param currentWriteHolder He would be {@link WriteSheetHolder} or {@link WriteTableHolder}.NotNull. * @return Data to put into a Excel - * @throws Exception - * Exception. + * @throws Exception Exception. */ - CellData convertToExcelData(T value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) - throws Exception; + default CellData convertToExcelData(T value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) throws Exception { + return convertToExcelData(value, contentProperty, currentWriteHolder.globalConfiguration()); + } } diff --git a/src/main/java/com/alibaba/excel/converters/ConverterKeyBuild.java b/src/main/java/com/alibaba/excel/converters/ConverterKeyBuild.java index 0bd54991..a92f3033 100644 --- a/src/main/java/com/alibaba/excel/converters/ConverterKeyBuild.java +++ b/src/main/java/com/alibaba/excel/converters/ConverterKeyBuild.java @@ -1,9 +1,9 @@ package com.alibaba.excel.converters; -import java.util.HashMap; import java.util.Map; import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.util.MapUtils; /** * Converter unique key.Consider that you can just use class as the key. @@ -12,7 +12,7 @@ import com.alibaba.excel.enums.CellDataTypeEnum; */ public class ConverterKeyBuild { - private static final Map BOXING_MAP = new HashMap(16); + private static final Map BOXING_MAP = MapUtils.newHashMap(); static { BOXING_MAP.put(int.class.getName(), Integer.class.getName()); @@ -25,7 +25,7 @@ public class ConverterKeyBuild { BOXING_MAP.put(boolean.class.getName(), Boolean.class.getName()); } - public static String buildKey(Class clazz) { + public static String buildKey(Class clazz) { String className = clazz.getName(); String boxingClassName = BOXING_MAP.get(clazz.getName()); if (boxingClassName == null) { @@ -34,7 +34,11 @@ public class ConverterKeyBuild { return boxingClassName; } - public static String buildKey(Class clazz, CellDataTypeEnum cellDataTypeEnum) { - return buildKey(clazz) + "-" + cellDataTypeEnum.toString(); + public static String buildKey(Class clazz, CellDataTypeEnum cellDataTypeEnum) { + String key = buildKey(clazz); + if (cellDataTypeEnum == null) { + return key; + } + return key + "-" + cellDataTypeEnum.toString(); } } diff --git a/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java b/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java index 01822559..b4cabe0d 100644 --- a/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java +++ b/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java @@ -1,6 +1,5 @@ package com.alibaba.excel.converters; -import java.util.HashMap; import java.util.Map; import com.alibaba.excel.converters.bigdecimal.BigDecimalBooleanConverter; @@ -14,6 +13,7 @@ import com.alibaba.excel.converters.bytearray.ByteArrayImageConverter; import com.alibaba.excel.converters.byteconverter.ByteBooleanConverter; import com.alibaba.excel.converters.byteconverter.ByteNumberConverter; import com.alibaba.excel.converters.byteconverter.ByteStringConverter; +import com.alibaba.excel.converters.date.DateDateConverter; import com.alibaba.excel.converters.date.DateNumberConverter; import com.alibaba.excel.converters.date.DateStringConverter; import com.alibaba.excel.converters.doubleconverter.DoubleBooleanConverter; @@ -38,6 +38,7 @@ import com.alibaba.excel.converters.string.StringErrorConverter; import com.alibaba.excel.converters.string.StringNumberConverter; import com.alibaba.excel.converters.string.StringStringConverter; import com.alibaba.excel.converters.url.UrlImageConverter; +import com.alibaba.excel.util.MapUtils; /** * Load default handler @@ -45,8 +46,8 @@ import com.alibaba.excel.converters.url.UrlImageConverter; * @author Jiaju Zhuang */ public class DefaultConverterLoader { - private static Map defaultWriteConverter; - private static Map allConverter; + private static Map> defaultWriteConverter; + private static Map> allConverter; static { initDefaultWriteConverter(); @@ -54,7 +55,7 @@ public class DefaultConverterLoader { } private static void initAllConverter() { - allConverter = new HashMap(64); + allConverter = MapUtils.newHashMapWithExpectedSize(40); putAllConverter(new BigDecimalBooleanConverter()); putAllConverter(new BigDecimalNumberConverter()); putAllConverter(new BigDecimalStringConverter()); @@ -97,11 +98,11 @@ public class DefaultConverterLoader { } private static void initDefaultWriteConverter() { - defaultWriteConverter = new HashMap(32); + defaultWriteConverter = MapUtils.newHashMapWithExpectedSize(40); putWriteConverter(new BigDecimalNumberConverter()); putWriteConverter(new BooleanBooleanConverter()); putWriteConverter(new ByteNumberConverter()); - putWriteConverter(new DateStringConverter()); + putWriteConverter(new DateDateConverter()); putWriteConverter(new DoubleNumberConverter()); putWriteConverter(new FloatNumberConverter()); putWriteConverter(new IntegerNumberConverter()); @@ -113,6 +114,18 @@ public class DefaultConverterLoader { putWriteConverter(new ByteArrayImageConverter()); putWriteConverter(new BoxingByteArrayImageConverter()); putWriteConverter(new UrlImageConverter()); + + // In some cases, it must be converted to string + putWriteStringConverter(new BigDecimalStringConverter()); + putWriteStringConverter(new BooleanStringConverter()); + putWriteStringConverter(new ByteStringConverter()); + putWriteStringConverter(new DateStringConverter()); + putWriteStringConverter(new DoubleStringConverter()); + putWriteStringConverter(new FloatStringConverter()); + putWriteStringConverter(new IntegerStringConverter()); + putWriteStringConverter(new LongStringConverter()); + putWriteStringConverter(new ShortStringConverter()); + putWriteStringConverter(new StringStringConverter()); } /** @@ -120,20 +133,25 @@ public class DefaultConverterLoader { * * @return */ - public static Map loadDefaultWriteConverter() { + public static Map> loadDefaultWriteConverter() { return defaultWriteConverter; } - private static void putWriteConverter(Converter converter) { + private static void putWriteConverter(Converter converter) { defaultWriteConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter); } + private static void putWriteStringConverter(Converter converter) { + defaultWriteConverter.put( + ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), converter); + } + /** * Load default read converter * * @return */ - public static Map loadDefaultReadConverter() { + public static Map> loadDefaultReadConverter() { return loadAllConverter(); } @@ -142,11 +160,11 @@ public class DefaultConverterLoader { * * @return */ - public static Map loadAllConverter() { + public static Map> loadAllConverter() { return allConverter; } - private static void putAllConverter(Converter converter) { + private static void putAllConverter(Converter converter) { allConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), converter); } diff --git a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java index 8dcac0c9..f4e9ad6f 100644 --- a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java @@ -16,7 +16,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class BigDecimalBooleanConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return BigDecimal.class; } @@ -26,7 +26,7 @@ public class BigDecimalBooleanConverter implements Converter { } @Override - public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (cellData.getBooleanValue()) { return BigDecimal.ONE; @@ -35,12 +35,12 @@ public class BigDecimalBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (BigDecimal.ONE.equals(value)) { - return new CellData(Boolean.TRUE); + return new CellData<>(Boolean.TRUE); } - return new CellData(Boolean.FALSE); + return new CellData<>(Boolean.FALSE); } } diff --git a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java index bf9b735f..39061d70 100644 --- a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java @@ -7,6 +7,8 @@ import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.NumberUtils; +import com.alibaba.excel.write.metadata.holder.WriteHolder; /** * BigDecimal and number converter @@ -16,7 +18,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class BigDecimalNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return BigDecimal.class; } @@ -26,14 +28,14 @@ public class BigDecimalNumberConverter implements Converter { } @Override - public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getNumberValue(); } @Override - public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(value); + public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } } diff --git a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java index 8c5f0f48..356a38c5 100644 --- a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java @@ -18,7 +18,7 @@ import com.alibaba.excel.util.NumberUtils; public class BigDecimalStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return BigDecimal.class; } @@ -28,14 +28,14 @@ public class BigDecimalStringConverter implements Converter { } @Override - public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException { return NumberUtils.parseBigDecimal(cellData.getStringValue(), contentProperty); } @Override - public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java index 08b83fe9..56654cd5 100644 --- a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java @@ -14,7 +14,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class BooleanBooleanConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Boolean.class; } @@ -24,15 +24,15 @@ public class BooleanBooleanConverter implements Converter { } @Override - public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getBooleanValue(); } @Override - public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value); + return new CellData<>(value); } } diff --git a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java index a0042eaa..00cd4c2c 100644 --- a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java @@ -15,7 +15,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; */ public class BooleanNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Boolean.class; } @@ -25,7 +25,7 @@ public class BooleanNumberConverter implements Converter { } @Override - public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (BigDecimal.ONE.compareTo(cellData.getNumberValue()) == 0) { return Boolean.TRUE; @@ -34,12 +34,12 @@ public class BooleanNumberConverter implements Converter { } @Override - public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (value) { - return new CellData(BigDecimal.ONE); + return new CellData<>(BigDecimal.ONE); } - return new CellData(BigDecimal.ZERO); + return new CellData<>(BigDecimal.ZERO); } } diff --git a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java index e86c6ada..9f82f32a 100644 --- a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java @@ -14,7 +14,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class BooleanStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Boolean.class; } @@ -24,15 +24,15 @@ public class BooleanStringConverter implements Converter { } @Override - public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return Boolean.valueOf(cellData.getStringValue()); } @Override - public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value.toString()); + return new CellData<>(value.toString()); } } diff --git a/src/main/java/com/alibaba/excel/converters/bytearray/BoxingByteArrayImageConverter.java b/src/main/java/com/alibaba/excel/converters/bytearray/BoxingByteArrayImageConverter.java index c083601b..883ed87f 100644 --- a/src/main/java/com/alibaba/excel/converters/bytearray/BoxingByteArrayImageConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bytearray/BoxingByteArrayImageConverter.java @@ -13,7 +13,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; */ public class BoxingByteArrayImageConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Byte[].class; } @@ -23,19 +23,19 @@ public class BoxingByteArrayImageConverter implements Converter { } @Override - public Byte[] convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Byte[] convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { throw new UnsupportedOperationException("Cannot convert images to byte arrays"); } @Override - public CellData convertToExcelData(Byte[] value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Byte[] value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { byte[] byteValue = new byte[value.length]; for (int i = 0; i < value.length; i++) { byteValue[i] = value[i]; } - return new CellData(byteValue); + return new CellData<>(byteValue); } } diff --git a/src/main/java/com/alibaba/excel/converters/bytearray/ByteArrayImageConverter.java b/src/main/java/com/alibaba/excel/converters/bytearray/ByteArrayImageConverter.java index 991999d1..afe1fd08 100644 --- a/src/main/java/com/alibaba/excel/converters/bytearray/ByteArrayImageConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bytearray/ByteArrayImageConverter.java @@ -13,7 +13,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; */ public class ByteArrayImageConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return byte[].class; } @@ -23,15 +23,15 @@ public class ByteArrayImageConverter implements Converter { } @Override - public byte[] convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public byte[] convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { throw new UnsupportedOperationException("Cannot convert images to byte arrays"); } @Override - public CellData convertToExcelData(byte[] value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(byte[] value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value); + return new CellData<>(value); } } diff --git a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java index 2b621558..afe079cb 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java @@ -16,7 +16,7 @@ public class ByteBooleanConverter implements Converter { private static final Byte ZERO = (byte)0; @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Byte.class; } @@ -26,7 +26,7 @@ public class ByteBooleanConverter implements Converter { } @Override - public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (cellData.getBooleanValue()) { return ONE; @@ -35,12 +35,12 @@ public class ByteBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (ONE.equals(value)) { - return new CellData(Boolean.TRUE); + return new CellData<>(Boolean.TRUE); } - return new CellData(Boolean.FALSE); + return new CellData<>(Boolean.FALSE); } } diff --git a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java index f1facdfb..891ae714 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java @@ -7,6 +7,8 @@ import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.NumberUtils; +import com.alibaba.excel.write.metadata.holder.WriteHolder; /** * Byte and number converter @@ -16,7 +18,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class ByteNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Byte.class; } @@ -26,15 +28,15 @@ public class ByteNumberConverter implements Converter { } @Override - public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getNumberValue().byteValue(); } @Override - public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(new BigDecimal(Byte.toString(value))); + public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } } diff --git a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java index c96114de..041557cf 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.NumberUtils; public class ByteStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Byte.class; } @@ -27,15 +27,15 @@ public class ByteStringConverter implements Converter { } @Override - public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException { return NumberUtils.parseByte(cellData.getStringValue(), contentProperty); } @Override - public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/date/DateDateConverter.java b/src/main/java/com/alibaba/excel/converters/date/DateDateConverter.java new file mode 100644 index 00000000..73b071af --- /dev/null +++ b/src/main/java/com/alibaba/excel/converters/date/DateDateConverter.java @@ -0,0 +1,47 @@ +package com.alibaba.excel.converters.date; + +import java.util.Date; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.WorkBookUtil; +import com.alibaba.excel.write.metadata.holder.WriteHolder; + +/** + * Date and date converter + * + * @author Jiaju Zhuang + */ +public class DateDateConverter implements Converter { + @Override + public Class supportJavaTypeKey() { + return Date.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.DATE; + } + + @Override + public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + GlobalConfiguration globalConfiguration) { + return cellData.getDateValue(); + } + + @Override + public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) throws Exception { + CellData cellData = new CellData<>(value); + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null + || contentProperty.getDateTimeFormatProperty().getFormat() == null) { + return cellData; + } + WorkBookUtil.fillDataFormat(cellData, currentWriteHolder, + contentProperty.getDateTimeFormatProperty().getFormat()); + return cellData; + } +} diff --git a/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java b/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java index fcc76bb3..6eee4de0 100644 --- a/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java @@ -19,7 +19,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class DateNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Date.class; } @@ -29,7 +29,7 @@ public class DateNumberConverter implements Converter { } @Override - public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { return DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), @@ -41,13 +41,13 @@ public class DateNumberConverter implements Converter { } @Override - public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { - return new CellData( + return new CellData<>( BigDecimal.valueOf(DateUtil.getExcelDate(value, globalConfiguration.getUse1904windowing()))); } else { - return new CellData(BigDecimal.valueOf( + return new CellData<>(BigDecimal.valueOf( DateUtil.getExcelDate(value, contentProperty.getDateTimeFormatProperty().getUse1904windowing()))); } } diff --git a/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java b/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java index ed7eb0a4..687d84d7 100644 --- a/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.DateUtils; */ public class DateStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Date.class; } @@ -27,7 +27,7 @@ public class DateStringConverter implements Converter { } @Override - public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { return DateUtils.parseDate(cellData.getStringValue(), null); @@ -38,12 +38,12 @@ public class DateStringConverter implements Converter { } @Override - public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { - return new CellData(DateUtils.format(value, null)); + return new CellData<>(DateUtils.format(value, null)); } else { - return new CellData(DateUtils.format(value, contentProperty.getDateTimeFormatProperty().getFormat())); + return new CellData<>(DateUtils.format(value, contentProperty.getDateTimeFormatProperty().getFormat())); } } } diff --git a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleBooleanConverter.java index cbf0b0b0..6aa509e1 100644 --- a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleBooleanConverter.java @@ -16,7 +16,7 @@ public class DoubleBooleanConverter implements Converter { private static final Double ZERO = 0.0; @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Double.class; } @@ -26,7 +26,7 @@ public class DoubleBooleanConverter implements Converter { } @Override - public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (cellData.getBooleanValue()) { return ONE; @@ -35,12 +35,12 @@ public class DoubleBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (ONE.equals(value)) { - return new CellData(Boolean.TRUE); + return new CellData<>(Boolean.TRUE); } - return new CellData(Boolean.FALSE); + return new CellData<>(Boolean.FALSE); } } diff --git a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java index 15fbdae3..c3db3d3b 100644 --- a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java @@ -7,6 +7,8 @@ import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.NumberUtils; +import com.alibaba.excel.write.metadata.holder.WriteHolder; /** * Double and number converter @@ -16,7 +18,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class DoubleNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Double.class; } @@ -26,15 +28,14 @@ public class DoubleNumberConverter implements Converter { } @Override - public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getNumberValue().doubleValue(); } @Override - public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(BigDecimal.valueOf(value)); + public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } - } diff --git a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java index 2572b4ee..351d0b8a 100644 --- a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.NumberUtils; public class DoubleStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Double.class; } @@ -27,14 +27,14 @@ public class DoubleStringConverter implements Converter { } @Override - public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException { return NumberUtils.parseDouble(cellData.getStringValue(), contentProperty); } @Override - public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/file/FileImageConverter.java b/src/main/java/com/alibaba/excel/converters/file/FileImageConverter.java index 10522154..0938f6f5 100644 --- a/src/main/java/com/alibaba/excel/converters/file/FileImageConverter.java +++ b/src/main/java/com/alibaba/excel/converters/file/FileImageConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.FileUtils; */ public class FileImageConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return File.class; } @@ -27,15 +27,15 @@ public class FileImageConverter implements Converter { } @Override - public File convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public File convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { throw new UnsupportedOperationException("Cannot convert images to file"); } @Override - public CellData convertToExcelData(File value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(File value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws IOException { - return new CellData(FileUtils.readFileToByteArray(value)); + return new CellData<>(FileUtils.readFileToByteArray(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatBooleanConverter.java index 8fa2a647..c2f674f2 100644 --- a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatBooleanConverter.java @@ -16,7 +16,7 @@ public class FloatBooleanConverter implements Converter { private static final Float ZERO = (float)0.0; @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Float.class; } @@ -26,7 +26,7 @@ public class FloatBooleanConverter implements Converter { } @Override - public Float convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Float convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (cellData.getBooleanValue()) { return ONE; @@ -35,12 +35,12 @@ public class FloatBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (ONE.equals(value)) { - return new CellData(Boolean.TRUE); + return new CellData<>(Boolean.TRUE); } - return new CellData(Boolean.FALSE); + return new CellData<>(Boolean.FALSE); } } diff --git a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java index 69cc22e7..1a401dff 100644 --- a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java @@ -1,12 +1,12 @@ package com.alibaba.excel.converters.floatconverter; -import java.math.BigDecimal; - import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.NumberUtils; +import com.alibaba.excel.write.metadata.holder.WriteHolder; /** * Float and number converter @@ -16,7 +16,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class FloatNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Float.class; } @@ -26,15 +26,14 @@ public class FloatNumberConverter implements Converter { } @Override - public Float convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Float convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getNumberValue().floatValue(); } @Override - public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(new BigDecimal(Float.toString(value))); + public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } - } diff --git a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java index ee2ef551..29c819b1 100644 --- a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.NumberUtils; public class FloatStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Float.class; } @@ -27,14 +27,14 @@ public class FloatStringConverter implements Converter { } @Override - public Float convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Float convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException { return NumberUtils.parseFloat(cellData.getStringValue(), contentProperty); } @Override - public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/inputstream/InputStreamImageConverter.java b/src/main/java/com/alibaba/excel/converters/inputstream/InputStreamImageConverter.java index abc2fe68..b45736e4 100644 --- a/src/main/java/com/alibaba/excel/converters/inputstream/InputStreamImageConverter.java +++ b/src/main/java/com/alibaba/excel/converters/inputstream/InputStreamImageConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.IoUtils; */ public class InputStreamImageConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return InputStream.class; } @@ -27,15 +27,15 @@ public class InputStreamImageConverter implements Converter { } @Override - public InputStream convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public InputStream convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { throw new UnsupportedOperationException("Cannot convert images to input stream"); } @Override - public CellData convertToExcelData(InputStream value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(InputStream value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws IOException { - return new CellData(IoUtils.toByteArray(value)); + return new CellData<>(IoUtils.toByteArray(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/integer/IntegerBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/integer/IntegerBooleanConverter.java index 541de08a..37b5d913 100644 --- a/src/main/java/com/alibaba/excel/converters/integer/IntegerBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/integer/IntegerBooleanConverter.java @@ -16,7 +16,7 @@ public class IntegerBooleanConverter implements Converter { private static final Integer ZERO = 0; @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Integer.class; } @@ -26,7 +26,7 @@ public class IntegerBooleanConverter implements Converter { } @Override - public Integer convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Integer convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (cellData.getBooleanValue()) { return ONE; @@ -35,12 +35,12 @@ public class IntegerBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (ONE.equals(value)) { - return new CellData(Boolean.TRUE); + return new CellData<>(Boolean.TRUE); } - return new CellData(Boolean.FALSE); + return new CellData<>(Boolean.FALSE); } } diff --git a/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java b/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java index 117d4c11..95a796b5 100644 --- a/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java @@ -1,12 +1,12 @@ package com.alibaba.excel.converters.integer; -import java.math.BigDecimal; - import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.NumberUtils; +import com.alibaba.excel.write.metadata.holder.WriteHolder; /** * Integer and number converter @@ -16,7 +16,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class IntegerNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Integer.class; } @@ -26,15 +26,15 @@ public class IntegerNumberConverter implements Converter { } @Override - public Integer convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Integer convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getNumberValue().intValue(); } @Override - public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(new BigDecimal(Integer.toString(value))); + public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } } diff --git a/src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java b/src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java index 07bc1b77..e6d91d34 100644 --- a/src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.NumberUtils; public class IntegerStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Integer.class; } @@ -27,14 +27,14 @@ public class IntegerStringConverter implements Converter { } @Override - public Integer convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Integer convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException { return NumberUtils.parseInteger(cellData.getStringValue(), contentProperty); } @Override - public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java index 6ee0217b..298fed5e 100644 --- a/src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java @@ -16,7 +16,7 @@ public class LongBooleanConverter implements Converter { private static final Long ZERO = 0L; @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Long.class; } @@ -26,7 +26,7 @@ public class LongBooleanConverter implements Converter { } @Override - public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (cellData.getBooleanValue()) { return ONE; @@ -35,12 +35,12 @@ public class LongBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (ONE.equals(value)) { - return new CellData(Boolean.TRUE); + return new CellData<>(Boolean.TRUE); } - return new CellData(Boolean.FALSE); + return new CellData<>(Boolean.FALSE); } } diff --git a/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java b/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java index 8058d624..7e4aa235 100644 --- a/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java @@ -1,12 +1,12 @@ package com.alibaba.excel.converters.longconverter; -import java.math.BigDecimal; - import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.NumberUtils; +import com.alibaba.excel.write.metadata.holder.WriteHolder; /** * Long and number converter @@ -16,7 +16,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class LongNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Long.class; } @@ -26,15 +26,15 @@ public class LongNumberConverter implements Converter { } @Override - public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getNumberValue().longValue(); } @Override - public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(BigDecimal.valueOf(value)); + public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } } diff --git a/src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java b/src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java index 06e94f03..873fb113 100644 --- a/src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.NumberUtils; public class LongStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Long.class; } @@ -27,14 +27,14 @@ public class LongStringConverter implements Converter { } @Override - public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException { return NumberUtils.parseLong(cellData.getStringValue(), contentProperty); } @Override - public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java index 2c0cc61d..eb39b7de 100644 --- a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java @@ -16,7 +16,7 @@ public class ShortBooleanConverter implements Converter { private static final Short ZERO = 0; @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Short.class; } @@ -26,7 +26,7 @@ public class ShortBooleanConverter implements Converter { } @Override - public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (cellData.getBooleanValue()) { return ONE; @@ -35,12 +35,12 @@ public class ShortBooleanConverter implements Converter { } @Override - public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (ONE.equals(value)) { - return new CellData(Boolean.TRUE); + return new CellData<>(Boolean.TRUE); } - return new CellData(Boolean.FALSE); + return new CellData<>(Boolean.FALSE); } } diff --git a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java index 357c6aeb..eedfca4f 100644 --- a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java @@ -7,6 +7,8 @@ import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.util.NumberUtils; +import com.alibaba.excel.write.metadata.holder.WriteHolder; /** * Short and number converter @@ -16,7 +18,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class ShortNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Short.class; } @@ -26,15 +28,14 @@ public class ShortNumberConverter implements Converter { } @Override - public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getNumberValue().shortValue(); } @Override - public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, - GlobalConfiguration globalConfiguration) { - return new CellData(new BigDecimal(Short.toString(value))); + public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + return NumberUtils.formatToCellData(value, contentProperty, currentWriteHolder); } - } diff --git a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java index a683a038..85c56067 100644 --- a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.NumberUtils; public class ShortStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return Short.class; } @@ -27,14 +27,14 @@ public class ShortStringConverter implements Converter { } @Override - public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public Short convertToJavaData(CellDatacellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws ParseException { return NumberUtils.parseShort(cellData.getStringValue(), contentProperty); } @Override - public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, + public CellDataconvertToExcelData(Short value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return NumberUtils.formatToCellData(value, contentProperty); + return NumberUtils.formatToCellDataString(value, contentProperty); } } diff --git a/src/main/java/com/alibaba/excel/converters/string/StringBooleanConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringBooleanConverter.java index c405de5e..f2aafb4d 100644 --- a/src/main/java/com/alibaba/excel/converters/string/StringBooleanConverter.java +++ b/src/main/java/com/alibaba/excel/converters/string/StringBooleanConverter.java @@ -14,7 +14,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; public class StringBooleanConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return String.class; } @@ -24,15 +24,15 @@ public class StringBooleanConverter implements Converter { } @Override - public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getBooleanValue().toString(); } @Override - public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(Boolean.valueOf(value)); + return new CellData<>(Boolean.valueOf(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/string/StringErrorConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringErrorConverter.java index 66112e1a..f0a71a46 100644 --- a/src/main/java/com/alibaba/excel/converters/string/StringErrorConverter.java +++ b/src/main/java/com/alibaba/excel/converters/string/StringErrorConverter.java @@ -13,7 +13,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; */ public class StringErrorConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return String.class; } @@ -23,15 +23,15 @@ public class StringErrorConverter implements Converter { } @Override - public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getStringValue(); } @Override - public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(CellDataTypeEnum.ERROR, value); + return new CellData<>(CellDataTypeEnum.ERROR, value); } } diff --git a/src/main/java/com/alibaba/excel/converters/string/StringImageConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringImageConverter.java index 931d4fa9..37e1c3c7 100644 --- a/src/main/java/com/alibaba/excel/converters/string/StringImageConverter.java +++ b/src/main/java/com/alibaba/excel/converters/string/StringImageConverter.java @@ -17,7 +17,7 @@ import com.alibaba.excel.util.FileUtils; */ public class StringImageConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return String.class; } @@ -27,15 +27,15 @@ public class StringImageConverter implements Converter { } @Override - public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { throw new UnsupportedOperationException("Cannot convert images to string"); } @Override - public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws IOException { - return new CellData(FileUtils.readFileToByteArray(new File(value))); + return new CellData<>(FileUtils.readFileToByteArray(new File(value))); } } diff --git a/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java index b31bc706..e9b6fef6 100644 --- a/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java @@ -22,7 +22,7 @@ import com.alibaba.excel.util.StringUtils; public class StringNumberConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return String.class; } @@ -32,7 +32,7 @@ public class StringNumberConverter implements Converter { } @Override - public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { // If there are "DateTimeFormat", read as date if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { @@ -55,8 +55,8 @@ public class StringNumberConverter implements Converter { } @Override - public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(new BigDecimal(value)); + return new CellData<>(new BigDecimal(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java index df1b1e14..3b1ce3df 100644 --- a/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java @@ -13,7 +13,7 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; */ public class StringStringConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return String.class; } @@ -23,15 +23,15 @@ public class StringStringConverter implements Converter { } @Override - public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { return cellData.getStringValue(); } @Override - public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value); + return new CellData<>(value); } } diff --git a/src/main/java/com/alibaba/excel/converters/url/UrlImageConverter.java b/src/main/java/com/alibaba/excel/converters/url/UrlImageConverter.java index b622d66d..a9e60df9 100644 --- a/src/main/java/com/alibaba/excel/converters/url/UrlImageConverter.java +++ b/src/main/java/com/alibaba/excel/converters/url/UrlImageConverter.java @@ -19,7 +19,7 @@ import com.alibaba.excel.util.IoUtils; */ public class UrlImageConverter implements Converter { @Override - public Class supportJavaTypeKey() { + public Class supportJavaTypeKey() { return URL.class; } @@ -29,19 +29,19 @@ public class UrlImageConverter implements Converter { } @Override - public URL convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, + public URL convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { throw new UnsupportedOperationException("Cannot convert images to url."); } @Override - public CellData convertToExcelData(URL value, ExcelContentProperty contentProperty, + public CellData convertToExcelData(URL value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws IOException { InputStream inputStream = null; try { inputStream = value.openStream(); byte[] bytes = IoUtils.toByteArray(inputStream); - return new CellData(bytes); + return new CellData<>(bytes); } finally { if (inputStream != null) { inputStream.close(); diff --git a/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java b/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java index 44efc179..6220340a 100644 --- a/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java +++ b/src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java @@ -39,9 +39,15 @@ public enum CellDataTypeEnum { /** * Images are currently supported only when writing */ - IMAGE; + IMAGE, + /** + * date.Support only when writing. + */ + DATE, + ; private static final Map TYPE_ROUTING_MAP = new HashMap(16); + static { TYPE_ROUTING_MAP.put("s", STRING); TYPE_ROUTING_MAP.put("str", DIRECT_STRING); diff --git a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java index 4b1b802a..a0cd5078 100644 --- a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java +++ b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java @@ -16,7 +16,7 @@ import com.alibaba.excel.util.ConverterUtils; public abstract class AnalysisEventListener implements ReadListener { @Override - public void invokeHead(Map headMap, AnalysisContext context) { + public void invokeHead(Map> headMap, AnalysisContext context) { invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context); } diff --git a/src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java b/src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java index 5198c20f..7231afd9 100644 --- a/src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java +++ b/src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java @@ -4,11 +4,16 @@ import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.write.builder.ExcelWriterBuilder; +import lombok.Getter; +import lombok.Setter; + /** * Data convert exception * * @author Jiaju Zhuang */ +@Getter +@Setter public class ExcelDataConvertException extends RuntimeException { /** * NotNull. @@ -21,7 +26,7 @@ public class ExcelDataConvertException extends RuntimeException { /** * NotNull. */ - private CellData cellData; + private CellData cellData; /** * Nullable.Only when the header is configured and when the class header is used is not null. * @@ -47,35 +52,4 @@ public class ExcelDataConvertException extends RuntimeException { this.excelContentProperty = excelContentProperty; } - public Integer getRowIndex() { - return rowIndex; - } - - public void setRowIndex(Integer rowIndex) { - this.rowIndex = rowIndex; - } - - public Integer getColumnIndex() { - return columnIndex; - } - - public void setColumnIndex(Integer columnIndex) { - this.columnIndex = columnIndex; - } - - public ExcelContentProperty getExcelContentProperty() { - return excelContentProperty; - } - - public void setExcelContentProperty(ExcelContentProperty excelContentProperty) { - this.excelContentProperty = excelContentProperty; - } - - public CellData getCellData() { - return cellData; - } - - public void setCellData(CellData cellData) { - this.cellData = cellData; - } } diff --git a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java index f7cb1ced..548503d0 100644 --- a/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/AbstractHolder.java @@ -34,7 +34,7 @@ public abstract class AbstractHolder implements ConfigurationHolder { *

* Write key: */ - private Map converterMap; + private Map> converterMap; public AbstractHolder(BasicParameter basicParameter, AbstractHolder prentAbstractHolder) { this.newInitialization = Boolean.TRUE; @@ -103,16 +103,16 @@ public abstract class AbstractHolder implements ConfigurationHolder { this.globalConfiguration = globalConfiguration; } - public Map getConverterMap() { + public Map> getConverterMap() { return converterMap; } - public void setConverterMap(Map converterMap) { + public void setConverterMap(Map> converterMap) { this.converterMap = converterMap; } @Override - public Map converterMap() { + public Map> converterMap() { return getConverterMap(); } diff --git a/src/main/java/com/alibaba/excel/metadata/CellData.java b/src/main/java/com/alibaba/excel/metadata/CellData.java index 2124e103..5a522ba8 100644 --- a/src/main/java/com/alibaba/excel/metadata/CellData.java +++ b/src/main/java/com/alibaba/excel/metadata/CellData.java @@ -1,10 +1,14 @@ package com.alibaba.excel.metadata; import java.math.BigDecimal; +import java.util.Date; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.util.StringUtils; +import lombok.Getter; +import lombok.Setter; + /** * Excel internal cell data. * @@ -12,6 +16,8 @@ import com.alibaba.excel.util.StringUtils; * * @author Jiaju Zhuang */ +@Getter +@Setter public class CellData extends AbstractCell { private CellDataTypeEnum type; /** @@ -30,11 +36,15 @@ public class CellData extends AbstractCell { private String formulaValue; private byte[] imageValue; /** - * The number formatting.Currently only supported when reading + * Support only when writing. + */ + private Date dateValue; + /** + * The number formatting. */ - private Integer dataFormat; + private Short dataFormat; /** - * The string of number formatting.Currently only supported when reading + * The string of number formatting. */ private String dataFormatString; /** @@ -53,6 +63,8 @@ public class CellData extends AbstractCell { this.dataFormat = other.dataFormat; this.dataFormatString = other.dataFormatString; this.data = other.data; + setRowIndex(other.getRowIndex()); + setColumnIndex(other.getColumnIndex()); } public CellData() {} @@ -110,92 +122,22 @@ public class CellData extends AbstractCell { this.formula = Boolean.FALSE; } - public CellData(CellDataTypeEnum type) { - if (type == null) { - throw new IllegalArgumentException("Type can not be null"); + public CellData(Date dateValue) { + if (dateValue == null) { + throw new IllegalArgumentException("DateValue can not be null"); } - this.type = type; + this.type = CellDataTypeEnum.DATE; + this.dateValue = dateValue; this.formula = Boolean.FALSE; } - public CellDataTypeEnum getType() { - return type; - } - public void setType(CellDataTypeEnum type) { + public CellData(CellDataTypeEnum type) { + if (type == null) { + throw new IllegalArgumentException("Type can not be null"); + } this.type = type; - } - - public BigDecimal getNumberValue() { - return numberValue; - } - - public void setNumberValue(BigDecimal numberValue) { - this.numberValue = numberValue; - } - - public String getStringValue() { - return stringValue; - } - - public void setStringValue(String stringValue) { - this.stringValue = stringValue; - } - - public Boolean getBooleanValue() { - return booleanValue; - } - - public void setBooleanValue(Boolean booleanValue) { - this.booleanValue = booleanValue; - } - - public Boolean getFormula() { - return formula; - } - - public void setFormula(Boolean formula) { - this.formula = formula; - } - - public String getFormulaValue() { - return formulaValue; - } - - public void setFormulaValue(String formulaValue) { - this.formulaValue = formulaValue; - } - - public byte[] getImageValue() { - return imageValue; - } - - public void setImageValue(byte[] imageValue) { - this.imageValue = imageValue; - } - - public Integer getDataFormat() { - return dataFormat; - } - - public void setDataFormat(Integer dataFormat) { - this.dataFormat = dataFormat; - } - - public String getDataFormatString() { - return dataFormatString; - } - - public void setDataFormatString(String dataFormatString) { - this.dataFormatString = dataFormatString; - } - - public T getData() { - return data; - } - - public void setData(T data) { - this.data = data; + this.formula = Boolean.FALSE; } /** @@ -226,37 +168,37 @@ public class CellData extends AbstractCell { } } - public static CellData newEmptyInstance() { + public static CellData newEmptyInstance() { return newEmptyInstance(null, null); } - public static CellData newEmptyInstance(Integer rowIndex, Integer columnIndex) { - CellData cellData = new CellData(CellDataTypeEnum.EMPTY); + public static CellData newEmptyInstance(Integer rowIndex, Integer columnIndex) { + CellData cellData = new CellData<>(CellDataTypeEnum.EMPTY); cellData.setRowIndex(rowIndex); cellData.setColumnIndex(columnIndex); return cellData; } - public static CellData newInstance(Boolean booleanValue) { + public static CellData newInstance(Boolean booleanValue) { return newInstance(booleanValue, null, null); } - public static CellData newInstance(Boolean booleanValue, Integer rowIndex, Integer columnIndex) { - CellData cellData = new CellData(booleanValue); + public static CellData newInstance(Boolean booleanValue, Integer rowIndex, Integer columnIndex) { + CellData cellData = new CellData<>(booleanValue); cellData.setRowIndex(rowIndex); cellData.setColumnIndex(columnIndex); return cellData; } - public static CellData newInstance(String stringValue, Integer rowIndex, Integer columnIndex) { - CellData cellData = new CellData(stringValue); + public static CellData newInstance(String stringValue, Integer rowIndex, Integer columnIndex) { + CellData cellData = new CellData<>(stringValue); cellData.setRowIndex(rowIndex); cellData.setColumnIndex(columnIndex); return cellData; } - public static CellData newInstance(BigDecimal numberValue, Integer rowIndex, Integer columnIndex) { - CellData cellData = new CellData(numberValue); + public static CellData newInstance(BigDecimal numberValue, Integer rowIndex, Integer columnIndex) { + CellData cellData = new CellData<>(numberValue); cellData.setRowIndex(rowIndex); cellData.setColumnIndex(columnIndex); return cellData; @@ -269,14 +211,28 @@ public class CellData extends AbstractCell { } switch (type) { case NUMBER: + if (numberValue == null) { + return StringUtils.EMPTY; + } return numberValue.toString(); case BOOLEAN: + if (booleanValue == null) { + return StringUtils.EMPTY; + } return booleanValue.toString(); case DIRECT_STRING: case STRING: case ERROR: return stringValue; + case DATE: + if (dateValue == null) { + return StringUtils.EMPTY; + } + return dateValue.toString(); case IMAGE: + if (imageValue == null) { + return StringUtils.EMPTY; + } return "image[" + imageValue.length + "]"; default: return StringUtils.EMPTY; diff --git a/src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java b/src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java index d84b1d58..ee4d7edf 100644 --- a/src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java @@ -32,5 +32,5 @@ public interface ConfigurationHolder extends Holder { * * @return Converter */ - Map converterMap(); + Map> converterMap(); } 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 be9d2ad6..e9266c71 100644 --- a/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java +++ b/src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java @@ -170,7 +170,7 @@ public class DataFormatter { this.decimalSymbols = DecimalFormatSymbols.getInstance(this.locale); } - private Format getFormat(Double data,Integer dataFormat, String dataFormatString) { + private Format getFormat(Double data,Short dataFormat, String dataFormatString) { // Might be better to separate out the n p and z formats, falling back to p when n and z are not set. // That however would require other code to be re factored. @@ -225,7 +225,7 @@ public class DataFormatter { return format; } - private Format createFormat(Integer dataFormat, String dataFormatString) { + private Format createFormat(Short dataFormat, String dataFormatString) { String formatStr = dataFormatString; Format format = checkSpecialConverter(formatStr); @@ -607,7 +607,7 @@ public class DataFormatter { * @param dataFormatString * @return Formatted value */ - private String getFormattedDateString(Double data, Integer dataFormat, String dataFormatString) { + private String getFormattedDateString(Double data, Short dataFormat, String dataFormatString) { Format dateFormat = getFormat(data, dataFormat, dataFormatString); if (dateFormat instanceof ExcelStyleDateFormatter) { // Hint about the raw excel value @@ -630,7 +630,7 @@ public class DataFormatter { * @param dataFormatString * @return a formatted number string */ - private String getFormattedNumberString(Double data, Integer dataFormat, String dataFormatString) { + private String getFormattedNumberString(Double data, Short dataFormat, String dataFormatString) { Format numberFormat = getFormat(data, dataFormat, dataFormatString); String formatted = numberFormat.format(data); return formatted.replaceFirst("E(\\d)", "E+$1"); // to match Excel's E-notation @@ -644,7 +644,7 @@ public class DataFormatter { * @param dataFormatString * @return */ - public String format(Double data, Integer dataFormat, String dataFormatString) { + public String format(Double data, Short dataFormat, String dataFormatString) { if (DateUtils.isADateFormat(dataFormat, dataFormatString)) { return getFormattedDateString(data, dataFormat, dataFormatString); } diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java index a191260d..878e8c0d 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; +import org.apache.commons.collections4.CollectionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -21,7 +22,6 @@ import com.alibaba.excel.exception.ExcelCommonException; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Holder; import com.alibaba.excel.util.ClassUtils; -import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; diff --git a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java index 78b57e0a..13e3d45b 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java +++ b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java @@ -14,9 +14,10 @@ import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.property.ExcelContentProperty; -import com.alibaba.excel.read.metadata.holder.ReadHolder; +import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; import com.alibaba.excel.util.ConverterUtils; +import com.alibaba.excel.util.FieldUtils; import net.sf.cglib.beans.BeanMap; @@ -25,28 +26,28 @@ import net.sf.cglib.beans.BeanMap; * * @author jipengfei */ -public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener> { +public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener>> { @Override - public void invokeHead(Map cellDataMap, AnalysisContext context) {} + public void invokeHead(Map> cellDataMap, AnalysisContext context) {} @Override - public void invoke(Map cellDataMap, AnalysisContext context) { - ReadHolder currentReadHolder = context.currentReadHolder(); - if (HeadKindEnum.CLASS.equals(currentReadHolder.excelReadHeadProperty().getHeadKind())) { + public void invoke(Map> cellDataMap, AnalysisContext context) { + ReadSheetHolder readSheetHolder = context.readSheetHolder(); + if (HeadKindEnum.CLASS.equals(readSheetHolder.excelReadHeadProperty().getHeadKind())) { context.readRowHolder() - .setCurrentRowAnalysisResult(buildUserModel(cellDataMap, currentReadHolder, context)); + .setCurrentRowAnalysisResult(buildUserModel(cellDataMap, readSheetHolder, context)); return; } - context.readRowHolder().setCurrentRowAnalysisResult(buildStringList(cellDataMap, currentReadHolder, context)); + context.readRowHolder().setCurrentRowAnalysisResult(buildStringList(cellDataMap, readSheetHolder, context)); } - private Object buildStringList(Map cellDataMap, ReadHolder currentReadHolder, + private Object buildStringList(Map> cellDataMap, ReadSheetHolder readSheetHolder, AnalysisContext context) { int index = 0; if (context.readWorkbookHolder().getDefaultReturnMap()) { Map map = new LinkedHashMap(cellDataMap.size() * 4 / 3 + 1); - for (Map.Entry entry : cellDataMap.entrySet()) { + for (Map.Entry> entry : cellDataMap.entrySet()) { Integer key = entry.getKey(); CellData cellData = entry.getValue(); while (index < key) { @@ -59,10 +60,10 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener continue; } map.put(key, - (String)ConverterUtils.convertToJavaObject(cellData, null, null, currentReadHolder.converterMap(), - currentReadHolder.globalConfiguration(), context.readRowHolder().getRowIndex(), key)); + (String)ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(), + readSheetHolder, context.readRowHolder().getRowIndex(), key)); } - int headSize = currentReadHolder.excelReadHeadProperty().getHeadMap().size(); + int headSize = readSheetHolder.excelReadHeadProperty().getHeadMap().size(); while (index < headSize) { map.put(index, null); index++; @@ -70,10 +71,10 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener return map; } else { // Compatible with the old code the old code returns a list - List list = new ArrayList(); - for (Map.Entry entry : cellDataMap.entrySet()) { + List list = new ArrayList<>(); + for (Map.Entry> entry : cellDataMap.entrySet()) { Integer key = entry.getKey(); - CellData cellData = entry.getValue(); + CellData cellData = entry.getValue(); while (index < key) { list.add(null); index++; @@ -84,10 +85,10 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener continue; } list.add( - (String)ConverterUtils.convertToJavaObject(cellData, null, null, currentReadHolder.converterMap(), - currentReadHolder.globalConfiguration(), context.readRowHolder().getRowIndex(), key)); + (String)ConverterUtils.convertToJavaObject(cellData, null, null, readSheetHolder.converterMap(), + readSheetHolder, context.readRowHolder().getRowIndex(), key)); } - int headSize = currentReadHolder.excelReadHeadProperty().getHeadMap().size(); + int headSize = readSheetHolder.excelReadHeadProperty().getHeadMap().size(); while (index < headSize) { list.add(null); index++; @@ -96,15 +97,15 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener } } - private Object buildUserModel(Map cellDataMap, ReadHolder currentReadHolder, + private Object buildUserModel(Map> cellDataMap, ReadSheetHolder readSheetHolder, AnalysisContext context) { - ExcelReadHeadProperty excelReadHeadProperty = currentReadHolder.excelReadHeadProperty(); + ExcelReadHeadProperty excelReadHeadProperty = readSheetHolder.excelReadHeadProperty(); Object resultModel; try { resultModel = excelReadHeadProperty.getHeadClazz().newInstance(); } catch (Exception e) { throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), 0, - new CellData(CellDataTypeEnum.EMPTY), null, + new CellData<>(CellDataTypeEnum.EMPTY), null, "Can not instance class: " + excelReadHeadProperty.getHeadClazz().getName(), e); } Map headMap = excelReadHeadProperty.getHeadMap(); @@ -115,16 +116,16 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener if (!cellDataMap.containsKey(index)) { continue; } - CellData cellData = cellDataMap.get(index); + CellData cellData = cellDataMap.get(index); if (cellData.getType() == CellDataTypeEnum.EMPTY) { continue; } ExcelContentProperty excelContentProperty = contentPropertyMap.get(index); Object value = ConverterUtils.convertToJavaObject(cellData, excelContentProperty.getField(), - excelContentProperty, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration(), + excelContentProperty, readSheetHolder.converterMap(), readSheetHolder, context.readRowHolder().getRowIndex(), index); if (value != null) { - map.put(excelContentProperty.getField().getName(), value); + map.put(FieldUtils.resolveCglibFieldName(excelContentProperty.getField()), value); } } BeanMap.create(resultModel).putAll(map); diff --git a/src/main/java/com/alibaba/excel/read/listener/ReadListener.java b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java index f1d341f5..b3a2e970 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ReadListener.java +++ b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java @@ -29,7 +29,7 @@ public interface ReadListener extends Listener { * @param headMap * @param context */ - void invokeHead(Map headMap, AnalysisContext context); + void invokeHead(Map> headMap, AnalysisContext context); /** * When analysis one row trigger invoke function. diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java index c431ab49..95bf6f89 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java @@ -1,12 +1,8 @@ package com.alibaba.excel.read.metadata.holder; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.ConverterKeyBuild; import com.alibaba.excel.converters.DefaultConverterLoader; @@ -17,6 +13,10 @@ import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.metadata.ReadBasicParameter; import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; +import com.alibaba.excel.util.ListUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Read Holder @@ -24,8 +24,6 @@ import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; * @author Jiaju Zhuang */ public abstract class AbstractReadHolder extends AbstractHolder implements ReadHolder { - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractReadHolder.class); - /** * Count the number of added heads when read sheet. * @@ -84,9 +82,9 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH } if (parentAbstractReadHolder == null) { - this.readListenerList = new ArrayList(); + this.readListenerList = ListUtils.newArrayList(); } else { - this.readListenerList = new ArrayList(parentAbstractReadHolder.getReadListenerList()); + this.readListenerList = ListUtils.newArrayList(parentAbstractReadHolder.getReadListenerList()); } if (HolderEnum.WORKBOOK.equals(holderType())) { Boolean useDefaultListener = ((ReadWorkbook)readBasicParameter).getUseDefaultListener(); @@ -102,11 +100,11 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH if (parentAbstractReadHolder == null) { setConverterMap(DefaultConverterLoader.loadDefaultReadConverter()); } else { - setConverterMap(new HashMap(parentAbstractReadHolder.getConverterMap())); + setConverterMap(new HashMap<>(parentAbstractReadHolder.getConverterMap())); } if (readBasicParameter.getCustomConverterList() != null && !readBasicParameter.getCustomConverterList().isEmpty()) { - for (Converter converter : readBasicParameter.getCustomConverterList()) { + for (Converter converter : readBasicParameter.getCustomConverterList()) { getConverterMap().put( ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()), converter); diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java index 7a5272a6..ddb5ca27 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java @@ -51,7 +51,7 @@ public class ReadSheetHolder extends AbstractReadHolder { /** * Current CellData */ - private CellData tempCellData; + private CellData tempCellData; public ReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { super(readSheet, readWorkbookHolder, readWorkbookHolder.getReadWorkbook().getConvertAllFiled()); @@ -135,11 +135,11 @@ public class ReadSheetHolder extends AbstractReadHolder { this.rowIndex = rowIndex; } - public CellData getTempCellData() { + public CellData getTempCellData() { return tempCellData; } - public void setTempCellData(CellData tempCellData) { + public void setTempCellData(CellData tempCellData) { this.tempCellData = tempCellData; } diff --git a/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java b/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java index ddd19504..f23f58c9 100644 --- a/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java +++ b/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java @@ -82,7 +82,7 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { private void dealData(AnalysisContext analysisContext) { ReadRowHolder readRowHolder = analysisContext.readRowHolder(); - Map cellDataMap = (Map)readRowHolder.getCellMap(); + Map> cellDataMap = (Map)readRowHolder.getCellMap(); readRowHolder.setCurrentRowAnalysisResult(cellDataMap); int rowIndex = readRowHolder.getRowIndex(); int currentHeadRowNumber = analysisContext.readSheetHolder().getHeadRowNumber(); @@ -111,7 +111,7 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { } } - private void buildHead(AnalysisContext analysisContext, Map cellDataMap) { + private void buildHead(AnalysisContext analysisContext, Map> cellDataMap) { if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) { return; } diff --git a/src/main/java/com/alibaba/excel/util/BooleanUtils.java b/src/main/java/com/alibaba/excel/util/BooleanUtils.java index 55c48a18..18f6dd39 100644 --- a/src/main/java/com/alibaba/excel/util/BooleanUtils.java +++ b/src/main/java/com/alibaba/excel/util/BooleanUtils.java @@ -25,4 +25,79 @@ public class BooleanUtils { } } + + // boolean Boolean methods + //----------------------------------------------------------------------- + /** + *

Checks if a {@code Boolean} value is {@code true}, + * handling {@code null} by returning {@code false}.

+ * + *
+     *   BooleanUtils.isTrue(Boolean.TRUE)  = true
+     *   BooleanUtils.isTrue(Boolean.FALSE) = false
+     *   BooleanUtils.isTrue(null)          = false
+     * 
+ * + * @param bool the boolean to check, null returns {@code false} + * @return {@code true} only if the input is non-null and true + * @since 2.1 + */ + public static boolean isTrue(final Boolean bool) { + return Boolean.TRUE.equals(bool); + } + + /** + *

Checks if a {@code Boolean} value is not {@code true}, + * handling {@code null} by returning {@code true}.

+ * + *
+     *   BooleanUtils.isNotTrue(Boolean.TRUE)  = false
+     *   BooleanUtils.isNotTrue(Boolean.FALSE) = true
+     *   BooleanUtils.isNotTrue(null)          = true
+     * 
+ * + * @param bool the boolean to check, null returns {@code true} + * @return {@code true} if the input is null or false + * @since 2.3 + */ + public static boolean isNotTrue(final Boolean bool) { + return !isTrue(bool); + } + + /** + *

Checks if a {@code Boolean} value is {@code false}, + * handling {@code null} by returning {@code false}.

+ * + *
+     *   BooleanUtils.isFalse(Boolean.TRUE)  = false
+     *   BooleanUtils.isFalse(Boolean.FALSE) = true
+     *   BooleanUtils.isFalse(null)          = false
+     * 
+ * + * @param bool the boolean to check, null returns {@code false} + * @return {@code true} only if the input is non-null and false + * @since 2.1 + */ + public static boolean isFalse(final Boolean bool) { + return Boolean.FALSE.equals(bool); + } + + /** + *

Checks if a {@code Boolean} value is not {@code false}, + * handling {@code null} by returning {@code true}.

+ * + *
+     *   BooleanUtils.isNotFalse(Boolean.TRUE)  = true
+     *   BooleanUtils.isNotFalse(Boolean.FALSE) = false
+     *   BooleanUtils.isNotFalse(null)          = true
+     * 
+ * + * @param bool the boolean to check, null returns {@code true} + * @return {@code true} if the input is null or true + * @since 2.3 + */ + public static boolean isNotFalse(final Boolean bool) { + return !isFalse(bool); + } + } diff --git a/src/main/java/com/alibaba/excel/util/ClassUtils.java b/src/main/java/com/alibaba/excel/util/ClassUtils.java index 936c325d..16643de4 100644 --- a/src/main/java/com/alibaba/excel/util/ClassUtils.java +++ b/src/main/java/com/alibaba/excel/util/ClassUtils.java @@ -6,6 +6,8 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -208,4 +210,51 @@ public class ClassUtils { return ignoreMap; } } + + + /** + *

Gets a {@code List} of all interfaces implemented by the given + * class and its superclasses.

+ * + *

The order is determined by looking through each interface in turn as + * declared in the source file and following its hierarchy up. Then each + * superclass is considered in the same way. Later duplicates are ignored, + * so the order is maintained.

+ * + * @param cls the class to look up, may be {@code null} + * @return the {@code List} of interfaces in order, + * {@code null} if null input + */ + public static List> getAllInterfaces(final Class cls) { + if (cls == null) { + return null; + } + + final LinkedHashSet> interfacesFound = new LinkedHashSet<>(); + getAllInterfaces(cls, interfacesFound); + + return new ArrayList<>(interfacesFound); + } + + + /** + * Gets the interfaces for the specified class. + * + * @param cls the class to look up, may be {@code null} + * @param interfacesFound the {@code Set} of interfaces for the class + */ + private static void getAllInterfaces(Class cls, final HashSet> interfacesFound) { + while (cls != null) { + final Class[] interfaces = cls.getInterfaces(); + + for (final Class i : interfaces) { + if (interfacesFound.add(i)) { + getAllInterfaces(i, interfacesFound); + } + } + + cls = cls.getSuperclass(); + } + } + } diff --git a/src/main/java/com/alibaba/excel/util/CollectionUtils.java b/src/main/java/com/alibaba/excel/util/CollectionUtils.java deleted file mode 100644 index f413be17..00000000 --- a/src/main/java/com/alibaba/excel/util/CollectionUtils.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.alibaba.excel.util; - -import java.util.Collection; -import java.util.Map; - -/** - * Collection utils - * - * @author jipengfei - */ -public class CollectionUtils { - - private CollectionUtils() {} - - public static boolean isEmpty(Collection collection) { - return (collection == null || collection.isEmpty()); - } - - public static boolean isEmpty(Map map) { - return (map == null || map.isEmpty()); - } -} diff --git a/src/main/java/com/alibaba/excel/util/ConverterUtils.java b/src/main/java/com/alibaba/excel/util/ConverterUtils.java index 43b12c53..61f69ac4 100644 --- a/src/main/java/com/alibaba/excel/util/ConverterUtils.java +++ b/src/main/java/com/alibaba/excel/util/ConverterUtils.java @@ -3,7 +3,6 @@ package com.alibaba.excel.util; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.HashMap; import java.util.Map; import com.alibaba.excel.context.AnalysisContext; @@ -12,9 +11,9 @@ import com.alibaba.excel.converters.ConverterKeyBuild; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.GlobalConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.read.metadata.holder.ReadHolder; +import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; /** * Converting objects @@ -32,13 +31,13 @@ public class ConverterUtils { * @param context * @return */ - public static Map convertToStringMap(Map cellDataMap, AnalysisContext context) { - Map stringMap = new HashMap(cellDataMap.size() * 4 / 3 + 1); - ReadHolder currentReadHolder = context.currentReadHolder(); + public static Map convertToStringMap(Map> cellDataMap, AnalysisContext context) { + Map stringMap = MapUtils.newHashMapWithExpectedSize(cellDataMap.size()); + ReadSheetHolder readSheetHolder = context.readSheetHolder(); int index = 0; - for (Map.Entry entry : cellDataMap.entrySet()) { + for (Map.Entry> entry : cellDataMap.entrySet()) { Integer key = entry.getKey(); - CellData cellData = entry.getValue(); + CellData cellData = entry.getValue(); while (index < key) { stringMap.put(index, null); index++; @@ -48,15 +47,15 @@ public class ConverterUtils { stringMap.put(key, null); continue; } - Converter converter = - currentReadHolder.converterMap().get(ConverterKeyBuild.buildKey(String.class, cellData.getType())); + Converter converter = + readSheetHolder.converterMap().get(ConverterKeyBuild.buildKey(String.class, cellData.getType())); if (converter == null) { throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), key, cellData, null, "Converter not found, convert " + cellData.getType() + " to String"); } try { stringMap.put(key, - (String)(converter.convertToJavaData(cellData, null, currentReadHolder.globalConfiguration()))); + (String)(converter.convertToJavaData(cellData, null, readSheetHolder))); } catch (Exception e) { throw new ExcelDataConvertException(context.readRowHolder().getRowIndex(), key, cellData, null, "Convert data " + cellData + " to String error ", e); @@ -72,15 +71,15 @@ public class ConverterUtils { * @param field * @param contentProperty * @param converterMap - * @param globalConfiguration + * @param readSheetHolder * @param rowIndex * @param columnIndex * @return */ - public static Object convertToJavaObject(CellData cellData, Field field, ExcelContentProperty contentProperty, - Map converterMap, GlobalConfiguration globalConfiguration, Integer rowIndex, + public static Object convertToJavaObject(CellData cellData, Field field, ExcelContentProperty contentProperty, + Map> converterMap, ReadSheetHolder readSheetHolder, Integer rowIndex, Integer columnIndex) { - Class clazz; + Class clazz; if (field == null) { clazz = String.class; } else { @@ -88,37 +87,37 @@ public class ConverterUtils { } if (clazz == CellData.class) { Type type = field.getGenericType(); - Class classGeneric; + Class classGeneric; if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type; - classGeneric = (Class)parameterizedType.getActualTypeArguments()[0]; + classGeneric = (Class)parameterizedType.getActualTypeArguments()[0]; } else { classGeneric = String.class; } - CellData cellDataReturn = new CellData(cellData); + CellData cellDataReturn = new CellData(cellData); cellDataReturn.setData(doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap, - globalConfiguration, rowIndex, columnIndex)); + readSheetHolder, rowIndex, columnIndex)); return cellDataReturn; } - return doConvertToJavaObject(cellData, clazz, contentProperty, converterMap, globalConfiguration, rowIndex, + return doConvertToJavaObject(cellData, clazz, contentProperty, converterMap, readSheetHolder, rowIndex, columnIndex); } /** - * * @param cellData * @param clazz * @param contentProperty * @param converterMap - * @param globalConfiguration + * @param readSheetHolder * @param rowIndex * @param columnIndex * @return */ - private static Object doConvertToJavaObject(CellData cellData, Class clazz, ExcelContentProperty contentProperty, - Map converterMap, GlobalConfiguration globalConfiguration, Integer rowIndex, + private static Object doConvertToJavaObject(CellData cellData, Class clazz, + ExcelContentProperty contentProperty, + Map> converterMap, ReadSheetHolder readSheetHolder, Integer rowIndex, Integer columnIndex) { - Converter converter = null; + Converter converter = null; if (contentProperty != null) { converter = contentProperty.getConverter(); } @@ -130,7 +129,7 @@ public class ConverterUtils { "Converter not found, convert " + cellData.getType() + " to " + clazz.getName()); } try { - return converter.convertToJavaData(cellData, contentProperty, globalConfiguration); + return converter.convertToJavaData(cellData, contentProperty, readSheetHolder); } catch (Exception e) { throw new ExcelDataConvertException(rowIndex, columnIndex, cellData, contentProperty, "Convert data " + cellData + " to " + clazz + " error ", e); diff --git a/src/main/java/com/alibaba/excel/util/DateUtils.java b/src/main/java/com/alibaba/excel/util/DateUtils.java index 815257b9..bc85adf6 100644 --- a/src/main/java/com/alibaba/excel/util/DateUtils.java +++ b/src/main/java/com/alibaba/excel/util/DateUtils.java @@ -17,16 +17,16 @@ public class DateUtils { /** * Is a cache of dates */ - private static final ThreadLocal> DATE_THREAD_LOCAL = - new ThreadLocal>(); + private static final ThreadLocal> DATE_THREAD_LOCAL = + new ThreadLocal<>(); /** * Is a cache of dates */ private static final ThreadLocal> DATE_FORMAT_THREAD_LOCAL = - new ThreadLocal>(); + new ThreadLocal<>(); /** - * The following patterns are used in {@link #isADateFormat(Integer, String)} + * The following patterns are used in {@link #isADateFormat(Short, String)} */ private static final Pattern date_ptrn1 = Pattern.compile("^\\[\\$\\-.*?\\]"); private static final Pattern date_ptrn2 = Pattern.compile("^\\[[a-zA-Z]+\\]"); @@ -43,11 +43,15 @@ public class DateUtils { public static final String DATE_FORMAT_10 = "yyyy-MM-dd"; public static final String DATE_FORMAT_14 = "yyyyMMddHHmmss"; + public static final String DATE_FORMAT_16 = "yyyy-MM-dd HH:mm"; + public static final String DATE_FORMAT_16_FORWARD_SLASH = "yyyy/MM/dd HH:mm"; public static final String DATE_FORMAT_17 = "yyyyMMdd HH:mm:ss"; public static final String DATE_FORMAT_19 = "yyyy-MM-dd HH:mm:ss"; public static final String DATE_FORMAT_19_FORWARD_SLASH = "yyyy/MM/dd HH:mm:ss"; private static final String MINUS = "-"; + public static String defaultDateFormat = DATE_FORMAT_19; + private DateUtils() {} /** @@ -91,6 +95,12 @@ public class DateUtils { } else { return DATE_FORMAT_19_FORWARD_SLASH; } + case 16: + if (dateString.contains(MINUS)) { + return DATE_FORMAT_16; + } else { + return DATE_FORMAT_16_FORWARD_SLASH; + } case 17: return DATE_FORMAT_17; case 14: @@ -126,7 +136,7 @@ public class DateUtils { return ""; } if (StringUtils.isEmpty(dateFormat)) { - dateFormat = DATE_FORMAT_19; + dateFormat = defaultDateFormat; } return getCacheDateFormat(dateFormat).format(date); } @@ -154,13 +164,13 @@ public class DateUtils { * @param formatString * @return */ - public static boolean isADateFormat(Integer formatIndex, String formatString) { + public static boolean isADateFormat(Short formatIndex, String formatString) { if (formatIndex == null) { return false; } - Map isDateCache = DATE_THREAD_LOCAL.get(); + Map isDateCache = DATE_THREAD_LOCAL.get(); if (isDateCache == null) { - isDateCache = new HashMap(); + isDateCache = MapUtils.newHashMap(); DATE_THREAD_LOCAL.set(isDateCache); } else { Boolean isDateCachedData = isDateCache.get(formatIndex); @@ -180,7 +190,7 @@ public class DateUtils { * @param formatString * @return */ - public static boolean isADateFormatUncached(Integer formatIndex, String formatString) { + public static boolean isADateFormatUncached(Short formatIndex, String formatString) { // First up, is this an internal date format? if (isInternalDateFormat(formatIndex)) { return true; @@ -256,9 +266,9 @@ public class DateUtils { /** * Given a format ID this will check whether the format represents an internal excel date format or not. * - * @see #isADateFormat(Integer, String) + * @see #isADateFormat(Short, String) */ - public static boolean isInternalDateFormat(int format) { + public static boolean isInternalDateFormat(short format) { switch (format) { // Internal Date Formats as described on page 427 in // Microsoft Excel Dev's Kit... diff --git a/src/main/java/com/alibaba/excel/util/FieldUtils.java b/src/main/java/com/alibaba/excel/util/FieldUtils.java new file mode 100644 index 00000000..1e788907 --- /dev/null +++ b/src/main/java/com/alibaba/excel/util/FieldUtils.java @@ -0,0 +1,145 @@ +package com.alibaba.excel.util; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; + + +/** + * Field utils + * + * @author Jiaju Zhuang + **/ +public class FieldUtils { + + private static final int START_RESOLVE_FIELD_LENGTH = 2; + + /** + * Parsing the name matching cglib。 + *
    + *
      null -> null
    + *
      string1 -> string1
    + *
      String2 -> string2
    + *
      sTring3 -> STring3
    + *
      STring4 -> STring4
    + *
      STRING5 -> STRING5
    + *
      STRing6 -> STRing6
    + *
+ * + * @param field field + * @return field name. + */ + public static String resolveCglibFieldName(Field field) { + if (field == null) { + return null; + } + String fieldName = field.getName(); + if (StringUtils.isBlank(fieldName) || fieldName.length() < START_RESOLVE_FIELD_LENGTH) { + return fieldName; + } + char firstChar = fieldName.charAt(0); + char secondChar = fieldName.charAt(1); + if (Character.isUpperCase(firstChar) == Character.isUpperCase(secondChar)) { + return fieldName; + } + if (Character.isUpperCase(firstChar)) { + return buildFieldName(Character.toLowerCase(firstChar), fieldName); + } + return buildFieldName(Character.toUpperCase(firstChar), fieldName); + } + + private static String buildFieldName(char firstChar, String fieldName) { + return firstChar + fieldName.substring(1); + } + + + /** + * Gets an accessible {@link Field} by name respecting scope. Superclasses/interfaces will be considered. + * + * @param cls + * the {@link Class} to reflect, must not be {@code null} + * @param fieldName + * the field name to obtain + * @return the Field object + * @throws IllegalArgumentException + * if the class is {@code null}, or the field name is blank or empty + */ + public static Field getField(final Class cls, final String fieldName) { + final Field field = getField(cls, fieldName, false); + MemberUtils.setAccessibleWorkaround(field); + return field; + } + + + + /** + * Gets an accessible {@link Field} by name, breaking scope if requested. Superclasses/interfaces will be + * considered. + * + * @param cls + * the {@link Class} to reflect, must not be {@code null} + * @param fieldName + * the field name to obtain + * @param forceAccess + * whether to break scope restrictions using the + * {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)} method. {@code false} will only + * match {@code public} fields. + * @return the Field object + * @throws NullPointerException if the class is {@code null} + * @throws IllegalArgumentException if the field name is blank or empty or is matched at multiple places + * in the inheritance hierarchy + */ + public static Field getField(final Class cls, final String fieldName, final boolean forceAccess) { + Validate.isTrue(cls != null, "The class must not be null"); + Validate.isTrue(StringUtils.isNotBlank(fieldName), "The field name must not be blank/empty"); + // FIXME is this workaround still needed? lang requires Java 6 + // Sun Java 1.3 has a bugged implementation of getField hence we write the + // code ourselves + + // getField() will return the Field object with the declaring class + // set correctly to the class that declares the field. Thus requesting the + // field on a subclass will return the field from the superclass. + // + // priority order for lookup: + // searchclass private/protected/package/public + // superclass protected/package/public + // private/different package blocks access to further superclasses + // implementedinterface public + + // check up the superclass hierarchy + for (Class acls = cls; acls != null; acls = acls.getSuperclass()) { + try { + final Field field = acls.getDeclaredField(fieldName); + // getDeclaredField checks for non-public scopes as well + // and it returns accurate results + if (!Modifier.isPublic(field.getModifiers())) { + if (forceAccess) { + field.setAccessible(true); + } else { + continue; + } + } + return field; + } catch (final NoSuchFieldException ex) { // NOPMD + // ignore + } + } + // check the public interface case. This must be manually searched for + // incase there is a public supersuperclass field hidden by a private/package + // superclass field. + Field match = null; + for (final Class class1 : ClassUtils.getAllInterfaces(cls)) { + try { + final Field test = class1.getField(fieldName); + Validate.isTrue(match == null, "Reference to field %s is ambiguous relative to %s" + + "; a matching field exists on two or more implemented interfaces.", fieldName, cls); + match = test; + } catch (final NoSuchFieldException ex) { // NOPMD + // ignore + } + } + return match; + } + + + +} diff --git a/src/main/java/com/alibaba/excel/util/FileUtils.java b/src/main/java/com/alibaba/excel/util/FileUtils.java index 20b16bc6..bc6b5d8a 100644 --- a/src/main/java/com/alibaba/excel/util/FileUtils.java +++ b/src/main/java/com/alibaba/excel/util/FileUtils.java @@ -9,12 +9,12 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.UUID; -import org.apache.poi.util.DefaultTempFileCreationStrategy; -import org.apache.poi.util.TempFile; - import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelCommonException; +import org.apache.poi.util.DefaultTempFileCreationStrategy; +import org.apache.poi.util.TempFile; + /** * * @author jipengfei @@ -100,10 +100,21 @@ public class FileUtils { /** * Write inputStream to file * - * @param file - * @param inputStream + * @param file file + * @param inputStream inputStream */ public static void writeToFile(File file, InputStream inputStream) { + writeToFile(file, inputStream, true); + } + + /** + * Write inputStream to file + * + * @param file file + * @param inputStream inputStream + * @param closeInputStream closeInputStream + */ + public static void writeToFile(File file, InputStream inputStream, boolean closeInputStream) { OutputStream outputStream = null; try { outputStream = new FileOutputStream(file); @@ -122,7 +133,7 @@ public class FileUtils { throw new ExcelAnalysisException("Can not close 'outputStream'!", e); } } - if (inputStream != null) { + if (inputStream != null && closeInputStream) { try { inputStream.close(); } catch (IOException e) { @@ -132,6 +143,7 @@ public class FileUtils { } } + public static void createPoiFilesDirectory() { File poiFilesPathFile = new File(poiFilesPath); createDirectory(poiFilesPathFile); diff --git a/src/main/java/com/alibaba/excel/util/IntUtils.java b/src/main/java/com/alibaba/excel/util/IntUtils.java new file mode 100644 index 00000000..6d2e244c --- /dev/null +++ b/src/main/java/com/alibaba/excel/util/IntUtils.java @@ -0,0 +1,39 @@ +package com.alibaba.excel.util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Int utils + * + * @author Jiaju Zhuang + **/ +public class IntUtils { + private IntUtils() {} + + + /** + * The largest power of two that can be represented as an {@code int}. + * + * @since 10.0 + */ + public static final int MAX_POWER_OF_TWO = 1 << (Integer.SIZE - 2); + + /** + * Returns the {@code int} nearest in value to {@code value}. + * + * @param value any {@code long} value + * @return the same value cast to {@code int} if it is in the range of the {@code int} type, + * {@link Integer#MAX_VALUE} if it is too large, or {@link Integer#MIN_VALUE} if it is too + * small + */ + public static int saturatedCast(long value) { + if (value > Integer.MAX_VALUE) { + return Integer.MAX_VALUE; + } + if (value < Integer.MIN_VALUE) { + return Integer.MIN_VALUE; + } + return (int) value; + } +} diff --git a/src/main/java/com/alibaba/excel/util/ListUtils.java b/src/main/java/com/alibaba/excel/util/ListUtils.java new file mode 100644 index 00000000..85d06b4d --- /dev/null +++ b/src/main/java/com/alibaba/excel/util/ListUtils.java @@ -0,0 +1,121 @@ +package com.alibaba.excel.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import lombok.NonNull; +import org.apache.commons.compress.utils.Iterators; + +/** + * List utils + * + * @author Jiaju Zhuang + **/ +public class ListUtils { + private ListUtils() {} + + /** + * Creates a mutable, empty {@code ArrayList} instance (for Java 6 and earlier). + * + *

Note for Java 7 and later: this method is now unnecessary and should be treated as + * deprecated. Instead, use the {@code ArrayList} {@linkplain ArrayList#ArrayList() constructor} + * directly, taking advantage of the new "diamond" syntax. + */ + public static ArrayList newArrayList() { + return new ArrayList<>(); + } + + /** + * Creates a mutable {@code ArrayList} instance containing the given elements; a very thin + * shortcut for creating an empty list and then calling {@link Iterators#addAll}. + * + */ + public static ArrayList newArrayList(Iterator elements) { + ArrayList list = newArrayList(); + Iterators.addAll(list, elements); + return list; + } + + /** + * Creates a mutable {@code ArrayList} instance containing the given elements; + * + * + *

Note for Java 7 and later: if {@code elements} is a {@link Collection}, you don't + * need this method. Use the {@code ArrayList} {@linkplain ArrayList#ArrayList(Collection) + * constructor} directly, taking advantage of the new "diamond" + * syntax. + */ + public static ArrayList newArrayList(Iterable elements) { + checkNotNull(elements); // for GWT + // Let ArrayList's sizing logic work, if possible + return (elements instanceof Collection) + ? new ArrayList<>((Collection)elements) + : newArrayList(elements.iterator()); + } + + /** + * Creates an {@code ArrayList} instance backed by an array with the specified initial size; + * simply delegates to {@link ArrayList#ArrayList(int)}. + * + *

Note for Java 7 and later: this method is now unnecessary and should be treated as + * deprecated. Instead, use {@code new }{@link ArrayList#ArrayList(int) ArrayList}{@code <>(int)} + * directly, taking advantage of the new "diamond" syntax. + * (Unlike here, there is no risk of overload ambiguity, since the {@code ArrayList} constructors + * very wisely did not accept varargs.) + * + * @param initialArraySize the exact size of the initial backing array for the returned array list + * ({@code ArrayList} documentation calls this value the "capacity") + * @return a new, empty {@code ArrayList} which is guaranteed not to resize itself unless its size + * reaches {@code initialArraySize + 1} + * @throws IllegalArgumentException if {@code initialArraySize} is negative + */ + public static ArrayList newArrayListWithCapacity(int initialArraySize) { + checkNonnegative(initialArraySize, "initialArraySize"); + return new ArrayList<>(initialArraySize); + } + + /** + * Creates an {@code ArrayList} instance to hold {@code estimatedSize} elements, plus an + * unspecified amount of padding; you almost certainly mean to call {@link + * #newArrayListWithCapacity} (see that method for further advice on usage). + * + *

Note: This method will soon be deprecated. Even in the rare case that you do want + * some amount of padding, it's best if you choose your desired amount explicitly. + * + * @param estimatedSize an estimate of the eventual {@link List#size()} of the new list + * @return a new, empty {@code ArrayList}, sized appropriately to hold the estimated number of + * elements + * @throws IllegalArgumentException if {@code estimatedSize} is negative + */ + public static ArrayList newArrayListWithExpectedSize(int estimatedSize) { + return new ArrayList<>(computeArrayListCapacity(estimatedSize)); + } + + static int computeArrayListCapacity(int arraySize) { + checkNonnegative(arraySize, "arraySize"); + return IntUtils.saturatedCast(5L + arraySize + (arraySize / 10)); + } + + static int checkNonnegative(int value, String name) { + if (value < 0) { + throw new IllegalArgumentException(name + " cannot be negative but was: " + value); + } + return value; + } + + /** + * Ensures that an object reference passed as a parameter to the calling method is not null. + * + * @param reference an object reference + * @return the non-null reference that was validated + * @throws NullPointerException if {@code reference} is null + */ + public static T checkNotNull(T reference) { + if (reference == null) { + throw new NullPointerException(); + } + return reference; + } +} diff --git a/src/main/java/com/alibaba/excel/util/MapUtils.java b/src/main/java/com/alibaba/excel/util/MapUtils.java new file mode 100644 index 00000000..6af4129e --- /dev/null +++ b/src/main/java/com/alibaba/excel/util/MapUtils.java @@ -0,0 +1,63 @@ +package com.alibaba.excel.util; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Map utils + * + * @author Jiaju Zhuang + **/ +public class MapUtils { + private MapUtils() {} + /** + * Creates a mutable, empty {@code HashMap} instance. + * + *

Note: if mutability is not required, use {@link ImmutableMap#of()} instead. + * + *

Note: if {@code K} is an {@code enum} type, use {@link #newEnumMap} instead. + * + *

Note for Java 7 and later: this method is now unnecessary and should be treated as + * deprecated. Instead, use the {@code HashMap} constructor directly, taking advantage of the new + * "diamond" syntax. + * + * @return a new, empty {@code HashMap} + */ + public static HashMap newHashMap() { + return new HashMap<>(); + } + + /** + * Creates a {@code HashMap} instance, with a high enough "initial capacity" that it should + * hold {@code expectedSize} elements without growth. This behavior cannot be broadly guaranteed, + * but it is observed to be true for OpenJDK 1.7. It also can't be guaranteed that the method + * isn't inadvertently oversizing the returned map. + * + * @param expectedSize the number of entries you expect to add to the returned map + * @return a new, empty {@code HashMap} with enough capacity to hold {@code expectedSize} entries + * without resizing + * @throws IllegalArgumentException if {@code expectedSize} is negative + */ + public static HashMap newHashMapWithExpectedSize(int expectedSize) { + return new HashMap<>(capacity(expectedSize)); + } + + /** + * Returns a capacity that is sufficient to keep the map from being resized as long as it grows no + * larger than expectedSize and the load factor is ≥ its default (0.75). + */ + static int capacity(int expectedSize) { + if (expectedSize < 3) { + return expectedSize + 1; + } + if (expectedSize < IntUtils.MAX_POWER_OF_TWO) { + // This is the calculation used in JDK8 to resize when a putAll + // happens; it seems to be the most conservative calculation we + // can make. 0.75 is the default load factor. + return (int) ((float) expectedSize / 0.75F + 1.0F); + } + return Integer.MAX_VALUE; + } +} diff --git a/src/main/java/com/alibaba/excel/util/MemberUtils.java b/src/main/java/com/alibaba/excel/util/MemberUtils.java new file mode 100644 index 00000000..6bcfaac6 --- /dev/null +++ b/src/main/java/com/alibaba/excel/util/MemberUtils.java @@ -0,0 +1,54 @@ +package com.alibaba.excel.util; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Member; +import java.lang.reflect.Modifier; + +/** + * Member utils. + * + * @author Jiaju Zhuang + */ +public class MemberUtils { + + private static final int ACCESS_TEST = Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE; + + + /** + * XXX Default access superclass workaround. + * + * When a {@code public} class has a default access superclass with {@code public} members, + * these members are accessible. Calling them from compiled code works fine. + * Unfortunately, on some JVMs, using reflection to invoke these members + * seems to (wrongly) prevent access even when the modifier is {@code public}. + * Calling {@code setAccessible(true)} solves the problem but will only work from + * sufficiently privileged code. Better workarounds would be gratefully + * accepted. + * @param o the AccessibleObject to set as accessible + * @return a boolean indicating whether the accessibility of the object was set to true. + */ + static boolean setAccessibleWorkaround(final AccessibleObject o) { + if (o == null || o.isAccessible()) { + return false; + } + final Member m = (Member) o; + if (!o.isAccessible() && Modifier.isPublic(m.getModifiers()) && isPackageAccess(m.getDeclaringClass().getModifiers())) { + try { + o.setAccessible(true); + return true; + } catch (final SecurityException e) { // NOPMD + // ignore in favor of subsequent IllegalAccessException + } + } + return false; + } + + /** + * Returns whether a given set of modifiers implies package access. + * @param modifiers to test + * @return {@code true} unless {@code package}/{@code protected}/{@code private} modifier detected + */ + static boolean isPackageAccess(final int modifiers) { + return (modifiers & ACCESS_TEST) == 0; + } +} diff --git a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java index 09d149b6..de01ad54 100644 --- a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java +++ b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java @@ -24,7 +24,7 @@ public class NumberDataFormatterUtils { * @param globalConfiguration * @return */ - public static String format(Double data, Integer dataFormat, String dataFormatString, + public static String format(Double data, Short dataFormat, String dataFormatString, GlobalConfiguration globalConfiguration) { DataFormatter dataFormatter = DATA_FORMATTER_THREAD_LOCAL.get(); if (dataFormatter == null) { diff --git a/src/main/java/com/alibaba/excel/util/NumberUtils.java b/src/main/java/com/alibaba/excel/util/NumberUtils.java index 4257ff44..09a15bea 100644 --- a/src/main/java/com/alibaba/excel/util/NumberUtils.java +++ b/src/main/java/com/alibaba/excel/util/NumberUtils.java @@ -7,6 +7,7 @@ import java.text.ParseException; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.write.metadata.holder.WriteHolder; /** * Number utils @@ -46,8 +47,27 @@ public class NumberUtils { * @param contentProperty * @return */ - public static CellData formatToCellData(Number num, ExcelContentProperty contentProperty) { - return new CellData(format(num, contentProperty)); + public static CellData formatToCellDataString(Number num, ExcelContentProperty contentProperty) { + return new CellData<>(format(num, contentProperty)); + } + + /** + * format + * + * @param num + * @param contentProperty + * @param currentWriteHolder + * @return + */ + public static CellData formatToCellData(Number num, ExcelContentProperty contentProperty, + WriteHolder currentWriteHolder) { + CellData cellData = new CellData<>(BigDecimal.valueOf(num.doubleValue())); + if (contentProperty != null && contentProperty.getNumberFormatProperty() != null + && StringUtils.isNotBlank(contentProperty.getNumberFormatProperty().getFormat())) { + WorkBookUtil.fillDataFormat(cellData, currentWriteHolder, + contentProperty.getNumberFormatProperty().getFormat()); + } + return cellData; } /** diff --git a/src/main/java/com/alibaba/excel/util/StringUtils.java b/src/main/java/com/alibaba/excel/util/StringUtils.java index 948ae652..667233dc 100644 --- a/src/main/java/com/alibaba/excel/util/StringUtils.java +++ b/src/main/java/com/alibaba/excel/util/StringUtils.java @@ -6,11 +6,92 @@ package com.alibaba.excel.util; * @author jipengfei */ public class StringUtils { + private StringUtils() {} + + /** + * A String for a space character. + */ + public static final String SPACE = " "; + + /** + * The empty String {@code ""}. + */ public static final String EMPTY = ""; - private StringUtils() {} + /** + *

Checks if a CharSequence is empty ("") or null.

+ * + *
+     * StringUtils.isEmpty(null)      = true
+     * StringUtils.isEmpty("")        = true
+     * StringUtils.isEmpty(" ")       = false
+     * StringUtils.isEmpty("bob")     = false
+     * StringUtils.isEmpty("  bob  ") = false
+     * 
+ * + *

NOTE: This method changed in Lang version 2.0. + * It no longer trims the CharSequence. + * That functionality is available in isBlank().

+ * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is empty or null + */ + public static boolean isEmpty(final CharSequence cs) { + return cs == null || cs.length() == 0; + } - public static boolean isEmpty(Object str) { - return (str == null || EMPTY.equals(str)); + /** + *

Checks if a CharSequence is empty (""), null or whitespace only.

+ * + *

Whitespace is defined by {@link Character#isWhitespace(char)}.

+ * + *
+     * StringUtils.isBlank(null)      = true
+     * StringUtils.isBlank("")        = true
+     * StringUtils.isBlank(" ")       = true
+     * StringUtils.isBlank("bob")     = false
+     * StringUtils.isBlank("  bob  ") = false
+     * 
+ * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is null, empty or whitespace only + */ + public static boolean isBlank(final CharSequence cs) { + int strLen; + if (cs == null || (strLen = cs.length()) == 0) { + return true; + } + for (int i = 0; i < strLen; i++) { + if (!Character.isWhitespace(cs.charAt(i))) { + return false; + } + } + return true; } + + + /** + *

Checks if a CharSequence is not empty (""), not null and not whitespace only.

+ * + *

Whitespace is defined by {@link Character#isWhitespace(char)}.

+ * + *
+     * StringUtils.isNotBlank(null)      = false
+     * StringUtils.isNotBlank("")        = false
+     * StringUtils.isNotBlank(" ")       = false
+     * StringUtils.isNotBlank("bob")     = true
+     * StringUtils.isNotBlank("  bob  ") = true
+     * 
+ * + * @param cs the CharSequence to check, may be null + * @return {@code true} if the CharSequence is + * not empty and not null and not whitespace only + * @since 2.0 + * @since 3.0 Changed signature from isNotBlank(String) to isNotBlank(CharSequence) + */ + public static boolean isNotBlank(final CharSequence cs) { + return !isBlank(cs); + } + + } diff --git a/src/main/java/com/alibaba/excel/util/StyleUtil.java b/src/main/java/com/alibaba/excel/util/StyleUtil.java index d0e1bd32..0154f181 100644 --- a/src/main/java/com/alibaba/excel/util/StyleUtil.java +++ b/src/main/java/com/alibaba/excel/util/StyleUtil.java @@ -1,5 +1,8 @@ package com.alibaba.excel.util; +import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import com.alibaba.excel.write.metadata.style.WriteFont; + import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.FillPatternType; @@ -8,15 +11,17 @@ import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.usermodel.Workbook; - -import com.alibaba.excel.write.metadata.style.WriteCellStyle; -import com.alibaba.excel.write.metadata.style.WriteFont; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; /** * @author jipengfei */ public class StyleUtil { + public static short XSSF_DEFAULT_STYLE = 0; + public static short HSSF_DEFAULT_STYLE = 15; + private StyleUtil() {} /** @@ -183,4 +188,13 @@ public class StyleUtil { } } + public static boolean isDefaultStyle(CellStyle cellStyle) { + if (cellStyle == null) { + return true; + } + if (cellStyle instanceof XSSFCellStyle) { + return cellStyle.getIndex() == XSSF_DEFAULT_STYLE; + } + return cellStyle.getIndex() == HSSF_DEFAULT_STYLE; + } } diff --git a/src/main/java/com/alibaba/excel/util/Validate.java b/src/main/java/com/alibaba/excel/util/Validate.java new file mode 100644 index 00000000..6207bb1a --- /dev/null +++ b/src/main/java/com/alibaba/excel/util/Validate.java @@ -0,0 +1,151 @@ +package com.alibaba.excel.util; + +import java.util.Objects; + +/** + * Validate + * + * @author Jiaju Zhuang + */ +public class Validate { + + private static final String DEFAULT_IS_TRUE_EX_MESSAGE = "The validated expression is false"; + private static final String DEFAULT_IS_NULL_EX_MESSAGE = "The validated object is null"; + + /** + *

Validate that the argument condition is {@code true}; otherwise + * throwing an exception with the specified message. This method is useful when + * validating according to an arbitrary boolean expression, such as validating a + * primitive number or using your own custom validation expression.

+ * + *
Validate.isTrue(i > 0.0, "The value must be greater than zero: %d", i);
+ * + *

For performance reasons, the long value is passed as a separate parameter and + * appended to the exception message only in the case of an error.

+ * + * @param expression the boolean expression to check + * @param message the {@link String#format(String, Object...)} exception message if invalid, not null + * @param value the value to append to the message when invalid + * @throws IllegalArgumentException if expression is {@code false} + * @see #isTrue(boolean) + * @see #isTrue(boolean, String, double) + * @see #isTrue(boolean, String, Object...) + */ + public static void isTrue(final boolean expression, final String message, final long value) { + if (!expression) { + throw new IllegalArgumentException(String.format(message, Long.valueOf(value))); + } + } + + /** + *

Validate that the argument condition is {@code true}; otherwise + * throwing an exception with the specified message. This method is useful when + * validating according to an arbitrary boolean expression, such as validating a + * primitive number or using your own custom validation expression.

+ * + *
Validate.isTrue(d > 0.0, "The value must be greater than zero: %s", d);
+ * + *

For performance reasons, the double value is passed as a separate parameter and + * appended to the exception message only in the case of an error.

+ * + * @param expression the boolean expression to check + * @param message the {@link String#format(String, Object...)} exception message if invalid, not null + * @param value the value to append to the message when invalid + * @throws IllegalArgumentException if expression is {@code false} + * @see #isTrue(boolean) + * @see #isTrue(boolean, String, long) + * @see #isTrue(boolean, String, Object...) + */ + public static void isTrue(final boolean expression, final String message, final double value) { + if (!expression) { + throw new IllegalArgumentException(String.format(message, Double.valueOf(value))); + } + } + + /** + *

Validate that the argument condition is {@code true}; otherwise + * throwing an exception with the specified message. This method is useful when + * validating according to an arbitrary boolean expression, such as validating a + * primitive number or using your own custom validation expression.

+ * + *
+     * Validate.isTrue(i >= min && i <= max, "The value must be between %d and %d", min, max);
+     * Validate.isTrue(myObject.isOk(), "The object is not okay");
+ * + * @param expression the boolean expression to check + * @param message the {@link String#format(String, Object...)} exception message if invalid, not null + * @param values the optional values for the formatted exception message, null array not recommended + * @throws IllegalArgumentException if expression is {@code false} + * @see #isTrue(boolean) + * @see #isTrue(boolean, String, long) + * @see #isTrue(boolean, String, double) + */ + public static void isTrue(final boolean expression, final String message, final Object... values) { + if (!expression) { + throw new IllegalArgumentException(String.format(message, values)); + } + } + + /** + *

Validate that the argument condition is {@code true}; otherwise + * throwing an exception. This method is useful when validating according + * to an arbitrary boolean expression, such as validating a + * primitive number or using your own custom validation expression.

+ * + *
+     * Validate.isTrue(i > 0);
+     * Validate.isTrue(myObject.isOk());
+ * + *

The message of the exception is "The validated expression is + * false".

+ * + * @param expression the boolean expression to check + * @throws IllegalArgumentException if expression is {@code false} + * @see #isTrue(boolean, String, long) + * @see #isTrue(boolean, String, double) + * @see #isTrue(boolean, String, Object...) + */ + public static void isTrue(final boolean expression) { + if (!expression) { + throw new IllegalArgumentException(DEFAULT_IS_TRUE_EX_MESSAGE); + } + } + + + /** + *

Validate that the specified argument is not {@code null}; + * otherwise throwing an exception. + * + *

Validate.notNull(myObject, "The object must not be null");
+ * + *

The message of the exception is "The validated object is + * null".

+ * + * @param the object type + * @param object the object to check + * @return the validated object (never {@code null} for method chaining) + * @throws NullPointerException if the object is {@code null} + * @see #notNull(Object, String, Object...) + */ + public static T notNull(final T object) { + return notNull(object, DEFAULT_IS_NULL_EX_MESSAGE); + } + + /** + *

Validate that the specified argument is not {@code null}; + * otherwise throwing an exception with the specified message. + * + *

Validate.notNull(myObject, "The object must not be null");
+ * + * @param the object type + * @param object the object to check + * @param message the {@link String#format(String, Object...)} exception message if invalid, not null + * @param values the optional values for the formatted exception message + * @return the validated object (never {@code null} for method chaining) + * @throws NullPointerException if the object is {@code null} + * @see #notNull(Object) + */ + public static T notNull(final T object, final String message, final Object... values) { + return Objects.requireNonNull(object, () -> String.format(message, values)); + } +} diff --git a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java index 186708c9..0ee92209 100644 --- a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java +++ b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java @@ -2,6 +2,13 @@ package com.alibaba.excel.util; import java.io.IOException; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.write.metadata.holder.WriteHolder; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; + import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; @@ -13,16 +20,12 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; -import com.alibaba.excel.support.ExcelTypeEnum; -import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; - /** - * * @author jipengfei */ public class WorkBookUtil { - private static final int ROW_ACCESS_WINDOW_SIZE = 500; + public static final int ROW_ACCESS_WINDOW_SIZE = 500; private WorkBookUtil() {} @@ -91,4 +94,16 @@ public class WorkBookUtil { cell.setCellValue(cellValue); return cell; } + + public static void fillDataFormat(CellData cellData, WriteHolder currentWriteHolder, String format) { + WriteWorkbookHolder writeWorkbookHolder; + if (currentWriteHolder instanceof WriteSheetHolder) { + writeWorkbookHolder = ((WriteSheetHolder)currentWriteHolder).getParentWriteWorkbookHolder(); + } else { + writeWorkbookHolder = ((WriteTableHolder)currentWriteHolder).getParentWriteSheetHolder() + .getParentWriteWorkbookHolder(); + } + cellData.setDataFormat(writeWorkbookHolder.getDataFormat(format)); + cellData.setDataFormatString(format); + } } diff --git a/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java b/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java index 044e7b2e..0bd0a068 100644 --- a/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java +++ b/src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java @@ -4,9 +4,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; - import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; @@ -16,6 +13,9 @@ import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler; import com.alibaba.excel.write.handler.WriteHandler; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; + /** * Write handler utils * @@ -25,7 +25,6 @@ public class WriteHandlerUtils { private WriteHandlerUtils() {} - public static void beforeWorkbookCreate(WriteContext writeContext) { beforeWorkbookCreate(writeContext, false); } @@ -37,7 +36,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof WorkbookWriteHandler) { - ((WorkbookWriteHandler) writeHandler).beforeWorkbookCreate(); + ((WorkbookWriteHandler)writeHandler).beforeWorkbookCreate(); } } } @@ -53,7 +52,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof WorkbookWriteHandler) { - ((WorkbookWriteHandler) writeHandler).afterWorkbookCreate(writeContext.writeWorkbookHolder()); + ((WorkbookWriteHandler)writeHandler).afterWorkbookCreate(writeContext.writeWorkbookHolder()); } } } @@ -66,7 +65,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof WorkbookWriteHandler) { - ((WorkbookWriteHandler) writeHandler).afterWorkbookDispose(writeContext.writeWorkbookHolder()); + ((WorkbookWriteHandler)writeHandler).afterWorkbookDispose(writeContext.writeWorkbookHolder()); } } } @@ -82,13 +81,12 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof SheetWriteHandler) { - ((SheetWriteHandler) writeHandler).beforeSheetCreate(writeContext.writeWorkbookHolder(), + ((SheetWriteHandler)writeHandler).beforeSheetCreate(writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder()); } } } - public static void afterSheetCreate(WriteContext writeContext) { afterSheetCreate(writeContext, false); } @@ -100,7 +98,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof SheetWriteHandler) { - ((SheetWriteHandler) writeHandler).afterSheetCreate(writeContext.writeWorkbookHolder(), + ((SheetWriteHandler)writeHandler).afterSheetCreate(writeContext.writeWorkbookHolder(), writeContext.writeSheetHolder()); } } @@ -119,7 +117,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { - ((CellWriteHandler) writeHandler).beforeCellCreate(writeContext.writeSheetHolder(), + ((CellWriteHandler)writeHandler).beforeCellCreate(writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, head, columnIndex, relativeRowIndex, isHead); } } @@ -134,7 +132,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { - ((CellWriteHandler) writeHandler).afterCellCreate(writeContext.writeSheetHolder(), + ((CellWriteHandler)writeHandler).afterCellCreate(writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cell, head, relativeRowIndex, isHead); } } @@ -149,7 +147,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { - ((CellWriteHandler) writeHandler).afterCellDataConverted(writeContext.writeSheetHolder(), + ((CellWriteHandler)writeHandler).afterCellDataConverted(writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cellData, cell, head, relativeRowIndex, isHead); } } @@ -157,14 +155,14 @@ public class WriteHandlerUtils { public static void afterCellDispose(WriteContext writeContext, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { - List cellDataList = new ArrayList(); - if (cell != null) { + List> cellDataList = new ArrayList<>(); + if (cellData != null) { cellDataList.add(cellData); } afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead); } - public static void afterCellDispose(WriteContext writeContext, List cellDataList, Cell cell, Head head, + public static void afterCellDispose(WriteContext writeContext, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { List handlerList = writeContext.currentWriteHolder().writeHandlerMap().get(CellWriteHandler.class); @@ -173,7 +171,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof CellWriteHandler) { - ((CellWriteHandler) writeHandler).afterCellDispose(writeContext.writeSheetHolder(), + ((CellWriteHandler)writeHandler).afterCellDispose(writeContext.writeSheetHolder(), writeContext.writeTableHolder(), cellDataList, cell, head, relativeRowIndex, isHead); } } @@ -190,7 +188,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof RowWriteHandler) { - ((RowWriteHandler) writeHandler).beforeRowCreate(writeContext.writeSheetHolder(), + ((RowWriteHandler)writeHandler).beforeRowCreate(writeContext.writeSheetHolder(), writeContext.writeTableHolder(), rowIndex, relativeRowIndex, isHead); } } @@ -203,7 +201,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof RowWriteHandler) { - ((RowWriteHandler) writeHandler).afterRowCreate(writeContext.writeSheetHolder(), + ((RowWriteHandler)writeHandler).afterRowCreate(writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, relativeRowIndex, isHead); } } @@ -217,7 +215,7 @@ public class WriteHandlerUtils { } for (WriteHandler writeHandler : handlerList) { if (writeHandler instanceof RowWriteHandler) { - ((RowWriteHandler) writeHandler).afterRowDispose(writeContext.writeSheetHolder(), + ((RowWriteHandler)writeHandler).afterRowDispose(writeContext.writeSheetHolder(), writeContext.writeTableHolder(), row, relativeRowIndex, isHead); } } diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilder.java b/src/main/java/com/alibaba/excel/write/ExcelBuilder.java index d3a50e35..a9f7e601 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilder.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilder.java @@ -1,5 +1,6 @@ package com.alibaba.excel.write; +import java.util.Collection; import java.util.List; import com.alibaba.excel.context.WriteContext; @@ -20,10 +21,10 @@ public interface ExcelBuilder { * java basic type or java model extend BaseModel * @param writeSheet * Write the sheet - * @deprecated please use{@link ExcelBuilder#addContent(List, WriteSheet, WriteTable)} + * @deprecated please use{@link ExcelBuilder#addContent(Collection, WriteSheet, WriteTable)} */ @Deprecated - void addContent(List data, WriteSheet writeSheet); + void addContent(Collection data, WriteSheet writeSheet); /** * WorkBook increase value @@ -35,7 +36,7 @@ public interface ExcelBuilder { * @param writeTable * Write the table */ - void addContent(List data, WriteSheet writeSheet, WriteTable writeTable); + void addContent(Collection data, WriteSheet writeSheet, WriteTable writeTable); /** * WorkBook fill value diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java index 0c7158ed..e172140d 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -1,13 +1,19 @@ package com.alibaba.excel.write; +import java.lang.reflect.Field; +import java.util.Collection; import java.util.List; +import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFSheet; import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContextImpl; import com.alibaba.excel.enums.WriteTypeEnum; import com.alibaba.excel.exception.ExcelGenerateException; +import com.alibaba.excel.util.FieldUtils; import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.write.executor.ExcelWriteAddExecutor; import com.alibaba.excel.write.executor.ExcelWriteFillExecutor; @@ -43,12 +49,12 @@ public class ExcelBuilderImpl implements ExcelBuilder { } @Override - public void addContent(List data, WriteSheet writeSheet) { + public void addContent(Collection data, WriteSheet writeSheet) { addContent(data, writeSheet, null); } @Override - public void addContent(List data, WriteSheet writeSheet, WriteTable writeTable) { + public void addContent(Collection data, WriteSheet writeSheet, WriteTable writeTable) { try { context.currentSheet(writeSheet, WriteTypeEnum.ADD); context.currentTable(writeTable); diff --git a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java index f79b7710..0ec448e2 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java @@ -1,6 +1,6 @@ package com.alibaba.excel.write.builder; -import java.util.List; +import java.util.Collection; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.exception.ExcelGenerateException; @@ -54,7 +54,7 @@ public class ExcelWriterSheetBuilder extends AbstractExcelWriterParameterBuilder return writeSheet; } - public void doWrite(List data) { + public void doWrite(Collection data) { if (excelWriter == null) { throw new ExcelGenerateException("Must use 'EasyExcelFactory.write().sheet()' to call this method"); } diff --git a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java index 077361ad..b7a90be9 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java @@ -1,6 +1,6 @@ package com.alibaba.excel.write.builder; -import java.util.List; +import java.util.Collection; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.exception.ExcelGenerateException; @@ -47,7 +47,7 @@ public class ExcelWriterTableBuilder extends AbstractExcelWriterParameterBuilder return writeTable; } - public void doWrite(List data) { + public void doWrite(Collection data) { if (excelWriter == null) { throw new ExcelGenerateException("Must use 'EasyExcelFactory.write().sheet().table()' to call this method"); } diff --git a/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java b/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java index 9e7ade6c..d2606ec2 100644 --- a/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java @@ -1,12 +1,5 @@ package com.alibaba.excel.write.executor; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.ClientAnchor; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Sheet; - import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.ConverterKeyBuild; @@ -18,6 +11,13 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.write.metadata.holder.WriteHolder; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.Drawing; +import org.apache.poi.ss.usermodel.Sheet; + /** * Excel write Executor * @@ -30,12 +30,13 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { this.writeContext = writeContext; } - protected CellData converterAndSet(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, + protected CellData converterAndSet(WriteHolder currentWriteHolder, Class clazz, CellDataTypeEnum targetType, + Cell cell, Object value, ExcelContentProperty excelContentProperty, Head head, Integer relativeRowIndex) { if (value instanceof String && currentWriteHolder.globalConfiguration().getAutoTrim()) { value = ((String)value).trim(); } - CellData cellData = convert(currentWriteHolder, clazz, cell, value, excelContentProperty); + CellData cellData = convert(currentWriteHolder, clazz, targetType, cell, value, excelContentProperty); if (cellData.getFormula() != null && cellData.getFormula()) { cell.setCellFormula(cellData.getFormulaValue()); } @@ -53,6 +54,9 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { case NUMBER: cell.setCellValue(cellData.getNumberValue().doubleValue()); return cellData; + case DATE: + cell.setCellValue(cellData.getDateValue()); + return cellData; case IMAGE: setImageValue(cellData, cell); return cellData; @@ -61,15 +65,16 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { default: throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), cellData, excelContentProperty, "Not supported data:" + value + " return type:" + cell.getCellType() - + "at row:" + cell.getRow().getRowNum()); + + "at row:" + cell.getRow().getRowNum()); } } - protected CellData convert(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, - ExcelContentProperty excelContentProperty) { + protected CellData convert(WriteHolder currentWriteHolder, Class clazz, CellDataTypeEnum targetType, + Cell cell, + Object value, ExcelContentProperty excelContentProperty) { // This means that the user has defined the data. if (value instanceof CellData) { - CellData cellDataValue = (CellData)value; + CellData cellDataValue = (CellData)value; if (cellDataValue.getType() != null) { return cellDataValue; } else { @@ -78,8 +83,8 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { return cellDataValue; } } - CellData cellDataReturn = doConvert(currentWriteHolder, cellDataValue.getData().getClass(), cell, - cellDataValue.getData(), excelContentProperty); + CellData cellDataReturn = doConvert(currentWriteHolder, cellDataValue.getData().getClass(), targetType, + cell, cellDataValue.getData(), excelContentProperty); // The formula information is subject to user input if (cellDataValue.getFormula() != null) { cellDataReturn.setFormula(cellDataValue.getFormula()); @@ -87,44 +92,40 @@ public abstract class AbstractExcelWriteExecutor implements ExcelWriteExecutor { } return cellDataReturn; } - return doConvert(currentWriteHolder, clazz, cell, value, excelContentProperty); + return doConvert(currentWriteHolder, clazz, targetType, cell, value, excelContentProperty); } - private CellData doConvert(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, - ExcelContentProperty excelContentProperty) { + private CellData doConvert(WriteHolder currentWriteHolder, Class clazz, CellDataTypeEnum targetType, + Cell cell, Object value, ExcelContentProperty excelContentProperty) { Converter converter = null; if (excelContentProperty != null) { converter = excelContentProperty.getConverter(); } if (converter == null) { - if (value == null || clazz == null) { - return new CellData(CellDataTypeEnum.EMPTY); - } - converter = currentWriteHolder.converterMap().get(ConverterKeyBuild.buildKey(clazz)); + converter = currentWriteHolder.converterMap().get(ConverterKeyBuild.buildKey(clazz, targetType)); } if (converter == null) { throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), - new CellData(CellDataTypeEnum.EMPTY), excelContentProperty, + new CellData<>(CellDataTypeEnum.EMPTY), excelContentProperty, "Can not find 'Converter' support class " + clazz.getSimpleName() + "."); } - CellData cellData; + CellData cellData; try { - cellData = - converter.convertToExcelData(value, excelContentProperty, currentWriteHolder.globalConfiguration()); + cellData = converter.convertToExcelData(value, excelContentProperty, currentWriteHolder); } catch (Exception e) { throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), - new CellData(CellDataTypeEnum.EMPTY), excelContentProperty, + new CellData<>(CellDataTypeEnum.EMPTY), excelContentProperty, "Convert data:" + value + " error,at row:" + cell.getRow().getRowNum(), e); } if (cellData == null || cellData.getType() == null) { throw new ExcelDataConvertException(cell.getRow().getRowNum(), cell.getColumnIndex(), - new CellData(CellDataTypeEnum.EMPTY), excelContentProperty, + new CellData<>(CellDataTypeEnum.EMPTY), excelContentProperty, "Convert data:" + value + " return null,at row:" + cell.getRow().getRowNum()); } return cellData; } - private void setImageValue(CellData cellData, Cell cell) { + private void setImageValue(CellData cellData, Cell cell) { Sheet sheet = cell.getSheet(); int index = sheet.getWorkbook().addPicture(cellData.getImageValue(), HSSFWorkbook.PICTURE_TYPE_PNG); Drawing drawing = sheet.getDrawingPatriarch(); diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java index 9f229029..4d96e8c4 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java @@ -2,31 +2,32 @@ package com.alibaba.excel.write.executor; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; - import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.util.ClassUtils; -import com.alibaba.excel.util.CollectionUtils; +import com.alibaba.excel.util.FieldUtils; import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WriteHandlerUtils; -import com.alibaba.excel.write.metadata.WriteWorkbook; -import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder; +import com.alibaba.excel.write.metadata.CollectionRowData; +import com.alibaba.excel.write.metadata.MapRowData; +import com.alibaba.excel.write.metadata.RowData; import com.alibaba.excel.write.metadata.holder.WriteHolder; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import net.sf.cglib.beans.BeanMap; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; /** * Add the data into excel @@ -39,9 +40,9 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { super(writeContext); } - public void add(List data) { + public void add(Collection data) { if (CollectionUtils.isEmpty(data)) { - data = new ArrayList(); + data = new ArrayList<>(); } WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder(); int newRowIndex = writeSheetHolder.getNewRowIndexAndStartDoWrite(); @@ -49,11 +50,11 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { newRowIndex += writeContext.currentWriteHolder().relativeHeadRowIndex(); } // BeanMap is out of order,so use sortedAllFiledMap - Map sortedAllFiledMap = new TreeMap(); + Map sortedAllFiledMap = new TreeMap<>(); int relativeRowIndex = 0; for (Object oneRowData : data) { - int n = relativeRowIndex + newRowIndex; - addOneRowOfDataToExcel(oneRowData, n, relativeRowIndex, sortedAllFiledMap); + int lastRowIndex = relativeRowIndex + newRowIndex; + addOneRowOfDataToExcel(oneRowData, lastRowIndex, relativeRowIndex, sortedAllFiledMap); relativeRowIndex++; } } @@ -66,16 +67,19 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { WriteHandlerUtils.beforeRowCreate(writeContext, n, relativeRowIndex, Boolean.FALSE); Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), n); WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE); - if (oneRowData instanceof List) { - addBasicTypeToExcel((List) oneRowData, row, relativeRowIndex); + + if (oneRowData instanceof Collection) { + addBasicTypeToExcel(new CollectionRowData((Collection)oneRowData), row, relativeRowIndex); + } else if (oneRowData instanceof Map) { + addBasicTypeToExcel(new MapRowData((Map)oneRowData), row, relativeRowIndex); } else { addJavaObjectToExcel(oneRowData, row, relativeRowIndex, sortedAllFiledMap); } WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE); } - private void addBasicTypeToExcel(List oneRowData, Row row, int relativeRowIndex) { - if (CollectionUtils.isEmpty(oneRowData)) { + private void addBasicTypeToExcel(RowData oneRowData, Row row, int relativeRowIndex) { + if (oneRowData.isEmpty()) { return; } Map headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap(); @@ -102,14 +106,15 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { } } - private void doAddBasicTypeToExcel(List oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex, + private void doAddBasicTypeToExcel(RowData oneRowData, Head head, Row row, int relativeRowIndex, + int dataIndex, int cellIndex) { WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE); Cell cell = WorkBookUtil.createCell(row, cellIndex); WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); Object value = oneRowData.get(dataIndex); CellData cellData = converterAndSet(writeContext.currentWriteHolder(), value == null ? null : value.getClass(), - cell, value, null, head, relativeRowIndex); + null, cell, value, null, head, relativeRowIndex); WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); } @@ -127,7 +132,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { for (Map.Entry entry : contentPropertyMap.entrySet()) { cellIndex = entry.getKey(); ExcelContentProperty excelContentProperty = entry.getValue(); - String name = excelContentProperty.getField().getName(); + String name = FieldUtils.resolveCglibFieldName(excelContentProperty.getField()); if (!beanMap.containsKey(name)) { continue; } @@ -136,8 +141,9 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { Cell cell = WorkBookUtil.createCell(row, cellIndex); WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE); Object value = beanMap.get(name); - CellData cellData = converterAndSet(currentWriteHolder, excelContentProperty.getField().getType(), cell, - value, excelContentProperty, head, relativeRowIndex); + CellData cellData = converterAndSet(currentWriteHolder, excelContentProperty.getField().getType(), + null, + cell, value, excelContentProperty, head, relativeRowIndex); WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE); beanMapHandledSet.add(name); } @@ -161,7 +167,7 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor { WriteHandlerUtils.beforeCellCreate(writeContext, row, null, cellIndex, relativeRowIndex, Boolean.FALSE); Cell cell = WorkBookUtil.createCell(row, cellIndex); WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE); - CellData cellData = converterAndSet(currentWriteHolder, value == null ? null : value.getClass(), cell, + CellData cellData = converterAndSet(currentWriteHolder, value == null ? null : value.getClass(), null, cell, value, null, null, relativeRowIndex); WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE); } diff --git a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java index 5930a311..9a144534 100644 --- a/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java +++ b/src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java @@ -9,12 +9,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CellType; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; - import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.WriteDirectionEnum; @@ -22,7 +16,6 @@ import com.alibaba.excel.enums.WriteTemplateAnalysisCellTypeEnum; import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.property.ExcelContentProperty; -import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.WriteHandlerUtils; import com.alibaba.excel.write.metadata.fill.AnalysisCell; @@ -31,6 +24,12 @@ import com.alibaba.excel.write.metadata.fill.FillWrapper; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import net.sf.cglib.beans.BeanMap; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; /** * Fill the data into excel @@ -94,7 +93,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { Object realData; if (data instanceof FillWrapper) { - FillWrapper fillWrapper = (FillWrapper) data; + FillWrapper fillWrapper = (FillWrapper)data; currentDataPrefix = fillWrapper.getName(); realData = fillWrapper.getCollectionData(); } else { @@ -106,7 +105,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { // processing data if (realData instanceof Collection) { List analysisCellList = readTemplateData(templateCollectionAnalysisCache); - Collection collectionData = (Collection) realData; + Collection collectionData = (Collection)realData; if (CollectionUtils.isEmpty(collectionData)) { return; } @@ -179,9 +178,12 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { private void doFill(List analysisCellList, Object oneRowData, FillConfig fillConfig, Integer relativeRowIndex) { + if (CollectionUtils.isEmpty(analysisCellList)) { + return; + } Map dataMap; if (oneRowData instanceof Map) { - dataMap = (Map) oneRowData; + dataMap = (Map)oneRowData; } else { dataMap = BeanMap.create(oneRowData); } @@ -196,21 +198,21 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { continue; } Object value = dataMap.get(variable); - CellData cellData = converterAndSet(writeSheetHolder, value == null ? null : value.getClass(), cell, - value, fieldNameContentPropertyMap.get(variable), null, relativeRowIndex); + CellData cellData = converterAndSet(writeSheetHolder, value == null ? null : value.getClass(), null, + cell, value, fieldNameContentPropertyMap.get(variable), null, relativeRowIndex); WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE); } else { StringBuilder cellValueBuild = new StringBuilder(); int index = 0; - List cellDataList = new ArrayList(); + List> cellDataList = new ArrayList<>(); for (String variable : analysisCell.getVariableList()) { cellValueBuild.append(analysisCell.getPrepareDataList().get(index++)); if (!dataMap.containsKey(variable)) { continue; } Object value = dataMap.get(variable); - CellData cellData = convert(writeSheetHolder, value == null ? null : value.getClass(), cell, value, - fieldNameContentPropertyMap.get(variable)); + CellData cellData = convert(writeSheetHolder, value == null ? null : value.getClass(), + CellDataTypeEnum.STRING, cell, value, fieldNameContentPropertyMap.get(variable)); cellDataList.add(cellData); CellDataTypeEnum type = cellData.getType(); if (type != null) { @@ -291,7 +293,7 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { } Row row = createRowIfNecessary(sheet, cachedSheet, lastRowIndex, fillConfig, analysisCell, isOriginalCell); - Cell cell = createCellIfNecessary(row,lastColumnIndex); + Cell cell = createCellIfNecessary(row, lastColumnIndex); Map collectionFieldStyleMap = collectionFieldStyleCache.get(currentUniqueDataFlag); if (collectionFieldStyleMap == null) { @@ -333,7 +335,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { row = cachedSheet.createRow(lastRowIndex); } else { // The last row of the middle disk inside empty rows, resulting in cachedSheet can not get inside. - // Will throw Attempting to write a row[" + rownum + "] " + "in the range [0," + this._sh.getLastRowNum() + "] that is already written to disk. + // Will throw Attempting to write a row[" + rownum + "] " + "in the range [0," + this._sh + // .getLastRowNum() + "] that is already written to disk. try { row = sheet.createRow(lastRowIndex); } catch (IllegalArgumentException ignore) { @@ -412,7 +415,8 @@ public class ExcelWriteFillExecutor extends AbstractExcelWriteExecutor { int startIndex = 0; int length = value.length(); int lastPrepareDataIndex = 0; - out: while (startIndex < length) { + out: + while (startIndex < length) { int prefixIndex = value.indexOf(FILL_PREFIX, startIndex); if (prefixIndex < 0) { break out; diff --git a/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java index b649af7a..6b663ce9 100644 --- a/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java @@ -14,7 +14,9 @@ import com.alibaba.excel.write.metadata.holder.WriteTableHolder; * Abstract cell write handler * * @author Jiaju Zhuang + * @deprecated Please use it directly {@link CellWriteHandler} **/ +@Deprecated public abstract class AbstractCellWriteHandler implements CellWriteHandler { @Override @@ -37,7 +39,7 @@ public abstract class AbstractCellWriteHandler implements CellWriteHandler { @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { } } diff --git a/src/main/java/com/alibaba/excel/write/handler/AbstractRowWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/AbstractRowWriteHandler.java index d1e8c3a9..286d8757 100644 --- a/src/main/java/com/alibaba/excel/write/handler/AbstractRowWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/AbstractRowWriteHandler.java @@ -1,15 +1,17 @@ package com.alibaba.excel.write.handler; -import org.apache.poi.ss.usermodel.Row; - import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.Row; + /** * Abstract row write handler * * @author Jiaju Zhuang + * @deprecated Please use it directly {@link RowWriteHandler} **/ +@Deprecated public abstract class AbstractRowWriteHandler implements RowWriteHandler { @Override public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer rowIndex, diff --git a/src/main/java/com/alibaba/excel/write/handler/AbstractSheetWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/AbstractSheetWriteHandler.java index 76f4c846..d24f9010 100644 --- a/src/main/java/com/alibaba/excel/write/handler/AbstractSheetWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/AbstractSheetWriteHandler.java @@ -7,7 +7,9 @@ import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; * Abstract sheet write handler * * @author Jiaju Zhuang + * @deprecated Please use it directly {@link SheetWriteHandler} **/ +@Deprecated public abstract class AbstractSheetWriteHandler implements SheetWriteHandler { @Override public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { diff --git a/src/main/java/com/alibaba/excel/write/handler/AbstractWorkbookWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/AbstractWorkbookWriteHandler.java index baad3920..5bb2fc5f 100644 --- a/src/main/java/com/alibaba/excel/write/handler/AbstractWorkbookWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/AbstractWorkbookWriteHandler.java @@ -6,7 +6,9 @@ import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; * Abstract workbook write handler * * @author Jiaju Zhuang + * @deprecated Please use it directly {@link WorkbookWriteHandler} **/ +@Deprecated public abstract class AbstractWorkbookWriteHandler implements WorkbookWriteHandler { @Override diff --git a/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java index 8701d6a0..4c9e39ed 100644 --- a/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/CellWriteHandler.java @@ -2,14 +2,14 @@ package com.alibaba.excel.write.handler; import java.util.List; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; - import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; + /** * intercepts handle cell creation * @@ -21,72 +21,54 @@ public interface CellWriteHandler extends WriteHandler { * Called before create the cell * * @param writeSheetHolder - * @param writeTableHolder - * Nullable.It is null without using table writes. + * @param writeTableHolder Nullable.It is null without using table writes. * @param row - * @param head - * Nullable.It is null in the case of fill data and without head. + * @param head Nullable.It is null in the case of fill data and without head. * @param columnIndex - * @param relativeRowIndex - * Nullable.It is null in the case of fill data. - * @param isHead - * It will always be false when fill data. + * @param relativeRowIndex Nullable.It is null in the case of fill data. + * @param isHead It will always be false when fill data. */ - void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, - Integer columnIndex, Integer relativeRowIndex, Boolean isHead); + default void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {} /** * Called after the cell is created * * @param writeSheetHolder - * @param writeTableHolder - * Nullable.It is null without using table writes. + * @param writeTableHolder Nullable.It is null without using table writes. * @param cell - * @param head - * Nullable.It is null in the case of fill data and without head. - * @param relativeRowIndex - * Nullable.It is null in the case of fill data. - * @param isHead - * It will always be false when fill data. + * @param head Nullable.It is null in the case of fill data and without head. + * @param relativeRowIndex Nullable.It is null in the case of fill data. + * @param isHead It will always be false when fill data. */ - void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, - Integer relativeRowIndex, Boolean isHead); + default void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, + Head head, Integer relativeRowIndex, Boolean isHead) {} /** * Called after the cell data is converted * * @param writeSheetHolder - * @param writeTableHolder - * Nullable.It is null without using table writes. + * @param writeTableHolder Nullable.It is null without using table writes. * @param cell - * @param head - * Nullable.It is null in the case of fill data and without head. - * @param cellData - * Nullable.It is null in the case of add header. - * @param relativeRowIndex - * Nullable.It is null in the case of fill data. - * @param isHead - * It will always be false when fill data. + * @param head Nullable.It is null in the case of fill data and without head. + * @param cellData Nullable.It is null in the case of add header. + * @param relativeRowIndex Nullable.It is null in the case of fill data. + * @param isHead It will always be false when fill data. */ - void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, - Cell cell, Head head, Integer relativeRowIndex, Boolean isHead); + default void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {} /** * Called after all operations on the cell have been completed * * @param writeSheetHolder - * @param writeTableHolder - * Nullable.It is null without using table writes. + * @param writeTableHolder Nullable.It is null without using table writes. * @param cell - * @param head - * Nullable.It is null in the case of fill data and without head. - * @param cellDataList - * Nullable.It is null in the case of add header.There may be several when fill the data. - * @param relativeRowIndex - * Nullable.It is null in the case of fill data. - * @param isHead - * It will always be false when fill data. + * @param head Nullable.It is null in the case of fill data and without head. + * @param cellDataList Nullable.It is null in the case of add header.There may be several when fill the data. + * @param relativeRowIndex Nullable.It is null in the case of fill data. + * @param isHead It will always be false when fill data. */ - void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead); + default void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {} } diff --git a/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java b/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java index dff84d7a..16897076 100644 --- a/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java +++ b/src/main/java/com/alibaba/excel/write/handler/DefaultWriteHandlerLoader.java @@ -3,12 +3,15 @@ package com.alibaba.excel.write.handler; import java.util.ArrayList; import java.util.List; -import org.apache.poi.ss.usermodel.IndexedColors; - +import com.alibaba.excel.write.handler.impl.DefaultRowWriteHandler; +import com.alibaba.excel.write.handler.impl.DimensionWorkbookWriteHandler; +import com.alibaba.excel.write.handler.impl.FillDataFormatCellWriteHandler; import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import org.apache.poi.ss.usermodel.IndexedColors; + /** * Load default handler * @@ -16,13 +19,20 @@ import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; */ public class DefaultWriteHandlerLoader { + public static final List DEFAULT_WRITE_HANDLER_LIST = new ArrayList<>(); + + static { + DEFAULT_WRITE_HANDLER_LIST.add(new DimensionWorkbookWriteHandler()); + DEFAULT_WRITE_HANDLER_LIST.add(new DefaultRowWriteHandler()); + } + /** * Load default handler * * @return */ public static List loadDefaultHandler(Boolean useDefaultStyle) { - List handlerList = new ArrayList(); + List handlerList = new ArrayList<>(); if (useDefaultStyle) { WriteCellStyle headWriteCellStyle = new WriteCellStyle(); headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); @@ -31,8 +41,10 @@ public class DefaultWriteHandlerLoader { headWriteFont.setFontHeightInPoints((short)14); headWriteFont.setBold(true); headWriteCellStyle.setWriteFont(headWriteFont); - handlerList.add(new HorizontalCellStyleStrategy(headWriteCellStyle, new ArrayList())); + handlerList.add(new HorizontalCellStyleStrategy(headWriteCellStyle, new ArrayList<>())); } + handlerList.addAll(DEFAULT_WRITE_HANDLER_LIST); + handlerList.add(new FillDataFormatCellWriteHandler()); return handlerList; } diff --git a/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java index 29ac10b0..e12d98f6 100644 --- a/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/RowWriteHandler.java @@ -1,10 +1,10 @@ package com.alibaba.excel.write.handler; -import org.apache.poi.ss.usermodel.Row; - import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.Row; + /** * intercepts handle row creation * @@ -16,44 +16,35 @@ public interface RowWriteHandler extends WriteHandler { * Called before create the row * * @param writeSheetHolder - * @param writeTableHolder - * Nullable.It is null without using table writes. + * @param writeTableHolder Nullable.It is null without using table writes. * @param rowIndex - * @param relativeRowIndex - * Nullable.It is null in the case of fill data. - * @param isHead - * Nullable.It is null in the case of fill data. + * @param relativeRowIndex Nullable.It is null in the case of fill data. + * @param isHead Nullable.It is null in the case of fill data. */ - void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer rowIndex, - Integer relativeRowIndex, Boolean isHead); + default void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer rowIndex, + Integer relativeRowIndex, Boolean isHead) {} /** * Called after the row is created * * @param writeSheetHolder - * @param writeTableHolder - * Nullable.It is null without using table writes. + * @param writeTableHolder Nullable.It is null without using table writes. * @param row - * @param relativeRowIndex - * Nullable.It is null in the case of fill data. - * @param isHead - * Nullable.It is null in the case of fill data. + * @param relativeRowIndex Nullable.It is null in the case of fill data. + * @param isHead Nullable.It is null in the case of fill data. */ - void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, - Integer relativeRowIndex, Boolean isHead); + default void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Integer relativeRowIndex, Boolean isHead) {} /** * Called after all operations on the row have been completed.This method is not called when fill the data. * * @param writeSheetHolder - * @param writeTableHolder - * Nullable.It is null without using table writes. + * @param writeTableHolder Nullable.It is null without using table writes. * @param row - * @param relativeRowIndex - * Nullable.It is null in the case of fill data. - * @param isHead - * Nullable.It is null in the case of fill data. + * @param relativeRowIndex Nullable.It is null in the case of fill data. + * @param isHead Nullable.It is null in the case of fill data. */ - void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, - Integer relativeRowIndex, Boolean isHead); + default void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Integer relativeRowIndex, Boolean isHead) {} } diff --git a/src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java index b97e1d15..5490fd39 100644 --- a/src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/SheetWriteHandler.java @@ -16,7 +16,7 @@ public interface SheetWriteHandler extends WriteHandler { * @param writeWorkbookHolder * @param writeSheetHolder */ - void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder); + default void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {} /** * Called after the sheet is created @@ -24,5 +24,5 @@ public interface SheetWriteHandler extends WriteHandler { * @param writeWorkbookHolder * @param writeSheetHolder */ - void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder); + default void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {} } diff --git a/src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java index 8dba9646..c3b758f5 100644 --- a/src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java +++ b/src/main/java/com/alibaba/excel/write/handler/WorkbookWriteHandler.java @@ -12,19 +12,19 @@ public interface WorkbookWriteHandler extends WriteHandler { /** * Called before create the workbook */ - void beforeWorkbookCreate(); + default void beforeWorkbookCreate() {} /** * Called after the workbook is created * * @param writeWorkbookHolder */ - void afterWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder); + default void afterWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder) {} /** * Called after all operations on the workbook have been completed * * @param writeWorkbookHolder */ - void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder); + default void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) {} } diff --git a/src/main/java/com/alibaba/excel/write/handler/impl/DefaultRowWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/impl/DefaultRowWriteHandler.java new file mode 100644 index 00000000..36f5ed09 --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/handler/impl/DefaultRowWriteHandler.java @@ -0,0 +1,22 @@ +package com.alibaba.excel.write.handler.impl; + +import com.alibaba.excel.write.handler.RowWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; + +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.Row; + +/** + * Default row handler. + * + * @author Jiaju Zhuang + */ +@Slf4j +public class DefaultRowWriteHandler implements RowWriteHandler { + @Override + public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, + Integer relativeRowIndex, Boolean isHead) { + writeSheetHolder.setLastRowIndex(row.getRowNum()); + } +} diff --git a/src/main/java/com/alibaba/excel/write/handler/impl/DimensionWorkbookWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/impl/DimensionWorkbookWriteHandler.java new file mode 100644 index 00000000..6b444a47 --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/handler/impl/DimensionWorkbookWriteHandler.java @@ -0,0 +1,81 @@ +package com.alibaba.excel.write.handler.impl; + +import java.lang.reflect.Field; +import java.util.Map; + +import com.alibaba.excel.util.FieldUtils; +import com.alibaba.excel.write.handler.WorkbookWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.MapUtils; +import org.apache.poi.ss.util.CellReference; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; + +/** + * Handle the problem of unable to write dimension. + * + * https://github.com/alibaba/easyexcel/issues/1282 + * + * @author Jiaju Zhuang + */ +@Slf4j +public class DimensionWorkbookWriteHandler implements WorkbookWriteHandler { + + private static final String XSSF_SHEET_MEMBER_VARIABLE_NAME = "_sh"; + private static final Field XSSF_SHEET_FIELD = FieldUtils.getField(SXSSFSheet.class, XSSF_SHEET_MEMBER_VARIABLE_NAME, + true); + + @Override + public void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) { + if (writeWorkbookHolder == null || writeWorkbookHolder.getWorkbook() == null) { + return; + } + if (!(writeWorkbookHolder.getWorkbook() instanceof SXSSFWorkbook)) { + return; + } + + Map writeSheetHolderMap = writeWorkbookHolder.getHasBeenInitializedSheetIndexMap(); + if (MapUtils.isEmpty(writeSheetHolderMap)) { + return; + } + for (WriteSheetHolder writeSheetHolder : writeSheetHolderMap.values()) { + if (writeSheetHolder.getSheet() == null || !(writeSheetHolder.getSheet() instanceof SXSSFSheet)) { + continue; + } + SXSSFSheet sxssfSheet = ((SXSSFSheet)writeSheetHolder.getSheet()); + XSSFSheet xssfSheet; + try { + xssfSheet = (XSSFSheet)XSSF_SHEET_FIELD.get(sxssfSheet); + } catch (IllegalAccessException e) { + log.debug("Can not found _sh.", e); + continue; + } + if (xssfSheet == null) { + continue; + } + CTWorksheet ctWorksheet = xssfSheet.getCTWorksheet(); + if (ctWorksheet == null) { + continue; + } + int headSize = 0; + if (MapUtils.isNotEmpty(writeSheetHolder.getExcelWriteHeadProperty().getHeadMap())) { + headSize = writeSheetHolder.getExcelWriteHeadProperty().getHeadMap().size(); + if (headSize > 0) { + headSize--; + } + } + Integer lastRowIndex = writeSheetHolder.getLastRowIndex(); + if (lastRowIndex == null) { + lastRowIndex = 0; + } + + ctWorksheet.getDimension().setRef( + "A1:" + CellReference.convertNumToColString(headSize) + (lastRowIndex + 1)); + } + } +} diff --git a/src/main/java/com/alibaba/excel/write/handler/impl/FillDataFormatCellWriteHandler.java b/src/main/java/com/alibaba/excel/write/handler/impl/FillDataFormatCellWriteHandler.java new file mode 100644 index 00000000..a465546b --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/handler/impl/FillDataFormatCellWriteHandler.java @@ -0,0 +1,76 @@ +package com.alibaba.excel.write.handler.impl; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.alibaba.excel.constant.OrderConstant; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.event.Order; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.util.DateUtils; +import com.alibaba.excel.util.StyleUtil; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.DataFormat; +import org.apache.poi.ss.usermodel.Workbook; + +/** + * fill cell style. + * + * @author Jiaju Zhuang + */ +@Slf4j +public class FillDataFormatCellWriteHandler implements CellWriteHandler, Order { + + private final Set cellStyleSet = new HashSet<>(); + + private CellStyle defaultDateCellStyle; + + @Override + public int order() { + return OrderConstant.FILL_DATA_FORMAT; + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + if (CollectionUtils.isEmpty(cellDataList) || cellDataList.size() > 1) { + return; + } + CellData cellData = cellDataList.get(0); + CellStyle cellStyle = cell.getCellStyle(); + if (cellStyle == null || StyleUtil.isDefaultStyle(cellStyle)) { + if (cellData.getType() == CellDataTypeEnum.DATE) { + cell.setCellStyle(getDefaultDateCellStyle(writeSheetHolder)); + } + return; + } + if (cellStyleSet.contains(cellStyle)) { + return; + } + if (cellData.getDataFormat() != null && cellData.getDataFormat() >= 0) { + cellStyle.setDataFormat(cellData.getDataFormat()); + } + cellStyleSet.add(cellStyle); + } + + private CellStyle getDefaultDateCellStyle(WriteSheetHolder writeSheetHolder) { + if (defaultDateCellStyle != null) { + return defaultDateCellStyle; + } + Workbook workbook = writeSheetHolder.getParentWriteWorkbookHolder().getWorkbook(); + defaultDateCellStyle = workbook.createCellStyle(); + DataFormat dataFormat = workbook.createDataFormat(); + defaultDateCellStyle.setDataFormat(dataFormat.getFormat(DateUtils.defaultDateFormat)); + return defaultDateCellStyle; + } + +} diff --git a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java b/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java index 2a2b7b6d..7b3d4b2b 100644 --- a/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java +++ b/src/main/java/com/alibaba/excel/write/merge/AbstractMergeStrategy.java @@ -2,42 +2,25 @@ package com.alibaba.excel.write.merge; import java.util.List; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; - import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Sheet; + /** * Merge strategy * * @author Jiaju Zhuang */ public abstract class AbstractMergeStrategy implements CellWriteHandler { - @Override - public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, - Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { - - } - - @Override - public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, - Head head, Integer relativeRowIndex, Boolean isHead) {} - - @Override - public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, - WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, - Boolean isHead) { - - } @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { if (isHead) { return; } diff --git a/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java b/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java index 5796dde5..13ebe3cb 100644 --- a/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java +++ b/src/main/java/com/alibaba/excel/write/merge/LoopMergeStrategy.java @@ -5,6 +5,7 @@ import org.apache.poi.ss.util.CellRangeAddress; import com.alibaba.excel.metadata.property.LoopMergeProperty; import com.alibaba.excel.write.handler.AbstractRowWriteHandler; +import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; @@ -13,7 +14,7 @@ import com.alibaba.excel.write.metadata.holder.WriteTableHolder; * * @author Jiaju Zhuang */ -public class LoopMergeStrategy extends AbstractRowWriteHandler { +public class LoopMergeStrategy implements RowWriteHandler { /** * Each row */ diff --git a/src/main/java/com/alibaba/excel/write/merge/OnceAbsoluteMergeStrategy.java b/src/main/java/com/alibaba/excel/write/merge/OnceAbsoluteMergeStrategy.java index d85781e1..0fe3dd61 100644 --- a/src/main/java/com/alibaba/excel/write/merge/OnceAbsoluteMergeStrategy.java +++ b/src/main/java/com/alibaba/excel/write/merge/OnceAbsoluteMergeStrategy.java @@ -4,6 +4,7 @@ import org.apache.poi.ss.util.CellRangeAddress; import com.alibaba.excel.metadata.property.OnceAbsoluteMergeProperty; import com.alibaba.excel.write.handler.AbstractSheetWriteHandler; +import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; @@ -12,7 +13,7 @@ import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; * * @author Jiaju Zhuang */ -public class OnceAbsoluteMergeStrategy extends AbstractSheetWriteHandler { +public class OnceAbsoluteMergeStrategy implements SheetWriteHandler { /** * First row */ diff --git a/src/main/java/com/alibaba/excel/write/metadata/CollectionRowData.java b/src/main/java/com/alibaba/excel/write/metadata/CollectionRowData.java new file mode 100644 index 00000000..bf98f5c5 --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/metadata/CollectionRowData.java @@ -0,0 +1,32 @@ +package com.alibaba.excel.write.metadata; + +import java.util.Collection; + +/** + * A collection row of data. + * + * @author Jiaju Zhuang + */ +public class CollectionRowData implements RowData { + + private final Object[] array; + + public CollectionRowData(Collection collection) { + this.array = collection.toArray(); + } + + @Override + public Object get(int index) { + return array[index]; + } + + @Override + public int size() { + return array.length; + } + + @Override + public boolean isEmpty() { + return array.length == 0; + } +} diff --git a/src/main/java/com/alibaba/excel/write/metadata/MapRowData.java b/src/main/java/com/alibaba/excel/write/metadata/MapRowData.java new file mode 100644 index 00000000..409fc58d --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/metadata/MapRowData.java @@ -0,0 +1,33 @@ +package com.alibaba.excel.write.metadata; + +import java.util.Map; + +/** + * A map row of data. + * + * @author Jiaju Zhuang + */ +public class MapRowData implements RowData { + + private final Map map; + + public MapRowData(Map map) { + this.map = map; + } + + @Override + public Object get(int index) { + return map.get(index); + } + + @Override + public int size() { + return map.size(); + } + + @Override + public boolean isEmpty() { + return map.isEmpty(); + } + +} diff --git a/src/main/java/com/alibaba/excel/write/metadata/RowData.java b/src/main/java/com/alibaba/excel/write/metadata/RowData.java new file mode 100644 index 00000000..937395b9 --- /dev/null +++ b/src/main/java/com/alibaba/excel/write/metadata/RowData.java @@ -0,0 +1,31 @@ +package com.alibaba.excel.write.metadata; + +/** + * A row of data. + * + * @author Jiaju Zhuang + */ +public interface RowData { + /** + * Returns the value to which the specified key is mapped, + * or {@code null} if this map contains no mapping for the key. + */ + Object get(int index); + + /** + * Returns the number of elements in this collection. If this collection + * contains more than Integer.MAX_VALUE elements, returns + * Integer.MAX_VALUE. + * + * @return the number of elements in this collection + */ + int size(); + + /** + * Returns true if this collection contains no elements. + * + * @return true if this collection contains no elements + */ + boolean isEmpty(); + +} diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java index 0fced0b5..59a9909f 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/AbstractWriteHolder.java @@ -9,6 +9,7 @@ import java.util.Map; import java.util.Set; import java.util.TreeMap; +import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.IndexedColors; @@ -25,7 +26,6 @@ import com.alibaba.excel.metadata.TableStyle; import com.alibaba.excel.metadata.property.LoopMergeProperty; import com.alibaba.excel.metadata.property.OnceAbsoluteMergeProperty; import com.alibaba.excel.metadata.property.RowHeightProperty; -import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.DefaultWriteHandlerLoader; import com.alibaba.excel.write.handler.RowWriteHandler; @@ -207,7 +207,7 @@ public abstract class AbstractWriteHolder extends AbstractHolder implements Writ if (parentAbstractWriteHolder == null) { setConverterMap(DefaultConverterLoader.loadDefaultWriteConverter()); } else { - setConverterMap(new HashMap(parentAbstractWriteHolder.getConverterMap())); + setConverterMap(new HashMap<>(parentAbstractWriteHolder.getConverterMap())); } if (writeBasicParameter.getCustomConverterList() != null && !writeBasicParameter.getCustomConverterList().isEmpty()) { diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java index 56fc7e4e..afae52b8 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteSheetHolder.java @@ -3,21 +3,25 @@ package com.alibaba.excel.write.metadata.holder; import java.util.HashMap; import java.util.Map; -import org.apache.poi.hssf.usermodel.HSSFSheet; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.streaming.SXSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFSheet; - import com.alibaba.excel.enums.HolderEnum; import com.alibaba.excel.enums.WriteLastRowTypeEnum; import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.write.metadata.WriteSheet; +import lombok.Getter; +import lombok.Setter; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFSheet; + /** * sheet holder * * @author Jiaju Zhuang */ +@Getter +@Setter public class WriteSheetHolder extends AbstractWriteHolder { /** * current param @@ -65,6 +69,11 @@ public class WriteSheetHolder extends AbstractWriteHolder { */ private WriteLastRowTypeEnum writeLastRowTypeEnum; + /** + * last row index + */ + private Integer lastRowIndex; + public WriteSheetHolder(WriteSheet writeSheet, WriteWorkbookHolder writeWorkbookHolder) { super(writeSheet, writeWorkbookHolder, writeWorkbookHolder.getWriteWorkbook().getConvertAllFiled()); this.writeSheet = writeSheet; @@ -75,76 +84,13 @@ public class WriteSheetHolder extends AbstractWriteHolder { } this.sheetName = writeSheet.getSheetName(); this.parentWriteWorkbookHolder = writeWorkbookHolder; - this.hasBeenInitializedTable = new HashMap(); + this.hasBeenInitializedTable = new HashMap<>(); if (writeWorkbookHolder.getTempTemplateInputStream() != null) { writeLastRowTypeEnum = WriteLastRowTypeEnum.TEMPLATE_EMPTY; } else { writeLastRowTypeEnum = WriteLastRowTypeEnum.COMMON_EMPTY; } - } - - public WriteSheet getWriteSheet() { - return writeSheet; - } - - public void setWriteSheet(WriteSheet writeSheet) { - this.writeSheet = writeSheet; - } - - public Sheet getSheet() { - return sheet; - } - - public void setSheet(Sheet sheet) { - this.sheet = sheet; - } - - public Integer getSheetNo() { - return sheetNo; - } - - public Sheet getCachedSheet() { - return cachedSheet; - } - - public void setCachedSheet(Sheet cachedSheet) { - this.cachedSheet = cachedSheet; - } - - public void setSheetNo(Integer sheetNo) { - this.sheetNo = sheetNo; - } - - public String getSheetName() { - return sheetName; - } - - public void setSheetName(String sheetName) { - this.sheetName = sheetName; - } - - public WriteWorkbookHolder getParentWriteWorkbookHolder() { - return parentWriteWorkbookHolder; - } - - public void setParentWriteWorkbookHolder(WriteWorkbookHolder parentWriteWorkbookHolder) { - this.parentWriteWorkbookHolder = parentWriteWorkbookHolder; - } - - public Map getHasBeenInitializedTable() { - return hasBeenInitializedTable; - } - - public void setHasBeenInitializedTable(Map hasBeenInitializedTable) { - this.hasBeenInitializedTable = hasBeenInitializedTable; - } - - public WriteLastRowTypeEnum getWriteLastRowTypeEnum() { - return writeLastRowTypeEnum; - } - - public void setWriteLastRowTypeEnum(WriteLastRowTypeEnum writeLastRowTypeEnum) { - this.writeLastRowTypeEnum = writeLastRowTypeEnum; + lastRowIndex = 0; } /** diff --git a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java index 8c84f1dc..19e4622b 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java @@ -10,23 +10,31 @@ import java.io.OutputStream; import java.util.HashMap; import java.util.Map; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; - +import com.alibaba.excel.constant.BuiltinFormats; import com.alibaba.excel.enums.HolderEnum; import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.util.FileUtils; import com.alibaba.excel.util.IoUtils; +import com.alibaba.excel.util.MapUtils; +import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.write.metadata.WriteWorkbook; +import lombok.Getter; +import lombok.Setter; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.DataFormat; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + /** * Workbook holder * * @author Jiaju Zhuang */ +@Getter +@Setter public class WriteWorkbookHolder extends AbstractWriteHolder { /*** * Current poi Workbook.This is only for writing, and there may be no data in version 07 when template data needs to @@ -111,7 +119,10 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { * Excel is also written in the event of an exception being thrown.The default false. */ private Boolean writeExcelOnException; - + /** + * Used to cache data Format. + */ + private Map dataFormatCache; public WriteWorkbookHolder(WriteWorkbook writeWorkbook) { super(writeWorkbook, null, writeWorkbook.getConvertAllFiled()); @@ -139,7 +150,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { if (writeWorkbook.getExcelType() == null) { boolean isXls = (file != null && file.getName().endsWith(ExcelTypeEnum.XLS.getValue())) || (writeWorkbook.getTemplateFile() != null - && writeWorkbook.getTemplateFile().getName().endsWith(ExcelTypeEnum.XLS.getValue())); + && writeWorkbook.getTemplateFile().getName().endsWith(ExcelTypeEnum.XLS.getValue())); if (isXls) { this.excelType = ExcelTypeEnum.XLS; } else { @@ -166,6 +177,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { } else { this.writeExcelOnException = writeWorkbook.getWriteExcelOnException(); } + this.dataFormatCache = MapUtils.newHashMap(); } private void copyTemplate() throws IOException { @@ -187,136 +199,29 @@ public class WriteWorkbookHolder extends AbstractWriteHolder { this.tempTemplateInputStream = new ByteArrayInputStream(templateFileByte); } - public Workbook getWorkbook() { - return workbook; - } - - public void setWorkbook(Workbook workbook) { - this.workbook = workbook; - } - - public Workbook getCachedWorkbook() { - return cachedWorkbook; - } - - public void setCachedWorkbook(Workbook cachedWorkbook) { - this.cachedWorkbook = cachedWorkbook; - } - - public Map getHasBeenInitializedSheetIndexMap() { - return hasBeenInitializedSheetIndexMap; - } - - public void setHasBeenInitializedSheetIndexMap(Map hasBeenInitializedSheetIndexMap) { - this.hasBeenInitializedSheetIndexMap = hasBeenInitializedSheetIndexMap; - } - - public Map getHasBeenInitializedSheetNameMap() { - return hasBeenInitializedSheetNameMap; - } - - public void setHasBeenInitializedSheetNameMap(Map hasBeenInitializedSheetNameMap) { - this.hasBeenInitializedSheetNameMap = hasBeenInitializedSheetNameMap; - } - - public WriteWorkbook getWriteWorkbook() { - return writeWorkbook; - } - - public void setWriteWorkbook(WriteWorkbook writeWorkbook) { - this.writeWorkbook = writeWorkbook; - } - - public File getFile() { - return file; - } - - public void setFile(File file) { - this.file = file; - } - - public OutputStream getOutputStream() { - return outputStream; - } - - public void setOutputStream(OutputStream outputStream) { - this.outputStream = outputStream; - } - - public InputStream getTemplateInputStream() { - return templateInputStream; - } - - public void setTemplateInputStream(InputStream templateInputStream) { - this.templateInputStream = templateInputStream; - } - - public InputStream getTempTemplateInputStream() { - return tempTemplateInputStream; - } - - public void setTempTemplateInputStream(InputStream tempTemplateInputStream) { - this.tempTemplateInputStream = tempTemplateInputStream; - } - - public File getTemplateFile() { - return templateFile; - } - - public void setTemplateFile(File templateFile) { - this.templateFile = templateFile; - } - - public Boolean getAutoCloseStream() { - return autoCloseStream; - } - - public void setAutoCloseStream(Boolean autoCloseStream) { - this.autoCloseStream = autoCloseStream; - } - - public ExcelTypeEnum getExcelType() { - return excelType; - } - - public void setExcelType(ExcelTypeEnum excelType) { - this.excelType = excelType; - } - - public Boolean getMandatoryUseInputStream() { - return mandatoryUseInputStream; - } - - public void setMandatoryUseInputStream(Boolean mandatoryUseInputStream) { - this.mandatoryUseInputStream = mandatoryUseInputStream; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public Boolean getInMemory() { - return inMemory; - } - - public void setInMemory(Boolean inMemory) { - this.inMemory = inMemory; - } - - public Boolean getWriteExcelOnException() { - return writeExcelOnException; - } - - public void setWriteExcelOnException(Boolean writeExcelOnException) { - this.writeExcelOnException = writeExcelOnException; - } - @Override public HolderEnum holderType() { return HolderEnum.WORKBOOK; } + + /** + * Get a data format. + * + * @param format + * @return + */ + public Short getDataFormat(String format) { + if (StringUtils.isEmpty(format)) { + return BuiltinFormats.GENERAL; + } + Short dataFormat = dataFormatCache.get(format); + if (dataFormat != null) { + return dataFormat; + } + DataFormat dataFormatCreate = workbook.createDataFormat(); + dataFormat = dataFormatCreate.getFormat(format); + dataFormatCache.put(format,dataFormat); + return dataFormat; + } + } diff --git a/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java b/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java index 979a7750..26af5512 100644 --- a/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java +++ b/src/main/java/com/alibaba/excel/write/property/ExcelWriteHeadProperty.java @@ -102,14 +102,6 @@ public class ExcelWriteHeadProperty extends ExcelHeadProperty { headData.setContentFontProperty(FontProperty.build(contentFontStyle)); headData.setLoopMergeProperty(LoopMergeProperty.build(field.getAnnotation(ContentLoopMerge.class))); - // If have @NumberFormat, 'NumberStringConverter' is specified by default - if (excelContentPropertyData.getConverter() == null) { - NumberFormat numberFormat = field.getAnnotation(NumberFormat.class); - if (numberFormat != null) { - excelContentPropertyData.setConverter(DefaultConverterLoader.loadAllConverter() - .get(ConverterKeyBuild.buildKey(field.getType(), CellDataTypeEnum.STRING))); - } - } } } diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java index 14ad9ce5..f131c456 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/AbstractCellStyleStrategy.java @@ -2,20 +2,18 @@ package com.alibaba.excel.write.style; import java.util.List; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Workbook; - import com.alibaba.excel.event.NotRepeatExecutor; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.handler.CellWriteHandler; -import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.WorkbookWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Workbook; + /** * Cell style strategy * @@ -30,53 +28,25 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, Wor return "CellStyleStrategy"; } - @Override - public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, - Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { - - } - - @Override - public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, - Head head, Integer relativeRowIndex, Boolean isHead) { - - } - - @Override - public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { - - } - @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { if (isHead == null) { return; } if (isHead) { - setHeadCellStyle(cell, head, relativeRowIndex); + setHeadCellStyle(writeSheetHolder, writeTableHolder, cell, head, relativeRowIndex); } else { - setContentCellStyle(cell, head, relativeRowIndex); + setContentCellStyle(writeSheetHolder, writeTableHolder, cell, head, relativeRowIndex); } } - @Override - public void beforeWorkbookCreate() { - - } - @Override public void afterWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder) { initCellStyle(writeWorkbookHolder.getWorkbook()); hasInitialized = true; } - @Override - public void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) { - - } - /** * Initialization cell style * @@ -87,11 +57,27 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, Wor /** * Sets the cell style of header * + * @param writeSheetHolder + * @param writeTableHolder * @param cell * @param head * @param relativeRowIndex */ - protected abstract void setHeadCellStyle(Cell cell, Head head, Integer relativeRowIndex); + protected void setHeadCellStyle(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + Cell cell, Head head, Integer relativeRowIndex) { + setHeadCellStyle(cell, head, relativeRowIndex); + } + + /** + * Sets the cell style of header + * + * @param cell + * @param head + * @param relativeRowIndex + */ + protected void setHeadCellStyle(Cell cell, Head head, Integer relativeRowIndex) { + throw new UnsupportedOperationException("Custom styles must override the setHeadCellStyle method."); + } /** * Sets the cell style of content @@ -100,6 +86,20 @@ public abstract class AbstractCellStyleStrategy implements CellWriteHandler, Wor * @param head * @param relativeRowIndex */ - protected abstract void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex); + protected void setContentCellStyle(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + Cell cell, Head head, Integer relativeRowIndex) { + setContentCellStyle(cell, head, relativeRowIndex); + } + + /** + * Sets the cell style of content + * + * @param cell + * @param head + * @param relativeRowIndex + */ + protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { + throw new UnsupportedOperationException("Custom styles must override the setContentCellStyle method."); + } } diff --git a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java index 197c5cf8..4ae5ac6a 100644 --- a/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/AbstractVerticalCellStyleStrategy.java @@ -1,16 +1,18 @@ package com.alibaba.excel.write.style; -import java.util.HashMap; import java.util.Map; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Workbook; - import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.util.MapUtils; import com.alibaba.excel.util.StyleUtil; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Workbook; + /** * Use the same style for the column * @@ -19,8 +21,8 @@ import com.alibaba.excel.write.metadata.style.WriteCellStyle; public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyleStrategy { private Workbook workbook; - private Map headCellStyleCache = new HashMap(); - private Map contentCellStyleCache = new HashMap(); + private final Map>> headCellStyleCache = MapUtils.newHashMap(); + private final Map>> contentCellStyleCache = MapUtils.newHashMap(); @Override protected void initCellStyle(Workbook workbook) { @@ -28,13 +30,16 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl } @Override - protected void setHeadCellStyle(Cell cell, Head head, Integer relativeRowIndex) { + protected void setHeadCellStyle(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, + Head head, Integer relativeRowIndex) { if (head == null) { return; } + Map styleMap = getStyleMap(headCellStyleCache, writeSheetHolder, writeTableHolder); + int columnIndex = head.getColumnIndex(); - if (headCellStyleCache.containsKey(columnIndex)) { - CellStyle cellStyle = headCellStyleCache.get(columnIndex); + if (styleMap.containsKey(columnIndex)) { + CellStyle cellStyle = styleMap.get(columnIndex); if (cellStyle != null) { cell.setCellStyle(cellStyle); } @@ -42,37 +47,52 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl } WriteCellStyle headCellStyle = headCellStyle(head); if (headCellStyle == null) { - headCellStyleCache.put(columnIndex, null); + styleMap.put(columnIndex, StyleUtil.buildHeadCellStyle(workbook, null)); } else { CellStyle cellStyle = StyleUtil.buildHeadCellStyle(workbook, headCellStyle); - headCellStyleCache.put(columnIndex, cellStyle); + styleMap.put(columnIndex, cellStyle); cell.setCellStyle(cellStyle); } } @Override - protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { + protected void setContentCellStyle(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, + Head head, Integer relativeRowIndex) { if (head == null) { return; } + Map styleMap = getStyleMap(contentCellStyleCache, writeSheetHolder, writeTableHolder); + int columnIndex = head.getColumnIndex(); - if (contentCellStyleCache.containsKey(columnIndex)) { - CellStyle cellStyle = contentCellStyleCache.get(columnIndex); + if (styleMap.containsKey(columnIndex)) { + CellStyle cellStyle = styleMap.get(columnIndex); if (cellStyle != null) { cell.setCellStyle(cellStyle); } return; } - WriteCellStyle contentCellStyle = contentCellStyle(head); + WriteCellStyle contentCellStyle = contentCellStyle(cell, head, relativeRowIndex); if (contentCellStyle == null) { - contentCellStyleCache.put(columnIndex, null); + styleMap.put(columnIndex, StyleUtil.buildContentCellStyle(workbook, null)); } else { CellStyle cellStyle = StyleUtil.buildContentCellStyle(workbook, contentCellStyle); - contentCellStyleCache.put(columnIndex, cellStyle); + styleMap.put(columnIndex, cellStyle); cell.setCellStyle(cellStyle); } } + /** + * Returns the column width corresponding to each column head. + * + * @param cell + * @param head + * @param relativeRowIndex + * @return + */ + protected WriteCellStyle contentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { + return contentCellStyle(head); + } + /** * Returns the column width corresponding to each column head * @@ -87,6 +107,21 @@ public abstract class AbstractVerticalCellStyleStrategy extends AbstractCellStyl * @param head Nullable * @return */ - protected abstract WriteCellStyle contentCellStyle(Head head); + protected WriteCellStyle contentCellStyle(Head head) { + throw new UnsupportedOperationException( + "One of the two methods 'contentCellStyle(Cell cell, Head head, Integer relativeRowIndex)' and " + + "'contentCellStyle(Head head)' must be implemented."); + } + + private Map getStyleMap(Map>> cellStyleCache, + WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder) { + Map> tableStyleMap = cellStyleCache.computeIfAbsent( + writeSheetHolder.getSheetNo(), key -> MapUtils.newHashMap()); + Integer tableNo = 0; + if (writeTableHolder != null) { + tableNo = writeTableHolder.getTableNo(); + } + return tableStyleMap.computeIfAbsent(tableNo, key -> MapUtils.newHashMap()); + } } diff --git a/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java index 295cd556..c8914f55 100644 --- a/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/HorizontalCellStyleStrategy.java @@ -1,29 +1,23 @@ package com.alibaba.excel.write.style; -import java.util.ArrayList; import java.util.List; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.Workbook; - import com.alibaba.excel.metadata.Head; -import com.alibaba.excel.util.StyleUtil; +import com.alibaba.excel.util.ListUtils; import com.alibaba.excel.write.metadata.style.WriteCellStyle; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.ss.usermodel.Cell; + /** - * * Use the same style for the row * * @author Jiaju Zhuang */ -public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy { - - private WriteCellStyle headWriteCellStyle; - private List contentWriteCellStyleList; +public class HorizontalCellStyleStrategy extends AbstractVerticalCellStyleStrategy { - private CellStyle headCellStyle; - private List contentCellStyleList; + private final WriteCellStyle headWriteCellStyle; + private final List contentWriteCellStyleList; public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, List contentWriteCellStyleList) { @@ -33,37 +27,21 @@ public class HorizontalCellStyleStrategy extends AbstractCellStyleStrategy { public HorizontalCellStyleStrategy(WriteCellStyle headWriteCellStyle, WriteCellStyle contentWriteCellStyle) { this.headWriteCellStyle = headWriteCellStyle; - contentWriteCellStyleList = new ArrayList(); + contentWriteCellStyleList = ListUtils.newArrayList(); contentWriteCellStyleList.add(contentWriteCellStyle); } @Override - protected void initCellStyle(Workbook workbook) { - if (headWriteCellStyle != null) { - headCellStyle = StyleUtil.buildHeadCellStyle(workbook, headWriteCellStyle); - } - if (contentWriteCellStyleList != null && !contentWriteCellStyleList.isEmpty()) { - contentCellStyleList = new ArrayList(); - for (WriteCellStyle writeCellStyle : contentWriteCellStyleList) { - contentCellStyleList.add(StyleUtil.buildContentCellStyle(workbook, writeCellStyle)); - } - } - } - - @Override - protected void setHeadCellStyle(Cell cell, Head head, Integer relativeRowIndex) { - if (headCellStyle == null) { - return; - } - cell.setCellStyle(headCellStyle); + protected WriteCellStyle headCellStyle(Head head) { + return headWriteCellStyle; } @Override - protected void setContentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { - if (contentCellStyleList == null || contentCellStyleList.isEmpty()) { - return; + protected WriteCellStyle contentCellStyle(Cell cell, Head head, Integer relativeRowIndex) { + if (CollectionUtils.isEmpty(contentWriteCellStyleList)) { + return new WriteCellStyle(); } - cell.setCellStyle(contentCellStyleList.get(relativeRowIndex % contentCellStyleList.size())); + return contentWriteCellStyleList.get(relativeRowIndex % contentWriteCellStyleList.size()); } } diff --git a/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java index 005f624e..277f96b9 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/AbstractColumnWidthStyleStrategy.java @@ -8,6 +8,7 @@ import com.alibaba.excel.event.NotRepeatExecutor; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.handler.AbstractCellWriteHandler; +import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; @@ -16,7 +17,7 @@ import com.alibaba.excel.write.metadata.holder.WriteTableHolder; * * @author Jiaju Zhuang */ -public abstract class AbstractColumnWidthStyleStrategy extends AbstractCellWriteHandler implements NotRepeatExecutor { +public abstract class AbstractColumnWidthStyleStrategy implements CellWriteHandler,NotRepeatExecutor { @Override public String uniqueValue() { @@ -25,7 +26,7 @@ public abstract class AbstractColumnWidthStyleStrategy extends AbstractCellWrite @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { setColumnWidth(writeSheetHolder, cellDataList, cell, head, relativeRowIndex, isHead); } @@ -39,7 +40,7 @@ public abstract class AbstractColumnWidthStyleStrategy extends AbstractCellWrite * @param relativeRowIndex * @param isHead */ - protected abstract void setColumnWidth(WriteSheetHolder writeSheetHolder, List cellDataList, Cell cell, + protected abstract void setColumnWidth(WriteSheetHolder writeSheetHolder, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead); } diff --git a/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java index 1a88eff6..d306d2e4 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/AbstractHeadColumnWidthStyleStrategy.java @@ -16,7 +16,7 @@ import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; public abstract class AbstractHeadColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy { @Override - protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List cellDataList, Cell cell, Head head, + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { boolean needSetWidth = relativeRowIndex != null && (isHead || relativeRowIndex == 0); if (!needSetWidth) { diff --git a/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java index cc8dcb20..c6cc9df1 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java @@ -4,12 +4,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.ss.usermodel.Cell; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; -import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; /** @@ -27,7 +27,7 @@ public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthSty private Map> cache = new HashMap>(8); @Override - protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List cellDataList, Cell cell, Head head, + protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList); if (!needSetWidth) { @@ -52,7 +52,7 @@ public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthSty } } - private Integer dataLength(List cellDataList, Cell cell, Boolean isHead) { + private Integer dataLength(List> cellDataList, Cell cell, Boolean isHead) { if (isHead) { return cell.getStringCellValue().getBytes().length; } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationData.java b/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationData.java index f1e91197..d1c2a4f7 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationData.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationData.java @@ -9,7 +9,6 @@ import com.alibaba.excel.annotation.format.NumberFormat; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.HeadRowHeight; -import com.alibaba.excel.converters.doubleconverter.DoubleStringConverter; import lombok.Data; @@ -24,7 +23,7 @@ public class AnnotationData { @ExcelProperty("日期") @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒") private Date date; - @ExcelProperty(value = "数字", converter = DoubleStringConverter.class) + @ExcelProperty(value = "数字") @NumberFormat("#.##%") private Double number; @ExcelIgnore diff --git a/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataData.java b/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataData.java index a4e624fb..ac928ec1 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataData.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataData.java @@ -17,5 +17,5 @@ public class CellDataData { private CellData date; private CellData integer1; private Integer integer2; - private CellData formulaValue; + private CellData formulaValue; } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataDataTest.java index 4615cdbc..ad8cbf13 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/celldata/CellDataDataTest.java @@ -55,7 +55,7 @@ public class CellDataDataTest { private List data() throws Exception { List list = new ArrayList(); CellDataData cellDataData = new CellDataData(); - cellDataData.setDate(new CellData(DateUtils.parseDate("2020-01-01 01:01:01"))); + cellDataData.setDate(new CellData<>(DateUtils.parseDate("2020-01-01 01:01:01"))); CellData integer1 = new CellData(); integer1.setType(CellDataTypeEnum.NUMBER); integer1.setNumberValue(BigDecimal.valueOf(2L)); diff --git a/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterData.java b/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterData.java index 88469470..fdff30e3 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterData.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterData.java @@ -34,5 +34,5 @@ public class ConverterData { @ExcelProperty("字符串") private String string; @ExcelProperty("自定义") - private CellData cellData; + private CellData cellData; } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java index c762db79..cf9c5d26 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/handler/WriteHandler.java @@ -98,7 +98,7 @@ public class WriteHandler implements WorkbookWriteHandler, SheetWriteHandler, Ro @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { if (isHead) { Assert.assertEquals(1L, beforeCellCreate); Assert.assertEquals(1L, afterCellCreate); diff --git a/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java new file mode 100644 index 00000000..1a0cf088 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/nomodel/NoModelDataTest.java @@ -0,0 +1,76 @@ +package com.alibaba.easyexcel.test.core.nomodel; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.util.DateUtils; + +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +/** + * @author Jiaju Zhuang + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class NoModelDataTest { + + private static File file07; + private static File file03; + private static File fileRepeat07; + private static File fileRepeat03; + + @BeforeClass + public static void init() { + file07 = TestFileUtil.createNewFile("noModel07.xlsx"); + file03 = TestFileUtil.createNewFile("noModel03.xls"); + fileRepeat07 = TestFileUtil.createNewFile("noModelRepeat07.xlsx"); + fileRepeat03 = TestFileUtil.createNewFile("noModelRepeat03.xls"); + } + + @Test + public void t01ReadAndWrite07() throws Exception { + readAndWrite(file07, fileRepeat07); + } + + @Test + public void t02ReadAndWrite03() throws Exception { + readAndWrite(file03, fileRepeat03); + } + + private void readAndWrite(File file, File fileRepeat) throws Exception { + EasyExcel.write(file).sheet().doWrite(data()); + List> result = EasyExcel.read(file).headRowNumber(0).sheet().doReadSync(); + Assert.assertEquals(10, result.size()); + Map data10 = result.get(9); + Assert.assertEquals("string19", data10.get(0)); + Assert.assertEquals("109", data10.get(1)); + Assert.assertEquals("2020-01-01 01:01:01", data10.get(2)); + + EasyExcel.write(fileRepeat).sheet().doWrite(result); + result = EasyExcel.read(fileRepeat).headRowNumber(0).sheet().doReadSync(); + Assert.assertEquals(10, result.size()); + data10 = result.get(9); + Assert.assertEquals("string19", data10.get(0)); + Assert.assertEquals("109", data10.get(1)); + Assert.assertEquals("2020-01-01 01:01:01", data10.get(2)); + } + + private List> data() throws Exception { + List> list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + List data = new ArrayList<>(); + data.add("string1" + i); + data.add(100 + i); + data.add(DateUtils.parseDate("2020-01-01 01:01:01")); + list.add(data); + } + return list; + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelData.java b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelData.java new file mode 100644 index 00000000..dd010fc7 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelData.java @@ -0,0 +1,16 @@ +package com.alibaba.easyexcel.test.core.noncamel; + +import lombok.Data; + +/** + * @author Jiaju Zhuang + */ +@Data +public class UnCamelData { + private String string1; + private String String2; + private String sTring3; + private String STring4; + private String STRING5; + private String STRing6; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java new file mode 100644 index 00000000..2f36d665 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataListener.java @@ -0,0 +1,49 @@ +package com.alibaba.easyexcel.test.core.noncamel; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.fastjson.JSON; + +import lombok.extern.slf4j.Slf4j; +import org.junit.Assert; + +/** + * @author Jiaju Zhuang + */ +@Slf4j +public class UnCamelDataListener extends AnalysisEventListener { + List list = new ArrayList<>(); + + @Override + public void invokeHeadMap(Map headMap, AnalysisContext context) { + log.debug("Head is:{}", JSON.toJSONString(headMap)); + Assert.assertEquals(headMap.get(0), "string1"); + Assert.assertEquals(headMap.get(1), "String2"); + Assert.assertEquals(headMap.get(2), "sTring3"); + Assert.assertEquals(headMap.get(3), "STring4"); + Assert.assertEquals(headMap.get(4), "STRING5"); + Assert.assertEquals(headMap.get(5), "STRing6"); + } + + @Override + public void invoke(UnCamelData data, AnalysisContext context) { + list.add(data); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + Assert.assertEquals(list.size(), 10); + UnCamelData unCamelData = list.get(0); + Assert.assertEquals(unCamelData.getString1(), "string1"); + Assert.assertEquals(unCamelData.getString2(), "string2"); + Assert.assertEquals(unCamelData.getSTring3(), "string3"); + Assert.assertEquals(unCamelData.getSTring4(), "string4"); + Assert.assertEquals(unCamelData.getSTRING5(), "string5"); + Assert.assertEquals(unCamelData.getSTRing6(), "string6"); + log.debug("First row:{}", JSON.toJSONString(list.get(0))); + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataTest.java new file mode 100644 index 00000000..689c9f8a --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/noncamel/UnCamelDataTest.java @@ -0,0 +1,59 @@ +package com.alibaba.easyexcel.test.core.noncamel; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; + +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +/** + * @author Jiaju Zhuang + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class UnCamelDataTest { + + private static File file07; + private static File file03; + + @BeforeClass + public static void init() { + file07 = TestFileUtil.createNewFile("unCame07.xlsx"); + file03 = TestFileUtil.createNewFile("unCame03.xls"); + } + + @Test + public void t01ReadAndWrite07() { + readAndWrite(file07); + } + + @Test + public void t02ReadAndWrite03() { + readAndWrite(file03); + } + + private void readAndWrite(File file) { + EasyExcel.write(file, UnCamelData.class).sheet().doWrite(data()); + EasyExcel.read(file, UnCamelData.class, new UnCamelDataListener()).sheet().doRead(); + } + + private List data() { + List list = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + UnCamelData unCamelData = new UnCamelData(); + unCamelData.setString1("string1"); + unCamelData.setString2("string2"); + unCamelData.setSTring3("string3"); + unCamelData.setSTring4("string4"); + unCamelData.setSTRING5("string5"); + unCamelData.setSTRing6("string6"); + list.add(unCamelData); + } + return list; + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java index 7a0e92e5..ffa8280c 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/fill/FillTest.java @@ -2,6 +2,7 @@ package com.alibaba.easyexcel.test.demo.fill; import java.io.File; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -205,7 +206,9 @@ public class FillTest { excelWriter.fill(new FillWrapper("data3", data()), writeSheet); Map map = new HashMap(); - map.put("date", "2019年10月9日13:28:28"); + //map.put("date", "2019年10月9日13:28:28"); + map.put("date", new Date()); + excelWriter.fill(map, writeSheet); // 别忘记关闭流 diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java b/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java index 01adfe72..df2afc36 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoExtraListener.java @@ -1,19 +1,18 @@ package com.alibaba.easyexcel.test.demo.read; -import org.junit.Assert; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.CellExtra; import com.alibaba.fastjson.JSON; +import org.junit.Assert; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * 读取单元格的批注 * - * @author: kaiux - * @date: 2019-10-23 14:10 + * @author Jiaju Zhuang **/ public class DemoExtraListener extends AnalysisEventListener { private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class); diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java index ab0ad968..0a147564 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java @@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.fastjson.JSON; /** @@ -43,7 +44,7 @@ public class WebTest { @GetMapping("download") public void download(HttpServletResponse response) throws IOException { // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman - response.setContentType("application/vnd.ms-excel"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20"); @@ -60,7 +61,7 @@ public class WebTest { public void downloadFailedUsingJson(HttpServletResponse response) throws IOException { // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman try { - response.setContentType("application/vnd.ms-excel"); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20"); diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/CommentWriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/CommentWriteHandler.java index 299d4072..d6eacb42 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/CommentWriteHandler.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/CommentWriteHandler.java @@ -8,6 +8,7 @@ import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFRichTextString; import com.alibaba.excel.write.handler.AbstractRowWriteHandler; +import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; @@ -16,7 +17,7 @@ import com.alibaba.excel.write.metadata.holder.WriteTableHolder; * * @author Jiaju Zhuang */ -public class CommentWriteHandler extends AbstractRowWriteHandler { +public class CommentWriteHandler implements RowWriteHandler { @Override public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java index b1bcb7dc..b4ade88f 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/CustomCellWriteHandler.java @@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.write.handler.AbstractCellWriteHandler; +import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; @@ -20,13 +21,13 @@ import com.alibaba.excel.write.metadata.holder.WriteTableHolder; * * @author Jiaju Zhuang */ -public class CustomCellWriteHandler extends AbstractCellWriteHandler { +public class CustomCellWriteHandler implements CellWriteHandler { private static final Logger LOGGER = LoggerFactory.getLogger(CustomCellWriteHandler.class); @Override public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, - List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { // 这里可以对cell进行任何操作 LOGGER.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex()); if (isHead && cell.getColumnIndex() == 0) { diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/CamlData.java b/src/test/java/com/alibaba/easyexcel/test/temp/CamlData.java new file mode 100644 index 00000000..9c3f39e4 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/CamlData.java @@ -0,0 +1,18 @@ +package com.alibaba.easyexcel.test.temp; + +import lombok.Data; + +/** + * TODO + * + * @author 是仪 + */ +@Data +public class CamlData { + private String string1; + private String String2; + private String sTring3; + private String STring4; + private String STRING5; + private String STRing6; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java index 938e031b..e8545670 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java @@ -34,7 +34,7 @@ public class Lock2Test { @Test public void test() throws Exception { // File file = TestFileUtil.readUserHomeFile("test/test6.xls"); - File file = new File("D:\\test\\T85_税金入库表202010.xlsx"); + File file = new File("/Users/zhuangjiaju/Downloads/1.xlsx"); List list = EasyExcel.read(file).sheet(0).headRowNumber(0).doReadSync(); LOGGER.info("数据:{}", list.size()); diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java index 27f820bc..ad09717f 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/LockTest.java @@ -26,11 +26,7 @@ public class LockTest { public void test() throws Exception { List list = - EasyExcel.read(new FileInputStream("D:\\test\\testbug嘉惠.xlsx")).sheet().headRowNumber(0).doReadSync(); - for (Object data : list) { - LOGGER.info("返回数据:{}", JSON.toJSONString(data)); - } - list = EasyExcel.read(new File("D:\\test\\t222.xlsx")).sheet().headRowNumber(0).doReadSync(); + EasyExcel.read(new FileInputStream("/Users/zhuangjiaju/Downloads/点位配置表 (1).xlsx")).doReadAllSync(); for (Object data : list) { LOGGER.info("返回数据:{}", JSON.toJSONString(data)); } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/WriteLargeTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/WriteLargeTest.java index 008d7629..23f623b6 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/WriteLargeTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/WriteLargeTest.java @@ -3,18 +3,7 @@ package com.alibaba.easyexcel.test.temp; import java.util.ArrayList; import java.util.List; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.alibaba.easyexcel.test.core.large.LargeData; -import com.alibaba.easyexcel.test.demo.write.DemoData; import com.alibaba.easyexcel.test.util.TestFileUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; @@ -23,6 +12,13 @@ import com.alibaba.excel.write.metadata.style.WriteCellStyle; import com.alibaba.excel.write.metadata.style.WriteFont; import com.alibaba.excel.write.style.HorizontalCellStyleStrategy; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * 临时测试 * @@ -59,8 +55,23 @@ public class WriteLargeTest { HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle); + ExcelWriter excelWriter = EasyExcel.write(fileName, LargeData.class).registerWriteHandler( + horizontalCellStyleStrategy).build(); + WriteSheet writeSheet = EasyExcel.writerSheet().build(); + for (int j = 0; j < 100; j++) { + excelWriter.write(data(), writeSheet); + LOGGER.info("{} fill success.", j); + } + excelWriter.finish(); - ExcelWriter excelWriter = EasyExcel.write(fileName,LargeData.class).registerWriteHandler(horizontalCellStyleStrategy).build(); + } + + @Test + public void test2() throws Exception { + // 方法2 如果写到不同的sheet 同一个对象 + String fileName = TestFileUtil.getPath() + "large" + System.currentTimeMillis() + ".xlsx"; + + ExcelWriter excelWriter = EasyExcel.write(fileName, LargeData.class).build(); WriteSheet writeSheet = EasyExcel.writerSheet().build(); for (int j = 0; j < 100; j++) { excelWriter.write(data(), writeSheet); @@ -70,39 +81,17 @@ public class WriteLargeTest { } + private List> data() { + List> list = new ArrayList<>(); - private List data() { - List list = new ArrayList(); - int size = i + 5000; - for (; i < size; i++) { - LargeData largeData = new LargeData(); - list.add(largeData); - largeData.setStr1("str1-" + i); - largeData.setStr2("str2-" + i); - largeData.setStr3("str3-" + i); - largeData.setStr4("str4-" + i); - largeData.setStr5("str5-" + i); - largeData.setStr6("str6-" + i); - largeData.setStr7("str7-" + i); - largeData.setStr8("str8-" + i); - largeData.setStr9("str9-" + i); - largeData.setStr10("str10-" + i); - largeData.setStr11("str11-" + i); - largeData.setStr12("str12-" + i); - largeData.setStr13("str13-" + i); - largeData.setStr14("str14-" + i); - largeData.setStr15("str15-" + i); - largeData.setStr16("str16-" + i); - largeData.setStr17("str17-" + i); - largeData.setStr18("str18-" + i); - largeData.setStr19("str19-" + i); - largeData.setStr20("str20-" + i); - largeData.setStr21("str21-" + i); - largeData.setStr22("str22-" + i); - largeData.setStr23("str23-" + i); - largeData.setStr24("str24-" + i); - largeData.setStr25("str25-" + i); + for (int j = 0; j < 10000; j++) { + List oneRow = new ArrayList<>(); + for (int i = 0; i < 150; i++) { + oneRow.add("这是测试字段" + i); + } + list.add(oneRow); } + return list; } } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java index c4331b1e..e5d7dfc3 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/Xls03Test.java @@ -2,14 +2,15 @@ package com.alibaba.easyexcel.test.temp; import java.util.List; +import com.alibaba.excel.EasyExcel; +import com.alibaba.fastjson.JSON; + +import net.sf.cglib.core.DebuggingClassWriter; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import com.alibaba.excel.EasyExcel; -import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson.JSON; +import org.springframework.cglib.beans.BeanMap; /** * 临时测试 @@ -27,4 +28,24 @@ public class Xls03Test { LOGGER.info("返回数据:{}", JSON.toJSONString(data)); } } + + @Test + public void test2() { + System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); + System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, + "/Users/zhuangjiaju/IdeaProjects/easyexcel/target"); + + CamlData camlData = new CamlData(); + //camlData.setTest("test2"); + //camlData.setAEst("test3"); + //camlData.setTEST("test4"); + + BeanMap beanMap = BeanMap.create(camlData); + + LOGGER.info("test:{}", beanMap.get("test")); + LOGGER.info("test:{}", beanMap.get("Test")); + LOGGER.info("test:{}", beanMap.get("TEst")); + LOGGER.info("test:{}", beanMap.get("TEST")); + + } } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java index e165d987..53902240 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/dataformat/DataFormatTest.java @@ -44,7 +44,7 @@ public class DataFormatTest { EasyExcel.read(file, DataFormatData.class, null).sheet().headRowNumber(0).doReadSync(); LOGGER.info("数据:{}", list.size()); for (DataFormatData data : list) { - Integer dataFormat = data.getDate().getDataFormat(); + Short dataFormat = data.getDate().getDataFormat(); String dataFormatString = data.getDate().getDataFormatString(); @@ -67,7 +67,7 @@ public class DataFormatTest { EasyExcel.read(file, DataFormatData.class, null).sheet().headRowNumber(0).doReadSync(); LOGGER.info("数据:{}", list.size()); for (DataFormatData data : list) { - Integer dataFormat = data.getDate().getDataFormat(); + Short dataFormat = data.getDate().getDataFormat(); String dataFormatString = data.getDate().getDataFormatString(); diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java index 0bde12ef..7f4a6717 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/large/TempLargeDataTest.java @@ -1,16 +1,19 @@ package com.alibaba.easyexcel.test.temp.large; +import java.io.File; import java.io.FileInputStream; +import java.lang.reflect.Field; +import com.alibaba.easyexcel.test.core.large.LargeDataTest; +import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; + +import org.apache.poi.openxml4j.util.ZipSecureFile; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.alibaba.easyexcel.test.core.large.LargeDataTest; -import com.alibaba.easyexcel.test.util.TestFileUtil; -import com.alibaba.excel.EasyExcel; - /** * @author Jiaju Zhuang */ @@ -29,9 +32,24 @@ public class TempLargeDataTest { @Test public void noModelRead() throws Exception { + ZipSecureFile.setMaxEntrySize(Long.MAX_VALUE); long start = System.currentTimeMillis(); EasyExcel.read(TestFileUtil.readUserHomeFile("test/ld.xlsx"), new NoModelLargeDataListener()) .sheet().doRead(); LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start); } + + @Test + public void noModelRead2() throws Exception { + Field field = ZipSecureFile.class.getDeclaredField("MAX_ENTRY_SIZE"); + field.setAccessible(true); + field.set(null, Long.MAX_VALUE); + + long start = System.currentTimeMillis(); + EasyExcel.read( + new File("/Users/zhuangjiaju/IdeaProjects/easyexcel/target/test-classes/large1617887262709.xlsx"), + new NoModelLargeDataListener()) + .sheet().doRead(); + LOGGER.info("Large data total time spent:{}", System.currentTimeMillis() - start); + } } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/poi/TestCell.java b/src/test/java/com/alibaba/easyexcel/test/temp/poi/TestCell.java index 3c4e0ab6..bb12c220 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/poi/TestCell.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/poi/TestCell.java @@ -13,6 +13,6 @@ import lombok.Data; **/ @Data public class TestCell { - private CellData c1; + private CellData c1; private CellData> c2; } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java index ffabd105..98e77527 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java @@ -5,11 +5,6 @@ import java.util.Date; import java.util.List; import java.util.Map; -import org.junit.Ignore; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.alibaba.easyexcel.test.core.large.LargeData; import com.alibaba.easyexcel.test.demo.write.DemoData; import com.alibaba.easyexcel.test.util.TestFileUtil; @@ -19,7 +14,12 @@ import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteTable; import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; import net.sf.cglib.beans.BeanMap; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * 测试poi @@ -27,6 +27,7 @@ import net.sf.cglib.beans.BeanMap; * @author Jiaju Zhuang **/ @Ignore +@Slf4j public class Wirte { private static final Logger LOGGER = LoggerFactory.getLogger(Wirte.class); @@ -43,6 +44,7 @@ public class Wirte { @Test public void simpleWrite() { + log.info("t5"); // 写法1 String fileName = TestFileUtil.getPath() + "t22" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 @@ -56,7 +58,18 @@ public class Wirte { String fileName = TestFileUtil.getPath() + "t22" + System.currentTimeMillis() + ".xlsx"; // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 // 如果这里想使用03 则 传入excelType参数即可 - EasyExcel.write(fileName, WriteData.class).sheet("模板").registerWriteHandler(new WriteHandler()).doWrite(data1()); + EasyExcel.write(fileName, WriteData.class).sheet("模板").registerWriteHandler(new WriteHandler()).doWrite( + data1()); + } + + @Test + public void simpleWrite3() { + // 写法1 + String fileName = TestFileUtil.getPath() + "t33" + System.currentTimeMillis() + ".xlsx"; + // 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭 + // 如果这里想使用03 则 传入excelType参数即可 + EasyExcel.write(fileName).head(head()).inMemory(true).sheet("模板").registerWriteHandler(new WriteCellHandler()).doWrite( + data1()); } @Test @@ -125,7 +138,7 @@ public class Wirte { List list = new ArrayList(); for (int i = 0; i < 10; i++) { WriteData data = new WriteData(); - data.setF(300.35f); + data.setDd(new Date()); data.setF1(33f); list.add(data); } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteCellHandler.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteCellHandler.java new file mode 100644 index 00000000..375cf636 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteCellHandler.java @@ -0,0 +1,40 @@ +package com.alibaba.easyexcel.test.temp.simple; + +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.write.handler.AbstractCellWriteHandler; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; + +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.DataFormat; +import org.apache.poi.ss.usermodel.IndexedColors; + +/** + * @author Jiaju Zhuang + */ +@Slf4j +public class WriteCellHandler implements CellWriteHandler { + + @Override + public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, + CellData cellData, Cell cell, Head head, Integer integer, Boolean isHead) { + + if (!isHead) { + CreationHelper createHelper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper(); + CellStyle cellStyle = writeSheetHolder.getSheet().getWorkbook().createCellStyle(); + if (cellStyle != null) { + DataFormat dataFormat = createHelper.createDataFormat(); + cellStyle.setWrapText(true); + cellStyle.setFillBackgroundColor(IndexedColors.RED.getIndex()); + cellStyle.setBottomBorderColor(IndexedColors.RED.getIndex()); + cellStyle.setDataFormat(dataFormat.getFormat("yyyy-MM-dd")); + cell.setCellStyle(cellStyle); + } + } + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java index 2b25bb0a..27967b9f 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteData.java @@ -1,5 +1,7 @@ package com.alibaba.easyexcel.test.temp.simple; +import java.util.Date; + import com.alibaba.excel.annotation.write.style.ContentStyle; import lombok.Data; @@ -12,7 +14,7 @@ import lombok.Data; @Data public class WriteData { // @ContentStyle(locked = true) - private float f; + private Date dd; // @ContentStyle(locked = false) private float f1; } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteHandler.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteHandler.java index 1420b2b0..a82543eb 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteHandler.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/WriteHandler.java @@ -1,6 +1,7 @@ package com.alibaba.easyexcel.test.temp.simple; import com.alibaba.excel.write.handler.AbstractSheetWriteHandler; +import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; @@ -10,7 +11,7 @@ import lombok.extern.slf4j.Slf4j; * @author Jiaju Zhuang */ @Slf4j -public class WriteHandler extends AbstractSheetWriteHandler { +public class WriteHandler implements SheetWriteHandler { @Override public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, diff --git a/update.md b/update.md index d7a96f7c..09ca62ac 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,23 @@ +# 3.0.0-beta1 +* 升级jdk8 不再支持jdk6 jdk7 +* 升级poi 到 4.1.2 +* 升级cglib 到 3.3.0 +* 升级ehcache 到 3.8.1 +* 支持非驼峰的字段读写 +* 修复`CellData`可能不返回行列号 [Issue #1832](https://github.com/alibaba/easyexcel/issues/1832) +* 优化读取性能 +* 修复部分情况下不抛出异常 +* 07版在导出的时候会导出 行数 [Issue #1282](https://github.com/alibaba/easyexcel/issues/1282) +* 修复没有样式的情况下空指针异常 [Issue #1738](https://github.com/alibaba/easyexcel/issues/1738) +* 修改异常抛出逻辑 [Issue #1618](https://github.com/alibaba/easyexcel/issues/1618) +* 兼容一些非官方excel的情况 [Issue #1527](https://github.com/alibaba/easyexcel/issues/1527) +* 修改读的关闭流无效 [Issue #1840](https://github.com/alibaba/easyexcel/issues/1840) +* 写入支持Collection [Issue #1834](https://github.com/alibaba/easyexcel/issues/1834) + + +# 2.2.8 +* 兼容07在特殊的excel的情况下,读取数据异常 + # 2.2.7 * 修改07在特殊情况下用`String`接收数字会丢小数位的bug