Browse Source

Merge branch '3.x' into master

developing
Jiaju Zhuang 4 years ago committed by GitHub
parent
commit
10bd7dc367
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      README.md
  2. 46
      pom.xml
  3. 18
      src/main/java/com/alibaba/excel/ExcelWriter.java
  4. 2
      src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
  5. 22
      src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java
  6. 11
      src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java
  7. 2
      src/main/java/com/alibaba/excel/analysis/v03/handlers/StringRecordHandler.java
  8. 58
      src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java
  9. 12
      src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java
  10. 2
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java
  11. 16
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java
  12. 5
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java
  13. 11
      src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java
  14. 2
      src/main/java/com/alibaba/excel/annotation/ExcelProperty.java
  15. 92
      src/main/java/com/alibaba/excel/cache/Ehcache.java
  16. 10
      src/main/java/com/alibaba/excel/cache/MapCache.java
  17. 8
      src/main/java/com/alibaba/excel/constant/BuiltinFormats.java
  18. 13
      src/main/java/com/alibaba/excel/constant/OrderConstant.java
  19. 41
      src/main/java/com/alibaba/excel/context/WriteContextImpl.java
  20. 8
      src/main/java/com/alibaba/excel/converters/AutoConverter.java
  21. 78
      src/main/java/com/alibaba/excel/converters/Converter.java
  22. 14
      src/main/java/com/alibaba/excel/converters/ConverterKeyBuild.java
  23. 40
      src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
  24. 10
      src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalBooleanConverter.java
  25. 12
      src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java
  26. 8
      src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalStringConverter.java
  27. 8
      src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanBooleanConverter.java
  28. 10
      src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java
  29. 8
      src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanStringConverter.java
  30. 8
      src/main/java/com/alibaba/excel/converters/bytearray/BoxingByteArrayImageConverter.java
  31. 8
      src/main/java/com/alibaba/excel/converters/bytearray/ByteArrayImageConverter.java
  32. 10
      src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java
  33. 12
      src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java
  34. 8
      src/main/java/com/alibaba/excel/converters/byteconverter/ByteStringConverter.java
  35. 47
      src/main/java/com/alibaba/excel/converters/date/DateDateConverter.java
  36. 10
      src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java
  37. 10
      src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java
  38. 10
      src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleBooleanConverter.java
  39. 13
      src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java
  40. 8
      src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleStringConverter.java
  41. 8
      src/main/java/com/alibaba/excel/converters/file/FileImageConverter.java
  42. 10
      src/main/java/com/alibaba/excel/converters/floatconverter/FloatBooleanConverter.java
  43. 15
      src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java
  44. 8
      src/main/java/com/alibaba/excel/converters/floatconverter/FloatStringConverter.java
  45. 8
      src/main/java/com/alibaba/excel/converters/inputstream/InputStreamImageConverter.java
  46. 10
      src/main/java/com/alibaba/excel/converters/integer/IntegerBooleanConverter.java
  47. 14
      src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java
  48. 8
      src/main/java/com/alibaba/excel/converters/integer/IntegerStringConverter.java
  49. 10
      src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java
  50. 14
      src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java
  51. 8
      src/main/java/com/alibaba/excel/converters/longconverter/LongStringConverter.java
  52. 10
      src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java
  53. 13
      src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java
  54. 8
      src/main/java/com/alibaba/excel/converters/shortconverter/ShortStringConverter.java
  55. 8
      src/main/java/com/alibaba/excel/converters/string/StringBooleanConverter.java
  56. 8
      src/main/java/com/alibaba/excel/converters/string/StringErrorConverter.java
  57. 8
      src/main/java/com/alibaba/excel/converters/string/StringImageConverter.java
  58. 8
      src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java
  59. 8
      src/main/java/com/alibaba/excel/converters/string/StringStringConverter.java
  60. 8
      src/main/java/com/alibaba/excel/converters/url/UrlImageConverter.java
  61. 8
      src/main/java/com/alibaba/excel/enums/CellDataTypeEnum.java
  62. 2
      src/main/java/com/alibaba/excel/event/AnalysisEventListener.java
  63. 38
      src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java
  64. 8
      src/main/java/com/alibaba/excel/metadata/AbstractHolder.java
  65. 142
      src/main/java/com/alibaba/excel/metadata/CellData.java
  66. 2
      src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java
  67. 10
      src/main/java/com/alibaba/excel/metadata/format/DataFormatter.java
  68. 2
      src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
  69. 51
      src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
  70. 2
      src/main/java/com/alibaba/excel/read/listener/ReadListener.java
  71. 18
      src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java
  72. 6
      src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java
  73. 4
      src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java
  74. 75
      src/main/java/com/alibaba/excel/util/BooleanUtils.java
  75. 49
      src/main/java/com/alibaba/excel/util/ClassUtils.java
  76. 22
      src/main/java/com/alibaba/excel/util/CollectionUtils.java
  77. 49
      src/main/java/com/alibaba/excel/util/ConverterUtils.java
  78. 32
      src/main/java/com/alibaba/excel/util/DateUtils.java
  79. 145
      src/main/java/com/alibaba/excel/util/FieldUtils.java
  80. 24
      src/main/java/com/alibaba/excel/util/FileUtils.java
  81. 39
      src/main/java/com/alibaba/excel/util/IntUtils.java
  82. 121
      src/main/java/com/alibaba/excel/util/ListUtils.java
  83. 63
      src/main/java/com/alibaba/excel/util/MapUtils.java
  84. 54
      src/main/java/com/alibaba/excel/util/MemberUtils.java
  85. 2
      src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java
  86. 24
      src/main/java/com/alibaba/excel/util/NumberUtils.java
  87. 87
      src/main/java/com/alibaba/excel/util/StringUtils.java
  88. 20
      src/main/java/com/alibaba/excel/util/StyleUtil.java
  89. 151
      src/main/java/com/alibaba/excel/util/Validate.java
  90. 25
      src/main/java/com/alibaba/excel/util/WorkBookUtil.java
  91. 38
      src/main/java/com/alibaba/excel/util/WriteHandlerUtils.java
  92. 7
      src/main/java/com/alibaba/excel/write/ExcelBuilder.java
  93. 10
      src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  94. 4
      src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java
  95. 4
      src/main/java/com/alibaba/excel/write/builder/ExcelWriterTableBuilder.java
  96. 59
      src/main/java/com/alibaba/excel/write/executor/AbstractExcelWriteExecutor.java
  97. 50
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteAddExecutor.java
  98. 40
      src/main/java/com/alibaba/excel/write/executor/ExcelWriteFillExecutor.java
  99. 4
      src/main/java/com/alibaba/excel/write/handler/AbstractCellWriteHandler.java
  100. 6
      src/main/java/com/alibaba/excel/write/handler/AbstractRowWriteHandler.java
  101. Some files were not shown because too many files have changed in this diff Show More

10
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");

46
pom.xml

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.7</version>
<version>3.0.0-beta1</version>
<packaging>jar</packaging>
<name>easyexcel</name>
@ -16,7 +16,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.6</jdk.version>
<jdk.version>1.8</jdk.version>
<gpg.skip>true</gpg.skip>
<maven.javadoc.skip>true</maven.javadoc.skip>
</properties>
@ -60,22 +60,22 @@
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.17</version>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@ -85,8 +85,15 @@
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.4.0</version>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<!--test-->
<dependency>
<groupId>ch.qos.logback</groupId>
@ -100,12 +107,6 @@
<version>1.2.71</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
@ -121,7 +122,7 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -187,8 +188,8 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
@ -232,6 +233,19 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.18.20.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>delombok</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

18
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) {

2
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;

22
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<Integer, Cell> 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);

11
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);
CellData<?>cellData = 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),

2
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();
CellData<?>tempCellData = xlsReadSheetHolder.getTempCellData();
if (tempCellData == null) {
LOGGER.warn("String type formula but no value found.");
return;

58
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<ReadSheet>();
sheetMap = new HashMap<Integer, InputStream>();
commentsTableMap = new HashMap<Integer, CommentsTable>();
@ -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) {

12
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();

2
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());
}

16
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()));

5
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()) {

11
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<Integer, Cell>());
xlsxReadSheetHolder.setCellMap(new LinkedHashMap<>());
}
}

2
src/main/java/com/alibaba/excel/annotation/ExcelProperty.java

@ -23,7 +23,7 @@ public @interface ExcelProperty {
* <p>
* write: It automatically merges when you have more than one head
* <p>
* 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
*/

92
src/main/java/com/alibaba/excel/cache/Ehcache.java vendored

@ -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<Integer, String> dataMap = new HashMap<Integer, String>(BATCH_COUNT * 4 / 3 + 1);
private static CacheManager fileCacheManager;
private static CacheConfiguration<Integer, HashMap> fileCacheConfiguration;
private static CacheManager activeCacheManager;
private CacheConfiguration<Integer, HashMap> 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<String> dataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
private static final CacheManager FILE_CACHE_MANAGER;
private static final CacheConfiguration<Integer, ArrayList> FILE_CACHE_CONFIGURATION;
private static final CacheManager ACTIVE_CACHE_MANAGER;
private final CacheConfiguration<Integer, ArrayList> activeCacheConfiguration;
/**
* Bulk storage data
*/
private org.ehcache.Cache<Integer, HashMap> fileCache;
private org.ehcache.Cache<Integer, ArrayList> fileCache;
/**
* Currently active cache
*/
private org.ehcache.Cache<Integer, HashMap> activeCache;
private org.ehcache.Cache<Integer, ArrayList> 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<Integer, String>(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<Integer, String> dataMap = activeCache.get(route);
if (dataMap == null) {
dataMap = fileCache.get(route);
activeCache.put(route, dataMap);
if (LOGGER.isDebugEnabled()) {
ArrayList<String> 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);
}
}

10
src/main/java/com/alibaba/excel/cache/MapCache.java vendored

@ -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<Integer, String> cache = new HashMap<Integer, String>();
private int index = 0;
private List<String> cache = new ArrayList<>();
@Override
public void init(AnalysisContext analysisContext) {}
@Override
public void put(String value) {
cache.put(index++, value);
cache.add(value);
}
@Override

8
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;

13
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;
}

41
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();

8
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<Object> {
@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;
}

78
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 <T>
* @author Dan Zheng
*/
public interface Converter<T> {
@ -18,44 +22,72 @@ public interface Converter<T> {
*
* @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());
}
}

14
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<String, String> BOXING_MAP = new HashMap<String, String>(16);
private static final Map<String, String> 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();
}
}

40
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<String, Converter> defaultWriteConverter;
private static Map<String, Converter> allConverter;
private static Map<String, Converter<?>> defaultWriteConverter;
private static Map<String, Converter<?>> allConverter;
static {
initDefaultWriteConverter();
@ -54,7 +55,7 @@ public class DefaultConverterLoader {
}
private static void initAllConverter() {
allConverter = new HashMap<String, Converter>(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<String, Converter>(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<String, Converter> loadDefaultWriteConverter() {
public static Map<String, Converter<?>> 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<String, Converter> loadDefaultReadConverter() {
public static Map<String, Converter<?>> loadDefaultReadConverter() {
return loadAllConverter();
}
@ -142,11 +160,11 @@ public class DefaultConverterLoader {
*
* @return
*/
public static Map<String, Converter> loadAllConverter() {
public static Map<String, Converter<?>> loadAllConverter() {
return allConverter;
}
private static void putAllConverter(Converter converter) {
private static void putAllConverter(Converter<?> converter) {
allConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey(), converter.supportExcelTypeKey()),
converter);
}

10
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<BigDecimal> {
@Override
public Class supportJavaTypeKey() {
public Class<BigDecimal> supportJavaTypeKey() {
return BigDecimal.class;
}
@ -26,7 +26,7 @@ public class BigDecimalBooleanConverter implements Converter<BigDecimal> {
}
@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<BigDecimal> {
}
@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);
}
}

12
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<BigDecimal> {
@Override
public Class supportJavaTypeKey() {
public Class<BigDecimal> supportJavaTypeKey() {
return BigDecimal.class;
}
@ -26,14 +28,14 @@ public class BigDecimalNumberConverter implements Converter<BigDecimal> {
}
@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);
}
}

8
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<BigDecimal> {
@Override
public Class supportJavaTypeKey() {
public Class<BigDecimal> supportJavaTypeKey() {
return BigDecimal.class;
}
@ -28,14 +28,14 @@ public class BigDecimalStringConverter implements Converter<BigDecimal> {
}
@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);
}
}

8
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<Boolean> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Boolean.class;
}
@ -24,15 +24,15 @@ public class BooleanBooleanConverter implements Converter<Boolean> {
}
@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);
}
}

10
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<Boolean> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Boolean.class;
}
@ -25,7 +25,7 @@ public class BooleanNumberConverter implements Converter<Boolean> {
}
@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<Boolean> {
}
@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);
}
}

8
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<Boolean> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Boolean.class;
}
@ -24,15 +24,15 @@ public class BooleanStringConverter implements Converter<Boolean> {
}
@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());
}
}

8
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<Byte[]> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Byte[].class;
}
@ -23,19 +23,19 @@ public class BoxingByteArrayImageConverter implements Converter<Byte[]> {
}
@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);
}
}

8
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<byte[]> {
@Override
public Class supportJavaTypeKey() {
public Class<byte[]> supportJavaTypeKey() {
return byte[].class;
}
@ -23,15 +23,15 @@ public class ByteArrayImageConverter implements Converter<byte[]> {
}
@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);
}
}

10
src/main/java/com/alibaba/excel/converters/byteconverter/ByteBooleanConverter.java

@ -16,7 +16,7 @@ public class ByteBooleanConverter implements Converter<Byte> {
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<Byte> {
}
@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<Byte> {
}
@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);
}
}

12
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<Byte> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Byte.class;
}
@ -26,15 +28,15 @@ public class ByteNumberConverter implements Converter<Byte> {
}
@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);
}
}

8
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<Byte> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Byte.class;
}
@ -27,15 +27,15 @@ public class ByteStringConverter implements Converter<Byte> {
}
@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);
}
}

47
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<Date> {
@Override
public Class<Date> 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;
}
}

10
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<Date> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Date.class;
}
@ -29,7 +29,7 @@ public class DateNumberConverter implements Converter<Date> {
}
@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<Date> {
}
@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())));
}
}

10
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<Date> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Date.class;
}
@ -27,7 +27,7 @@ public class DateStringConverter implements Converter<Date> {
}
@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<Date> {
}
@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()));
}
}
}

10
src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleBooleanConverter.java

@ -16,7 +16,7 @@ public class DoubleBooleanConverter implements Converter<Double> {
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<Double> {
}
@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<Double> {
}
@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);
}
}

13
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<Double> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Double.class;
}
@ -26,15 +28,14 @@ public class DoubleNumberConverter implements Converter<Double> {
}
@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);
}
}

8
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<Double> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Double.class;
}
@ -27,14 +27,14 @@ public class DoubleStringConverter implements Converter<Double> {
}
@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);
}
}

8
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<File> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return File.class;
}
@ -27,15 +27,15 @@ public class FileImageConverter implements Converter<File> {
}
@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));
}
}

10
src/main/java/com/alibaba/excel/converters/floatconverter/FloatBooleanConverter.java

@ -16,7 +16,7 @@ public class FloatBooleanConverter implements Converter<Float> {
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<Float> {
}
@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<Float> {
}
@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);
}
}

15
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<Float> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Float.class;
}
@ -26,15 +26,14 @@ public class FloatNumberConverter implements Converter<Float> {
}
@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);
}
}

8
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<Float> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Float.class;
}
@ -27,14 +27,14 @@ public class FloatStringConverter implements Converter<Float> {
}
@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);
}
}

8
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<InputStream> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return InputStream.class;
}
@ -27,15 +27,15 @@ public class InputStreamImageConverter implements Converter<InputStream> {
}
@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));
}
}

10
src/main/java/com/alibaba/excel/converters/integer/IntegerBooleanConverter.java

@ -16,7 +16,7 @@ public class IntegerBooleanConverter implements Converter<Integer> {
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<Integer> {
}
@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<Integer> {
}
@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);
}
}

14
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<Integer> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Integer.class;
}
@ -26,15 +26,15 @@ public class IntegerNumberConverter implements Converter<Integer> {
}
@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);
}
}

8
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<Integer> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Integer.class;
}
@ -27,14 +27,14 @@ public class IntegerStringConverter implements Converter<Integer> {
}
@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);
}
}

10
src/main/java/com/alibaba/excel/converters/longconverter/LongBooleanConverter.java

@ -16,7 +16,7 @@ public class LongBooleanConverter implements Converter<Long> {
private static final Long ZERO = 0L;
@Override
public Class supportJavaTypeKey() {
public Class<Long> supportJavaTypeKey() {
return Long.class;
}
@ -26,7 +26,7 @@ public class LongBooleanConverter implements Converter<Long> {
}
@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<Long> {
}
@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);
}
}

14
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<Long> {
@Override
public Class supportJavaTypeKey() {
public Class<Long> supportJavaTypeKey() {
return Long.class;
}
@ -26,15 +26,15 @@ public class LongNumberConverter implements Converter<Long> {
}
@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);
}
}

8
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<Long> {
@Override
public Class supportJavaTypeKey() {
public Class<Long> supportJavaTypeKey() {
return Long.class;
}
@ -27,14 +27,14 @@ public class LongStringConverter implements Converter<Long> {
}
@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);
}
}

10
src/main/java/com/alibaba/excel/converters/shortconverter/ShortBooleanConverter.java

@ -16,7 +16,7 @@ public class ShortBooleanConverter implements Converter<Short> {
private static final Short ZERO = 0;
@Override
public Class supportJavaTypeKey() {
public Class<Short> supportJavaTypeKey() {
return Short.class;
}
@ -26,7 +26,7 @@ public class ShortBooleanConverter implements Converter<Short> {
}
@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<Short> {
}
@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);
}
}

13
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<Short> {
@Override
public Class supportJavaTypeKey() {
public Class<Short> supportJavaTypeKey() {
return Short.class;
}
@ -26,15 +28,14 @@ public class ShortNumberConverter implements Converter<Short> {
}
@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);
}
}

8
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<Short> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return Short.class;
}
@ -27,14 +27,14 @@ public class ShortStringConverter implements Converter<Short> {
}
@Override
public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
public Short convertToJavaData(CellData<?>cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws ParseException {
return NumberUtils.parseShort(cellData.getStringValue(), contentProperty);
}
@Override
public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty,
public CellData<?>convertToExcelData(Short value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
return NumberUtils.formatToCellData(value, contentProperty);
return NumberUtils.formatToCellDataString(value, contentProperty);
}
}

8
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<String> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return String.class;
}
@ -24,15 +24,15 @@ public class StringBooleanConverter implements Converter<String> {
}
@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));
}
}

8
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<String> {
@Override
public Class supportJavaTypeKey() {
public Class<String> supportJavaTypeKey() {
return String.class;
}
@ -23,15 +23,15 @@ public class StringErrorConverter implements Converter<String> {
}
@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);
}
}

8
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<String> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return String.class;
}
@ -27,15 +27,15 @@ public class StringImageConverter implements Converter<String> {
}
@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)));
}
}

8
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<String> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return String.class;
}
@ -32,7 +32,7 @@ public class StringNumberConverter implements Converter<String> {
}
@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<String> {
}
@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));
}
}

8
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<String> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return String.class;
}
@ -23,15 +23,15 @@ public class StringStringConverter implements Converter<String> {
}
@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);
}
}

8
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<URL> {
@Override
public Class supportJavaTypeKey() {
public Class<?> supportJavaTypeKey() {
return URL.class;
}
@ -29,19 +29,19 @@ public class UrlImageConverter implements Converter<URL> {
}
@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();

8
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<String, CellDataTypeEnum> TYPE_ROUTING_MAP = new HashMap<String, CellDataTypeEnum>(16);
static {
TYPE_ROUTING_MAP.put("s", STRING);
TYPE_ROUTING_MAP.put("str", DIRECT_STRING);

2
src/main/java/com/alibaba/excel/event/AnalysisEventListener.java

@ -16,7 +16,7 @@ import com.alibaba.excel.util.ConverterUtils;
public abstract class AnalysisEventListener<T> implements ReadListener<T> {
@Override
public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {
public void invokeHead(Map<Integer, CellData<?>> headMap, AnalysisContext context) {
invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context);
}

38
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;
}
}

8
src/main/java/com/alibaba/excel/metadata/AbstractHolder.java

@ -34,7 +34,7 @@ public abstract class AbstractHolder implements ConfigurationHolder {
* <p>
* Write key:
*/
private Map<String, Converter> converterMap;
private Map<String, Converter<?>> 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<String, Converter> getConverterMap() {
public Map<String, Converter<?>> getConverterMap() {
return converterMap;
}
public void setConverterMap(Map<String, Converter> converterMap) {
public void setConverterMap(Map<String, Converter<?>> converterMap) {
this.converterMap = converterMap;
}
@Override
public Map<String, Converter> converterMap() {
public Map<String, Converter<?>> converterMap() {
return getConverterMap();
}

142
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<T> extends AbstractCell {
private CellDataTypeEnum type;
/**
@ -30,11 +36,15 @@ public class CellData<T> 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<T> 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<T> 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<T> 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<T> 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;

2
src/main/java/com/alibaba/excel/metadata/ConfigurationHolder.java

@ -32,5 +32,5 @@ public interface ConfigurationHolder extends Holder {
*
* @return Converter
*/
Map<String, Converter> converterMap();
Map<String, Converter<?>> converterMap();
}

10
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);
}

2
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;

51
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<Map<Integer, CellData>> {
public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener<Map<Integer, CellData<?>>> {
@Override
public void invokeHead(Map<Integer, CellData> cellDataMap, AnalysisContext context) {}
public void invokeHead(Map<Integer, CellData<?>> cellDataMap, AnalysisContext context) {}
@Override
public void invoke(Map<Integer, CellData> cellDataMap, AnalysisContext context) {
ReadHolder currentReadHolder = context.currentReadHolder();
if (HeadKindEnum.CLASS.equals(currentReadHolder.excelReadHeadProperty().getHeadKind())) {
public void invoke(Map<Integer, CellData<?>> 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<Integer, CellData> cellDataMap, ReadHolder currentReadHolder,
private Object buildStringList(Map<Integer, CellData<?>> cellDataMap, ReadSheetHolder readSheetHolder,
AnalysisContext context) {
int index = 0;
if (context.readWorkbookHolder().getDefaultReturnMap()) {
Map<Integer, String> map = new LinkedHashMap<Integer, String>(cellDataMap.size() * 4 / 3 + 1);
for (Map.Entry<Integer, CellData> entry : cellDataMap.entrySet()) {
for (Map.Entry<Integer, CellData<?>> 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<String> list = new ArrayList<String>();
for (Map.Entry<Integer, CellData> entry : cellDataMap.entrySet()) {
List<String> list = new ArrayList<>();
for (Map.Entry<Integer, CellData<?>> 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<Integer, CellData> cellDataMap, ReadHolder currentReadHolder,
private Object buildUserModel(Map<Integer, CellData<?>> 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<Integer, Head> 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);

2
src/main/java/com/alibaba/excel/read/listener/ReadListener.java

@ -29,7 +29,7 @@ public interface ReadListener<T> extends Listener {
* @param headMap
* @param context
*/
void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context);
void invokeHead(Map<Integer, CellData<?>> headMap, AnalysisContext context);
/**
* When analysis one row trigger invoke function.

18
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<ReadListener>();
this.readListenerList = ListUtils.newArrayList();
} else {
this.readListenerList = new ArrayList<ReadListener>(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<String, Converter>(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);

6
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;
}

4
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<Integer, CellData> cellDataMap = (Map)readRowHolder.getCellMap();
Map<Integer, CellData<?>> 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<Integer, CellData> cellDataMap) {
private void buildHead(AnalysisContext analysisContext, Map<Integer, CellData<?>> cellDataMap) {
if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) {
return;
}

75
src/main/java/com/alibaba/excel/util/BooleanUtils.java

@ -25,4 +25,79 @@ public class BooleanUtils {
}
}
// boolean Boolean methods
//-----------------------------------------------------------------------
/**
* <p>Checks if a {@code Boolean} value is {@code true},
* handling {@code null} by returning {@code false}.</p>
*
* <pre>
* BooleanUtils.isTrue(Boolean.TRUE) = true
* BooleanUtils.isTrue(Boolean.FALSE) = false
* BooleanUtils.isTrue(null) = false
* </pre>
*
* @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);
}
/**
* <p>Checks if a {@code Boolean} value is <i>not</i> {@code true},
* handling {@code null} by returning {@code true}.</p>
*
* <pre>
* BooleanUtils.isNotTrue(Boolean.TRUE) = false
* BooleanUtils.isNotTrue(Boolean.FALSE) = true
* BooleanUtils.isNotTrue(null) = true
* </pre>
*
* @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);
}
/**
* <p>Checks if a {@code Boolean} value is {@code false},
* handling {@code null} by returning {@code false}.</p>
*
* <pre>
* BooleanUtils.isFalse(Boolean.TRUE) = false
* BooleanUtils.isFalse(Boolean.FALSE) = true
* BooleanUtils.isFalse(null) = false
* </pre>
*
* @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);
}
/**
* <p>Checks if a {@code Boolean} value is <i>not</i> {@code false},
* handling {@code null} by returning {@code true}.</p>
*
* <pre>
* BooleanUtils.isNotFalse(Boolean.TRUE) = true
* BooleanUtils.isNotFalse(Boolean.FALSE) = false
* BooleanUtils.isNotFalse(null) = true
* </pre>
*
* @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);
}
}

49
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;
}
}
/**
* <p>Gets a {@code List} of all interfaces implemented by the given
* class and its superclasses.</p>
*
* <p>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.</p>
*
* @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<Class<?>> getAllInterfaces(final Class<?> cls) {
if (cls == null) {
return null;
}
final LinkedHashSet<Class<?>> 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<Class<?>> interfacesFound) {
while (cls != null) {
final Class<?>[] interfaces = cls.getInterfaces();
for (final Class<?> i : interfaces) {
if (interfacesFound.add(i)) {
getAllInterfaces(i, interfacesFound);
}
}
cls = cls.getSuperclass();
}
}
}

22
src/main/java/com/alibaba/excel/util/CollectionUtils.java

@ -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());
}
}

49
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<Integer, String> convertToStringMap(Map<Integer, CellData> cellDataMap, AnalysisContext context) {
Map<Integer, String> stringMap = new HashMap<Integer, String>(cellDataMap.size() * 4 / 3 + 1);
ReadHolder currentReadHolder = context.currentReadHolder();
public static Map<Integer, String> convertToStringMap(Map<Integer, CellData<?>> cellDataMap, AnalysisContext context) {
Map<Integer, String> stringMap = MapUtils.newHashMapWithExpectedSize(cellDataMap.size());
ReadSheetHolder readSheetHolder = context.readSheetHolder();
int index = 0;
for (Map.Entry<Integer, CellData> entry : cellDataMap.entrySet()) {
for (Map.Entry<Integer, CellData<?>> 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<String, Converter> converterMap, GlobalConfiguration globalConfiguration, Integer rowIndex,
public static Object convertToJavaObject(CellData<?> cellData, Field field, ExcelContentProperty contentProperty,
Map<String, Converter<?>> 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<Object> cellDataReturn = new CellData<Object>(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<String, Converter> converterMap, GlobalConfiguration globalConfiguration, Integer rowIndex,
private static Object doConvertToJavaObject(CellData<?> cellData, Class<?> clazz,
ExcelContentProperty contentProperty,
Map<String, Converter<?>> 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);

32
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<Map<Integer, Boolean>> DATE_THREAD_LOCAL =
new ThreadLocal<Map<Integer, Boolean>>();
private static final ThreadLocal<Map<Short, Boolean>> DATE_THREAD_LOCAL =
new ThreadLocal<>();
/**
* Is a cache of dates
*/
private static final ThreadLocal<Map<String, SimpleDateFormat>> DATE_FORMAT_THREAD_LOCAL =
new ThreadLocal<Map<String, SimpleDateFormat>>();
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<Integer, Boolean> isDateCache = DATE_THREAD_LOCAL.get();
Map<Short, Boolean> isDateCache = DATE_THREAD_LOCAL.get();
if (isDateCache == null) {
isDateCache = new HashMap<Integer, Boolean>();
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...

145
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
* <ul>
* <ul>null -> null</ul>
* <ul>string1 -> string1</ul>
* <ul>String2 -> string2</ul>
* <ul>sTring3 -> STring3</ul>
* <ul>STring4 -> STring4</ul>
* <ul>STRING5 -> STRING5</ul>
* <ul>STRing6 -> STRing6</ul>
* </ul>
*
* @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;
}
}

24
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);

39
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;
}
}

121
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 <i>mutable</i>, empty {@code ArrayList} instance (for Java 6 and earlier).
*
* <p><b>Note for Java 7 and later:</b> 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 <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
*/
public static <E> ArrayList<E> newArrayList() {
return new ArrayList<>();
}
/**
* Creates a <i>mutable</i> {@code ArrayList} instance containing the given elements; a very thin
* shortcut for creating an empty list and then calling {@link Iterators#addAll}.
*
*/
public static <E> ArrayList<E> newArrayList(Iterator<? extends E> elements) {
ArrayList<E> list = newArrayList();
Iterators.addAll(list, elements);
return list;
}
/**
* Creates a <i>mutable</i> {@code ArrayList} instance containing the given elements;
*
*
* <p><b>Note for Java 7 and later:</b> 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 <a href="http://goo.gl/iz2Wi">"diamond"
* syntax</a>.
*/
public static <E> ArrayList<E> newArrayList(Iterable<? extends E> elements) {
checkNotNull(elements); // for GWT
// Let ArrayList's sizing logic work, if possible
return (elements instanceof Collection)
? new ArrayList<>((Collection<? extends E>)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)}.
*
* <p><b>Note for Java 7 and later:</b> 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 <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
* (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 <E> ArrayList<E> newArrayListWithCapacity(int initialArraySize) {
checkNonnegative(initialArraySize, "initialArraySize");
return new ArrayList<>(initialArraySize);
}
/**
* Creates an {@code ArrayList} instance to hold {@code estimatedSize} elements, <i>plus</i> an
* unspecified amount of padding; you almost certainly mean to call {@link
* #newArrayListWithCapacity} (see that method for further advice on usage).
*
* <p><b>Note:</b> 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 <E> ArrayList<E> 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 extends @NonNull Object> T checkNotNull(T reference) {
if (reference == null) {
throw new NullPointerException();
}
return reference;
}
}

63
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 <i>mutable</i>, empty {@code HashMap} instance.
*
* <p><b>Note:</b> if mutability is not required, use {@link ImmutableMap#of()} instead.
*
* <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link #newEnumMap} instead.
*
* <p><b>Note for Java 7 and later:</b> this method is now unnecessary and should be treated as
* deprecated. Instead, use the {@code HashMap} constructor directly, taking advantage of the new
* <a href="http://goo.gl/iz2Wi">"diamond" syntax</a>.
*
* @return a new, empty {@code HashMap}
*/
public static <K, V> HashMap<K, V> newHashMap() {
return new HashMap<>();
}
/**
* Creates a {@code HashMap} instance, with a high enough "initial capacity" that it <i>should</i>
* 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 <i>oversizing</i> 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 <K, V> HashMap<K, V> 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;
}
}

54
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;
}
}

2
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) {

24
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;
}
/**

87
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() {}
/**
* <p>Checks if a CharSequence is empty ("") or null.</p>
*
* <pre>
* StringUtils.isEmpty(null) = true
* StringUtils.isEmpty("") = true
* StringUtils.isEmpty(" ") = false
* StringUtils.isEmpty("bob") = false
* StringUtils.isEmpty(" bob ") = false
* </pre>
*
* <p>NOTE: This method changed in Lang version 2.0.
* It no longer trims the CharSequence.
* That functionality is available in isBlank().</p>
*
* @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));
/**
* <p>Checks if a CharSequence is empty (""), null or whitespace only.</p>
*
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.isBlank(null) = true
* StringUtils.isBlank("") = true
* StringUtils.isBlank(" ") = true
* StringUtils.isBlank("bob") = false
* StringUtils.isBlank(" bob ") = false
* </pre>
*
* @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;
}
/**
* <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p>
*
* <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p>
*
* <pre>
* StringUtils.isNotBlank(null) = false
* StringUtils.isNotBlank("") = false
* StringUtils.isNotBlank(" ") = false
* StringUtils.isNotBlank("bob") = true
* StringUtils.isNotBlank(" bob ") = true
* </pre>
*
* @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);
}
}

20
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;
}
}

151
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";
/**
* <p>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.</p>
*
* <pre>Validate.isTrue(i &gt; 0.0, "The value must be greater than zero: &#37;d", i);</pre>
*
* <p>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.</p>
*
* @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)));
}
}
/**
* <p>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.</p>
*
* <pre>Validate.isTrue(d &gt; 0.0, "The value must be greater than zero: &#37;s", d);</pre>
*
* <p>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.</p>
*
* @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)));
}
}
/**
* <p>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.</p>
*
* <pre>
* Validate.isTrue(i &gt;= min &amp;&amp; i &lt;= max, "The value must be between &#37;d and &#37;d", min, max);
* Validate.isTrue(myObject.isOk(), "The object is not okay");</pre>
*
* @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));
}
}
/**
* <p>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.</p>
*
* <pre>
* Validate.isTrue(i &gt; 0);
* Validate.isTrue(myObject.isOk());</pre>
*
* <p>The message of the exception is &quot;The validated expression is
* false&quot;.</p>
*
* @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);
}
}
/**
* <p>Validate that the specified argument is not {@code null};
* otherwise throwing an exception.
*
* <pre>Validate.notNull(myObject, "The object must not be null");</pre>
*
* <p>The message of the exception is &quot;The validated object is
* null&quot;.</p>
*
* @param <T> 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> T notNull(final T object) {
return notNull(object, DEFAULT_IS_NULL_EX_MESSAGE);
}
/**
* <p>Validate that the specified argument is not {@code null};
* otherwise throwing an exception with the specified message.
*
* <pre>Validate.notNull(myObject, "The object must not be null");</pre>
*
* @param <T> 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> T notNull(final T object, final String message, final Object... values) {
return Objects.requireNonNull(object, () -> String.format(message, values));
}
}

25
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);
}
}

38
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<CellData> cellDataList = new ArrayList<CellData>();
if (cell != null) {
List<CellData<?>> cellDataList = new ArrayList<>();
if (cellData != null) {
cellDataList.add(cellData);
}
afterCellDispose(writeContext, cellDataList, cell, head, relativeRowIndex, isHead);
}
public static void afterCellDispose(WriteContext writeContext, List<CellData> cellDataList, Cell cell, Head head,
public static void afterCellDispose(WriteContext writeContext, List<CellData<?>> cellDataList, Cell cell, Head head,
Integer relativeRowIndex, Boolean isHead) {
List<WriteHandler> 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);
}
}

7
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

10
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);

4
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");
}

4
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");
}

59
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();

50
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<Integer, Field> sortedAllFiledMap = new TreeMap<Integer, Field>();
Map<Integer, Field> 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<Integer, ?>)oneRowData), row, relativeRowIndex);
} else {
addJavaObjectToExcel(oneRowData, row, relativeRowIndex, sortedAllFiledMap);
}
WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE);
}
private void addBasicTypeToExcel(List<Object> oneRowData, Row row, int relativeRowIndex) {
if (CollectionUtils.isEmpty(oneRowData)) {
private void addBasicTypeToExcel(RowData oneRowData, Row row, int relativeRowIndex) {
if (oneRowData.isEmpty()) {
return;
}
Map<Integer, Head> headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
@ -102,14 +106,15 @@ public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
}
}
private void doAddBasicTypeToExcel(List<Object> 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<Integer, ExcelContentProperty> 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);
}

40
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<AnalysisCell> 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<AnalysisCell> 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<CellData> cellDataList = new ArrayList<CellData>();
List<CellData<?>> 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<AnalysisCell, CellStyle> 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;

4
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<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
List<CellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
}
}

6
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,

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save