diff --git a/README.md b/README.md
index fd5c5a2f..1251ebd2 100644
--- a/README.md
+++ b/README.md
@@ -62,16 +62,19 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja
DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java](/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java)
```java
/**
- * 文件下载
+ * 文件下载(失败了会返回一个有部分数据的Excel)
*
1. 创建excel对应的实体对象 参照{@link DownloadData}
*
2. 设置返回的 参数
*
3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大
*/
@GetMapping("download")
public void download(HttpServletResponse response) throws IOException {
+ // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
- response.setHeader("Content-disposition", "attachment;filename=demo.xlsx");
+ // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
+ String fileName = URLEncoder.encode("测试", "UTF-8");
+ response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());
}
@@ -84,7 +87,7 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja
@PostMapping("upload")
@ResponseBody
public String upload(MultipartFile file) throws IOException {
- EasyExcel.read(file.getInputStream(), UploadData.class, new UploadDataListener()).sheet().doRead();
+ EasyExcel.read(file.getInputStream(), UploadData.class, new UploadDataListener(uploadDAO)).sheet().doRead();
return "success";
}
```
diff --git a/img/readme/quickstart/fill/complexFill.png b/img/readme/quickstart/fill/complexFill.png
deleted file mode 100644
index d37bb0f9..00000000
Binary files a/img/readme/quickstart/fill/complexFill.png and /dev/null differ
diff --git a/img/readme/quickstart/fill/complexFillTemplate.png b/img/readme/quickstart/fill/complexFillTemplate.png
deleted file mode 100644
index 14e26b95..00000000
Binary files a/img/readme/quickstart/fill/complexFillTemplate.png and /dev/null differ
diff --git a/img/readme/quickstart/fill/complexFillWithTable.png b/img/readme/quickstart/fill/complexFillWithTable.png
deleted file mode 100644
index c1075201..00000000
Binary files a/img/readme/quickstart/fill/complexFillWithTable.png and /dev/null differ
diff --git a/img/readme/quickstart/fill/complexFillWithTableTemplate.png b/img/readme/quickstart/fill/complexFillWithTableTemplate.png
deleted file mode 100644
index 902cd0da..00000000
Binary files a/img/readme/quickstart/fill/complexFillWithTableTemplate.png and /dev/null differ
diff --git a/img/readme/quickstart/fill/horizontalFill.png b/img/readme/quickstart/fill/horizontalFill.png
deleted file mode 100644
index 10f90cd7..00000000
Binary files a/img/readme/quickstart/fill/horizontalFill.png and /dev/null differ
diff --git a/img/readme/quickstart/fill/horizontalFillTemplate.png b/img/readme/quickstart/fill/horizontalFillTemplate.png
deleted file mode 100644
index 462b86eb..00000000
Binary files a/img/readme/quickstart/fill/horizontalFillTemplate.png and /dev/null differ
diff --git a/img/readme/quickstart/fill/listFill.png b/img/readme/quickstart/fill/listFill.png
deleted file mode 100644
index 3baca5a8..00000000
Binary files a/img/readme/quickstart/fill/listFill.png and /dev/null differ
diff --git a/img/readme/quickstart/fill/listFillTemplate.png b/img/readme/quickstart/fill/listFillTemplate.png
deleted file mode 100644
index 010c8c16..00000000
Binary files a/img/readme/quickstart/fill/listFillTemplate.png and /dev/null differ
diff --git a/img/readme/quickstart/fill/simpleFill.png b/img/readme/quickstart/fill/simpleFill.png
deleted file mode 100644
index 4f575628..00000000
Binary files a/img/readme/quickstart/fill/simpleFill.png and /dev/null differ
diff --git a/img/readme/quickstart/fill/simpleFillTemplate.png b/img/readme/quickstart/fill/simpleFillTemplate.png
deleted file mode 100644
index 97a9119d..00000000
Binary files a/img/readme/quickstart/fill/simpleFillTemplate.png and /dev/null differ
diff --git a/img/readme/quickstart/read/demo.png b/img/readme/quickstart/read/demo.png
deleted file mode 100644
index 8bd14139..00000000
Binary files a/img/readme/quickstart/read/demo.png and /dev/null differ
diff --git a/img/readme/quickstart/write/complexHeadWrite.png b/img/readme/quickstart/write/complexHeadWrite.png
deleted file mode 100644
index 995ffc3c..00000000
Binary files a/img/readme/quickstart/write/complexHeadWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/converterWrite.png b/img/readme/quickstart/write/converterWrite.png
deleted file mode 100644
index 5c9f2898..00000000
Binary files a/img/readme/quickstart/write/converterWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/customHandlerWrite.png b/img/readme/quickstart/write/customHandlerWrite.png
deleted file mode 100644
index 41916c3f..00000000
Binary files a/img/readme/quickstart/write/customHandlerWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/dynamicHeadWrite.png b/img/readme/quickstart/write/dynamicHeadWrite.png
deleted file mode 100644
index 3b25ad72..00000000
Binary files a/img/readme/quickstart/write/dynamicHeadWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/imageWrite.png b/img/readme/quickstart/write/imageWrite.png
deleted file mode 100644
index c6a0c67a..00000000
Binary files a/img/readme/quickstart/write/imageWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/indexWrite.png b/img/readme/quickstart/write/indexWrite.png
deleted file mode 100644
index 8dbec177..00000000
Binary files a/img/readme/quickstart/write/indexWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/longestMatchColumnWidthWrite.png b/img/readme/quickstart/write/longestMatchColumnWidthWrite.png
deleted file mode 100644
index c8a06049..00000000
Binary files a/img/readme/quickstart/write/longestMatchColumnWidthWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/mergeWrite.png b/img/readme/quickstart/write/mergeWrite.png
deleted file mode 100644
index b631e59b..00000000
Binary files a/img/readme/quickstart/write/mergeWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/repeatedWrite.png b/img/readme/quickstart/write/repeatedWrite.png
deleted file mode 100644
index fb204a4b..00000000
Binary files a/img/readme/quickstart/write/repeatedWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/simpleWrite.png b/img/readme/quickstart/write/simpleWrite.png
deleted file mode 100644
index e5924b19..00000000
Binary files a/img/readme/quickstart/write/simpleWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/styleWrite.png b/img/readme/quickstart/write/styleWrite.png
deleted file mode 100644
index 356c3a7f..00000000
Binary files a/img/readme/quickstart/write/styleWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/tableWrite.png b/img/readme/quickstart/write/tableWrite.png
deleted file mode 100644
index 0006a9ea..00000000
Binary files a/img/readme/quickstart/write/tableWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/templateWrite.png b/img/readme/quickstart/write/templateWrite.png
deleted file mode 100644
index 75f7cb16..00000000
Binary files a/img/readme/quickstart/write/templateWrite.png and /dev/null differ
diff --git a/img/readme/quickstart/write/widthAndHeightWrite.png b/img/readme/quickstart/write/widthAndHeightWrite.png
deleted file mode 100644
index d59d8972..00000000
Binary files a/img/readme/quickstart/write/widthAndHeightWrite.png and /dev/null differ
diff --git a/img/readme/wechat.png b/img/readme/wechat.png
deleted file mode 100644
index b8057604..00000000
Binary files a/img/readme/wechat.png and /dev/null differ
diff --git a/pom.xml b/pom.xml
index a6183490..7dad24da 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.alibaba
easyexcel
- 2.1.0-beta4
+ 2.1.1
jar
easyexcel
diff --git a/src/main/java/com/alibaba/excel/ExcelReader.java b/src/main/java/com/alibaba/excel/ExcelReader.java
index 0887e325..07a373b7 100644
--- a/src/main/java/com/alibaba/excel/ExcelReader.java
+++ b/src/main/java/com/alibaba/excel/ExcelReader.java
@@ -14,7 +14,6 @@ import com.alibaba.excel.analysis.ExcelReadExecutor;
import com.alibaba.excel.cache.MapCache;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
-import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.parameter.AnalysisParam;
import com.alibaba.excel.read.listener.ReadListener;
@@ -35,8 +34,6 @@ public class ExcelReader {
*/
private ExcelAnalyser excelAnalyser;
- private boolean finished = false;
-
/**
* Create new reader
*
@@ -160,7 +157,6 @@ public class ExcelReader {
* Parse all sheet content by default
*/
public void readAll() {
- checkFinished();
excelAnalyser.analysis(null, Boolean.TRUE);
}
@@ -181,7 +177,6 @@ public class ExcelReader {
* @return
*/
public ExcelReader read(List readSheetList) {
- checkFinished();
excelAnalyser.analysis(readSheetList, Boolean.FALSE);
return this;
}
@@ -231,7 +226,6 @@ public class ExcelReader {
* @return
*/
public AnalysisContext analysisContext() {
- checkFinished();
return excelAnalyser.analysisContext();
}
@@ -241,7 +235,6 @@ public class ExcelReader {
* @return
*/
public ExcelReadExecutor excelExecutor() {
- checkFinished();
return excelAnalyser.excelExecutor();
}
@@ -281,10 +274,6 @@ public class ExcelReader {
* Complete the entire read file.Release the cache and close stream.
*/
public void finish() {
- if (finished) {
- return;
- }
- finished = true;
excelAnalyser.finish();
}
@@ -294,19 +283,11 @@ public class ExcelReader {
*/
@Override
protected void finalize() {
- if (finished) {
- return;
- }
try {
- excelAnalyser.finish();
+ finish();
} catch (Throwable e) {
LOGGER.warn("Destroy object failed", e);
}
}
- private void checkFinished() {
- if (finished) {
- throw new ExcelAnalysisException("Can not use a finished reader.");
- }
- }
}
diff --git a/src/main/java/com/alibaba/excel/ExcelWriter.java b/src/main/java/com/alibaba/excel/ExcelWriter.java
index 65a99fe5..a0b4795b 100644
--- a/src/main/java/com/alibaba/excel/ExcelWriter.java
+++ b/src/main/java/com/alibaba/excel/ExcelWriter.java
@@ -5,6 +5,9 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
@@ -31,6 +34,8 @@ import com.alibaba.excel.write.metadata.fill.FillConfig;
* @author jipengfei
*/
public class ExcelWriter {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ExcelWriter.class);
+
private ExcelBuilder excelBuilder;
/**
@@ -320,7 +325,20 @@ public class ExcelWriter {
* Close IO
*/
public void finish() {
- excelBuilder.finish();
+ excelBuilder.finish(false);
+ }
+
+ /**
+ * Prevents calls to {@link #finish} from freeing the cache
+ *
+ */
+ @Override
+ protected void finalize() {
+ try {
+ finish();
+ } catch (Throwable e) {
+ LOGGER.warn("Destroy object failed", e);
+ }
}
/**
diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
index 72a27e7f..f3ef9505 100644
--- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
+++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
@@ -1,13 +1,10 @@
package com.alibaba.excel.analysis;
-import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.crypt.Decryptor;
-import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.filesystem.DocumentFactoryHelper;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.IOUtils;
@@ -37,6 +34,10 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
private AnalysisContext analysisContext;
private ExcelReadExecutor excelReadExecutor;
+ /**
+ * Prevent multiple shutdowns
+ */
+ private boolean finished = false;
public ExcelAnalyserImpl(ReadWorkbook readWorkbook) {
try {
@@ -124,6 +125,10 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
@Override
public void finish() {
+ if (finished) {
+ return;
+ }
+ finished = true;
if (analysisContext == null || analysisContext.readWorkbookHolder() == null) {
return;
}
diff --git a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
index 21977a4d..e0c150cd 100644
--- a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
+++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
@@ -3,6 +3,7 @@ package com.alibaba.excel.analysis.v03;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -26,6 +27,7 @@ import com.alibaba.excel.analysis.ExcelReadExecutor;
import com.alibaba.excel.analysis.v03.handlers.BlankOrErrorRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.BofRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.FormulaRecordHandler;
+import com.alibaba.excel.analysis.v03.handlers.IndexRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.LabelRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.MissingCellDummyRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.NoteRecordHandler;
@@ -77,7 +79,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
public XlsSaxAnalyser(AnalysisContext context, POIFSFileSystem poifsFileSystem) {
this.analysisContext = context;
- this.records = new TreeMap();
+ this.records = new LinkedHashMap();
this.poifsFileSystem = poifsFileSystem;
analysisContext.readWorkbookHolder().setPoifsFileSystem(poifsFileSystem);
}
@@ -120,7 +122,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
private void init() {
lastRowNumber = 0;
lastColumnNumber = 0;
- records = new TreeMap();
+ records = new LinkedHashMap();
buildXlsRecordHandlers();
}
@@ -210,6 +212,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
recordHandlers.add(new RkRecordHandler());
recordHandlers.add(new SstRecordHandler());
recordHandlers.add(new MissingCellDummyRecordHandler());
+ recordHandlers.add(new IndexRecordHandler(analysisContext));
Collections.sort(recordHandlers);
}
diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
index 3a862942..083edbc7 100644
--- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
+++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
@@ -73,7 +73,7 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
readSheet = SheetUtils.match(readSheet, readSheetList, readAll,
context.readWorkbookHolder().getGlobalConfiguration());
if (readSheet != null) {
- if (readSheet.getSheetNo() != 0) {
+ if (readSheet.getSheetNo() != 0 && context.readSheetHolder() != null) {
// Prompt for the end of the previous form read
context.readSheetHolder().notifyAfterAllAnalysed(context);
}
diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/IndexRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/IndexRecordHandler.java
new file mode 100644
index 00000000..6837ebd6
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/IndexRecordHandler.java
@@ -0,0 +1,42 @@
+package com.alibaba.excel.analysis.v03.handlers;
+
+import org.apache.poi.hssf.record.IndexRecord;
+import org.apache.poi.hssf.record.Record;
+
+import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
+import com.alibaba.excel.context.AnalysisContext;
+
+/**
+ * Record handler
+ *
+ * @author Jiaju Zhuang
+ */
+public class IndexRecordHandler extends AbstractXlsRecordHandler {
+
+ private AnalysisContext context;
+
+ public IndexRecordHandler(AnalysisContext context) {
+ this.context = context;
+ }
+
+ @Override
+ public boolean support(Record record) {
+ return record instanceof IndexRecord;
+ }
+
+ @Override
+ public void init() {}
+
+ @Override
+ public void processRecord(Record record) {
+ if (context.readSheetHolder() == null) {
+ return;
+ }
+ context.readSheetHolder().setApproximateTotalRowNumber(((IndexRecord)record).getLastRowAdd1());
+ }
+
+ @Override
+ public int getOrder() {
+ return 1;
+ }
+}
diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java
index ea63409b..b94483f4 100644
--- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java
+++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java
@@ -10,7 +10,7 @@ import com.alibaba.excel.context.AnalysisContext;
/**
* Cell Handler
- *
+ *
* @author jipengfei
*/
public class CountRowCellHandler implements XlsxCellHandler {
@@ -31,7 +31,7 @@ public class CountRowCellHandler implements XlsxCellHandler {
String d = attributes.getValue(DIMENSION_REF);
String totalStr = d.substring(d.indexOf(":") + 1, d.length());
String c = totalStr.toUpperCase().replaceAll("[A-Z]", "");
- analysisContext.readSheetHolder().setTotal(Integer.parseInt(c));
+ analysisContext.readSheetHolder().setApproximateTotalRowNumber(Integer.parseInt(c));
}
@Override
diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
index 0d44a95b..e0b9c413 100644
--- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
+++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
@@ -9,9 +9,9 @@ import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TYPE_TAG;
import java.math.BigDecimal;
import java.util.Deque;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
-import java.util.TreeMap;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.xssf.model.StylesTable;
@@ -37,7 +37,7 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
private final AnalysisContext analysisContext;
private Deque currentTagDeque = new LinkedList();
private int curCol;
- private Map curRowContent = new TreeMap();
+ private Map curRowContent = new LinkedHashMap();
private CellData currentCellData;
private StringBuilder dataStringBuilder;
private StringBuilder formulaStringBuilder;
@@ -54,7 +54,7 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
@Override
public void clearResult() {
- curRowContent = new TreeMap();
+ curRowContent = new LinkedHashMap();
}
@Override
diff --git a/src/main/java/com/alibaba/excel/context/WriteContext.java b/src/main/java/com/alibaba/excel/context/WriteContext.java
index c6e85c94..0a59e1d0 100644
--- a/src/main/java/com/alibaba/excel/context/WriteContext.java
+++ b/src/main/java/com/alibaba/excel/context/WriteContext.java
@@ -66,9 +66,10 @@ public interface WriteContext {
/**
* close
+ *
+ * @param onException
*/
- void finish();
-
+ void finish(boolean onException);
/**
* Current sheet
diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java
index fcb276cb..84205024 100644
--- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java
+++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java
@@ -65,6 +65,10 @@ public class WriteContextImpl implements WriteContext {
* Configuration of currently operated cell
*/
private WriteHolder currentWriteHolder;
+ /**
+ * Prevent multiple shutdowns
+ */
+ private boolean finished = false;
public WriteContextImpl(WriteWorkbook writeWorkbook) {
if (writeWorkbook == null) {
@@ -249,23 +253,36 @@ public class WriteContextImpl implements WriteContext {
}
@Override
- public void finish() {
+ public void finish(boolean onException) {
+ if (finished) {
+ return;
+ }
+ finished = true;
WriteHandlerUtils.afterWorkbookDispose(this);
if (writeWorkbookHolder == null) {
return;
}
Throwable throwable = null;
-
boolean isOutputStreamEncrypt = false;
- try {
- isOutputStreamEncrypt = doOutputStreamEncrypt07();
- } catch (Throwable t) {
- throwable = t;
+ // Determine if you need to write excel
+ boolean writeExcel = !onException;
+ if (writeWorkbookHolder.getWriteExcelOnException()) {
+ writeExcel = Boolean.TRUE;
+ }
+ // No data is written if an exception is thrown
+ if (writeExcel) {
+ try {
+ isOutputStreamEncrypt = doOutputStreamEncrypt07();
+ } catch (Throwable t) {
+ throwable = t;
+ }
}
if (!isOutputStreamEncrypt) {
try {
- writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream());
+ if (writeExcel) {
+ writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream());
+ }
writeWorkbookHolder.getWorkbook().close();
} catch (Throwable t) {
throwable = t;
@@ -289,7 +306,7 @@ public class WriteContextImpl implements WriteContext {
throwable = t;
}
- if (!isOutputStreamEncrypt) {
+ if (writeExcel && !isOutputStreamEncrypt) {
try {
doFileEncrypt07();
} catch (Throwable t) {
diff --git a/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java b/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
index e53c1f85..77e8b592 100644
--- a/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
+++ b/src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
@@ -37,6 +37,7 @@ import com.alibaba.excel.converters.string.StringBooleanConverter;
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;
/**
* Load default handler
@@ -71,6 +72,7 @@ public class DefaultConverterLoader {
putWriteConverter(new InputStreamImageConverter());
putWriteConverter(new ByteArrayImageConverter());
putWriteConverter(new BoxingByteArrayImageConverter());
+ putWriteConverter(new UrlImageConverter());
return defaultWriteConverter;
}
diff --git a/src/main/java/com/alibaba/excel/converters/url/UrlImageConverter.java b/src/main/java/com/alibaba/excel/converters/url/UrlImageConverter.java
new file mode 100644
index 00000000..b622d66d
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/converters/url/UrlImageConverter.java
@@ -0,0 +1,52 @@
+package com.alibaba.excel.converters.url;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+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.IoUtils;
+
+/**
+ * Url and image converter
+ *
+ * @since 2.1.1
+ * @author Jiaju Zhuang
+ */
+public class UrlImageConverter implements Converter {
+ @Override
+ public Class supportJavaTypeKey() {
+ return URL.class;
+ }
+
+ @Override
+ public CellDataTypeEnum supportExcelTypeKey() {
+ return CellDataTypeEnum.IMAGE;
+ }
+
+ @Override
+ 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,
+ GlobalConfiguration globalConfiguration) throws IOException {
+ InputStream inputStream = null;
+ try {
+ inputStream = value.openStream();
+ byte[] bytes = IoUtils.toByteArray(inputStream);
+ return new CellData(bytes);
+ } finally {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ }
+ }
+
+}
diff --git a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java
index 89bca753..176bd798 100644
--- a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java
+++ b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java
@@ -16,7 +16,7 @@ public abstract class AnalysisEventListener implements ReadListener {
@Override
public void invokeHead(Map headMap, AnalysisContext context) {
- invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context.currentReadHolder()), context);
+ invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context);
}
/**
diff --git a/src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java b/src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java
index 2ffdde5f..5198c20f 100644
--- a/src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java
+++ b/src/main/java/com/alibaba/excel/exception/ExcelDataConvertException.java
@@ -1,5 +1,6 @@
package com.alibaba.excel.exception;
+import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
@@ -17,6 +18,10 @@ public class ExcelDataConvertException extends RuntimeException {
* NotNull.
*/
private Integer columnIndex;
+ /**
+ * NotNull.
+ */
+ private CellData cellData;
/**
* Nullable.Only when the header is configured and when the class header is used is not null.
*
@@ -24,34 +29,24 @@ public class ExcelDataConvertException extends RuntimeException {
*/
private ExcelContentProperty excelContentProperty;
- public ExcelDataConvertException(String message) {
- super(message);
- }
-
- public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, ExcelContentProperty excelContentProperty,
- String message) {
+ public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, CellData cellData,
+ ExcelContentProperty excelContentProperty, String message) {
super(message);
this.rowIndex = rowIndex;
this.columnIndex = columnIndex;
+ this.cellData = cellData;
this.excelContentProperty = excelContentProperty;
}
- public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, ExcelContentProperty excelContentProperty,
- String message, Throwable cause) {
+ public ExcelDataConvertException(Integer rowIndex, Integer columnIndex, CellData cellData,
+ ExcelContentProperty excelContentProperty, String message, Throwable cause) {
super(message, cause);
this.rowIndex = rowIndex;
this.columnIndex = columnIndex;
+ this.cellData = cellData;
this.excelContentProperty = excelContentProperty;
}
- public ExcelDataConvertException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public ExcelDataConvertException(Throwable cause) {
- super(cause);
- }
-
public Integer getRowIndex() {
return rowIndex;
}
@@ -75,4 +70,12 @@ public class ExcelDataConvertException extends RuntimeException {
public void setExcelContentProperty(ExcelContentProperty excelContentProperty) {
this.excelContentProperty = excelContentProperty;
}
+
+ public CellData getCellData() {
+ return cellData;
+ }
+
+ public void setCellData(CellData cellData) {
+ this.cellData = cellData;
+ }
}
diff --git a/src/main/java/com/alibaba/excel/metadata/CellData.java b/src/main/java/com/alibaba/excel/metadata/CellData.java
index a6b7af58..7cd5496e 100644
--- a/src/main/java/com/alibaba/excel/metadata/CellData.java
+++ b/src/main/java/com/alibaba/excel/metadata/CellData.java
@@ -229,18 +229,21 @@ public class CellData {
@Override
public String toString() {
if (type == null) {
- return "empty";
+ return StringUtils.EMPTY;
}
switch (type) {
case NUMBER:
return numberValue.toString();
case BOOLEAN:
return booleanValue.toString();
+ case DIRECT_STRING:
case STRING:
case ERROR:
return stringValue;
+ case IMAGE:
+ return "image[" + imageValue.length + "]";
default:
- return "empty";
+ return StringUtils.EMPTY;
}
}
diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
index 9d6a5442..782f635a 100644
--- a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
+++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
@@ -24,6 +24,7 @@ import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.Holder;
+import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder;
@@ -119,51 +120,10 @@ public class ExcelHeadProperty {
if (headClazz == null) {
return;
}
- List fieldList = new ArrayList();
- Class tempClass = headClazz;
- // When the parent class is null, it indicates that the parent class (Object class) has reached the top
- // level.
- while (tempClass != null) {
- Collections.addAll(fieldList, tempClass.getDeclaredFields());
- // Get the parent class and give it to yourself
- tempClass = tempClass.getSuperclass();
- }
-
- ExcelIgnoreUnannotated excelIgnoreUnannotated =
- (ExcelIgnoreUnannotated)headClazz.getAnnotation(ExcelIgnoreUnannotated.class);
- // Screening of field
+ // Declared fields
List defaultFieldList = new ArrayList();
Map customFiledMap = new TreeMap();
- for (Field field : fieldList) {
- ExcelIgnore excelIgnore = field.getAnnotation(ExcelIgnore.class);
- if (excelIgnore != null) {
- ignoreMap.put(field.getName(), field);
- continue;
- }
- ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
- boolean noExcelProperty = excelProperty == null
- && ((convertAllFiled != null && !convertAllFiled) || excelIgnoreUnannotated != null);
- if (noExcelProperty) {
- ignoreMap.put(field.getName(), field);
- continue;
- }
- boolean isStaticFinalOrTransient =
- (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers()))
- || Modifier.isTransient(field.getModifiers());
- if (excelProperty == null && isStaticFinalOrTransient) {
- ignoreMap.put(field.getName(), field);
- continue;
- }
- if (excelProperty == null || excelProperty.index() < 0) {
- defaultFieldList.add(field);
- continue;
- }
- if (customFiledMap.containsKey(excelProperty.index())) {
- throw new ExcelGenerateException("The index of '" + customFiledMap.get(excelProperty.index()).getName()
- + "' and '" + field.getName() + "' must be inconsistent");
- }
- customFiledMap.put(excelProperty.index(), field);
- }
+ ClassUtils.declaredFields(headClazz, defaultFieldList, customFiledMap, ignoreMap, convertAllFiled);
int index = 0;
for (Field field : defaultFieldList) {
diff --git a/src/main/java/com/alibaba/excel/read/builder/ExcelReaderSheetBuilder.java b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderSheetBuilder.java
index af3b05e1..d494e233 100644
--- a/src/main/java/com/alibaba/excel/read/builder/ExcelReaderSheetBuilder.java
+++ b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderSheetBuilder.java
@@ -166,7 +166,7 @@ public class ExcelReaderSheetBuilder {
*
* @return
*/
- public List