diff --git a/quickstart.md b/quickstart.md
index dd4f3d6..9ca53df 100644
--- a/quickstart.md
+++ b/quickstart.md
@@ -1,13 +1,15 @@
# easyexcel核心功能
## 目录
### 前言
-#### 关于@Data
-读写的对象都用到了[Lombok](https://www.projectlombok.org/),他会自动生成`get`,`set` ,如果不需要自己创建对象并生成`get`,`set` 。
#### 以下功能目前不支持
* 单个文件的并发写入、读取
* 读取图片
* 宏
* csv读取(这个后续可能会考虑)
+#### 常见问题
+* 关于@Data,读写的对象都用到了[Lombok](https://www.projectlombok.org/),他会自动生成`get`,`set` ,如果不需要的话,自己创建对象并生成`get`,`set` 。
+* 如果在读的时候`Listener`里面需要使用spring的`@Autowired`,给`Listener`创建成员变量,然后在构造方法里面传进去。而别必须不让spring管理`Listener`,每次读取都要`new`一个。
+* 如果用`String`去接收数字,出现小数点等情况,这个是BUG,但是很难修复,后续版本会修复这个问题。目前请使用`@NumberFormat`直接,里面的参数就是调用了java自带的`NumberFormat.format`方法,不知道怎么入参的可以自己网上查询。
#### 详细参数介绍
有些参数不知道怎么用,或者有些功能不知道用什么参数,参照:[详细参数介绍](/docs/API.md)
#### 开源项目不容易,如果觉得本项目对您的工作还是有帮助的话,请在右上角帮忙点个★Star。
@@ -28,7 +30,7 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja
* [最简单的写](#simpleWrite)
* [指定写入的列](#indexWrite)
* [复杂头写入](#complexHeadWrite)
-* [重复多次写入](#repeatedWrite)
+* [重复多次写入(包括不同sheet)](#repeatedWrite)
* [日期、数字或者自定义格式转换](#converterWrite)
* [图片导出](#imageWrite)
* [根据模板写入](#templateWrite)
@@ -165,12 +167,16 @@ public class IndexOrNameData {
```java
/**
* 读多个sheet,这里注意一个sheet不能读取多次,多次读取需要重新读取文件
- *
1. 创建excel对应的实体对象 参照{@link DemoData}
- *
2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
- *
3. 直接读即可
+ *
+ * 1. 创建excel对应的实体对象 参照{@link DemoData}
+ *
+ * 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
+ *
+ * 3. 直接读即可
*/
@Test
public void repeatedRead() {
+ // 方法1 如果 sheet1 sheet2 都是同一数据 监听器和头 都写到最外层
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build();
ReadSheet readSheet1 = EasyExcel.readSheet(0).build();
@@ -179,6 +185,17 @@ public class IndexOrNameData {
excelReader.read(readSheet2);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
+
+ // 方法2 如果 sheet1 sheet2 数据不一致的话
+ fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
+ excelReader = EasyExcel.read(fileName).build();
+ // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
+ readSheet1 = EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
+ readSheet2 = EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
+ excelReader.read(readSheet1);
+ excelReader.read(readSheet2);
+ // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
+ excelReader.finish();
}
```
@@ -572,7 +589,7 @@ public class ComplexHeadData {
参照:[对象](#simpleWriteObject)
##### 代码
```java
- /**
+ /**
* 重复多次写入
*
* 1. 创建excel对应的实体对象 参照{@link ComplexHeadData}
@@ -583,6 +600,7 @@ public class ComplexHeadData {
*/
@Test
public void repeatedWrite() {
+ // 方法1 如果写到同一个sheet
String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去读
ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
@@ -596,6 +614,36 @@ public class ComplexHeadData {
}
/// 千万别忘记finish 会帮忙关闭流
excelWriter.finish();
+
+ // 方法2 如果写到不同的sheet 同一个对象
+ fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
+ // 这里 指定文件
+ excelWriter = EasyExcel.write(fileName, DemoData.class).build();
+ // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
+ for (int i = 0; i < 5; i++) {
+ // 每次都要创建writeSheet 这里注意必须指定sheetNo
+ writeSheet = EasyExcel.writerSheet(i, "模板").build();
+ // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
+ List data = data();
+ excelWriter.write(data, writeSheet);
+ }
+ /// 千万别忘记finish 会帮忙关闭流
+ excelWriter.finish();
+
+ // 方法3 如果写到不同的sheet 不同的对象
+ fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
+ // 这里 指定文件
+ excelWriter = EasyExcel.write(fileName).build();
+ // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
+ for (int i = 0; i < 5; i++) {
+ // 每次都要创建writeSheet 这里注意必须指定sheetNo。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变
+ writeSheet = EasyExcel.writerSheet(i, "模板").head(DemoData.class).build();
+ // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
+ List data = data();
+ excelWriter.write(data, writeSheet);
+ }
+ /// 千万别忘记finish 会帮忙关闭流
+ excelWriter.finish();
}
```
@@ -867,18 +915,19 @@ public class WidthAndHeightData {
*
* 思路是这样子的,先创建List头格式的sheet仅仅写入头,然后通过table 不写入头的方式 去写入数据
*
- * 1. 创建excel对应的实体对象 参照{@link DemoData}
- *
2. 然后写入table即可
+ *
+ * 1. 创建excel对应的实体对象 参照{@link DemoData}
+ *
+ * 2. 然后写入table即可
*/
@Test
public void dynamicHeadWrite() {
String fileName = TestFileUtil.getPath() + "dynamicHeadWrite" + System.currentTimeMillis() + ".xlsx";
- // write的时候 不传入 class 在table的时候传入
EasyExcel.write(fileName)
// 这里放入动态头
.head(head()).sheet("模板")
- // table的时候 传入class 并且设置needHead =false
- .table().head(DemoData.class).needHead(Boolean.FALSE).doWrite(data());
+ // 当然这里数据也可以用 List> 去传入
+ .doWrite(data());
}
private List> head() {
@@ -1056,10 +1105,12 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja
*/
@GetMapping("download")
public void download(HttpServletResponse response) throws IOException {
- // 这里注意 有同学反应下载的文件名不对。这个时候 请别使用swagger 他会影像
+ // 这里注意 有同学反应下载的文件名不对。这个时候 请别使用swagger 他会有影响
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());
}
```
diff --git a/src/main/java/com/alibaba/excel/ExcelWriter.java b/src/main/java/com/alibaba/excel/ExcelWriter.java
index d32d7ee..6ee5b6f 100644
--- a/src/main/java/com/alibaba/excel/ExcelWriter.java
+++ b/src/main/java/com/alibaba/excel/ExcelWriter.java
@@ -5,6 +5,7 @@ import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
+import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table;
import com.alibaba.excel.parameter.GenerateParam;
@@ -309,4 +310,12 @@ public class ExcelWriter {
excelBuilder.finish();
}
+ /**
+ * The context of the entire writing process
+ *
+ * @return
+ */
+ public WriteContext writeContext() {
+ return excelBuilder.writeContext();
+ }
}
diff --git a/src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java b/src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java
new file mode 100644
index 0000000..62d5517
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java
@@ -0,0 +1,60 @@
+package com.alibaba.excel.analysis.v03;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder;
+import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
+import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
+import org.apache.poi.hssf.eventusermodel.HSSFListener;
+import org.apache.poi.hssf.eventusermodel.HSSFRequest;
+import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;
+import org.apache.poi.hssf.record.BoundSheetRecord;
+import org.apache.poi.hssf.record.Record;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+
+import com.alibaba.excel.analysis.v03.handlers.BofRecordHandler;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.exception.ExcelAnalysisException;
+import com.alibaba.excel.read.metadata.ReadSheet;
+
+/**
+ * In some cases, you need to know the number of sheets in advance and only read the file once in advance.
+ *
+ * @author Jiaju Zhuang
+ */
+public class XlsListSheetListener implements HSSFListener {
+ private POIFSFileSystem poifsFileSystem;
+ private List sheetList;
+ private XlsRecordHandler bofRecordHandler;
+
+ public XlsListSheetListener(AnalysisContext analysisContext, POIFSFileSystem poifsFileSystem) {
+ this.poifsFileSystem = poifsFileSystem;
+ sheetList = new ArrayList();
+ bofRecordHandler = new BofRecordHandler(analysisContext, sheetList, false);
+ bofRecordHandler.init();
+ }
+
+ @Override
+ public void processRecord(Record record) {
+ bofRecordHandler.processRecord(record);
+ }
+
+ public List getSheetList() {
+ MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);
+ HSSFListener formatListener = new FormatTrackingHSSFListener(listener);
+ HSSFEventFactory factory = new HSSFEventFactory();
+ HSSFRequest request = new HSSFRequest();
+ EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener =
+ new EventWorkbookBuilder.SheetRecordCollectingListener(formatListener);
+ request.addListenerForAllRecords(workbookBuildingListener);
+
+ try {
+ factory.processWorkbookEvents(request, poifsFileSystem);
+ } catch (IOException e) {
+ throw new ExcelAnalysisException(e);
+ }
+ return sheetList;
+ }
+}
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 ddabd8c..19aa256 100644
--- a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
+++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
@@ -2,6 +2,7 @@ package com.alibaba.excel.analysis.v03;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -19,6 +20,8 @@ import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.ExcelExecutor;
import com.alibaba.excel.analysis.v03.handlers.BlankOrErrorRecordHandler;
@@ -55,6 +58,8 @@ import com.alibaba.excel.util.CollectionUtils;
* @author jipengfei
*/
public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
+ private static final Logger LOGGER = LoggerFactory.getLogger(XlsSaxAnalyser.class);
+
private boolean outputFormulaValues = true;
private POIFSFileSystem poifsFileSystem;
private int lastRowNumber;
@@ -66,12 +71,12 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
private EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener;
private FormatTrackingHSSFListener formatListener;
private Map records;
- private List sheets = new ArrayList();
+ private List sheets;
private HSSFWorkbook stubWorkbook;
private List recordHandlers = new ArrayList();
private AnalysisContext analysisContext;
- public XlsSaxAnalyser(AnalysisContext context, POIFSFileSystem poifsFileSystem) throws IOException {
+ public XlsSaxAnalyser(AnalysisContext context, POIFSFileSystem poifsFileSystem) {
this.analysisContext = context;
this.records = new TreeMap();
this.poifsFileSystem = poifsFileSystem;
@@ -80,6 +85,11 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
@Override
public List sheetList() {
+ if (sheets == null) {
+ LOGGER.warn("Getting the 'sheetList' before reading will cause the file to be read twice.");
+ XlsListSheetListener xlsListSheetListener = new XlsListSheetListener(analysisContext, poifsFileSystem);
+ sheets = xlsListSheetListener.getSheetList();
+ }
return sheets;
}
@@ -92,9 +102,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
if (workbookBuildingListener != null && stubWorkbook == null) {
stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook();
}
-
init();
-
HSSFEventFactory factory = new HSSFEventFactory();
HSSFRequest request = new HSSFRequest();
if (outputFormulaValues) {
@@ -102,7 +110,6 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
} else {
request.addListenerForAllRecords(workbookBuildingListener);
}
-
try {
factory.processWorkbookEvents(request, poifsFileSystem);
} catch (IOException e) {
@@ -118,7 +125,6 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
lastRowNumber = 0;
lastColumnNumber = 0;
records = new TreeMap();
- sheets = new ArrayList();
buildXlsRecordHandlers();
}
@@ -199,7 +205,13 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
private void buildXlsRecordHandlers() {
if (CollectionUtils.isEmpty(recordHandlers)) {
recordHandlers.add(new BlankOrErrorRecordHandler());
- recordHandlers.add(new BofRecordHandler(workbookBuildingListener, analysisContext, sheets));
+ // The table has been counted and there are no duplicate statistics
+ if (sheets == null) {
+ sheets = new ArrayList();
+ recordHandlers.add(new BofRecordHandler(analysisContext, sheets, false));
+ } else {
+ recordHandlers.add(new BofRecordHandler(analysisContext, sheets, true));
+ }
recordHandlers.add(new FormulaRecordHandler(stubWorkbook, formatListener));
recordHandlers.add(new LabelRecordHandler());
recordHandlers.add(new NoteRecordHandler());
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 324d3e3..d6a93a5 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
@@ -3,7 +3,6 @@ package com.alibaba.excel.analysis.v03.handlers;
import java.util.ArrayList;
import java.util.List;
-import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.Record;
@@ -23,13 +22,12 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
private int sheetIndex;
private List sheets;
private AnalysisContext context;
- private EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener;
+ private boolean alreadyInit;
- public BofRecordHandler(EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener,
- AnalysisContext context, List sheets) {
+ public BofRecordHandler(AnalysisContext context, List sheets, boolean alreadyInit) {
this.context = context;
- this.workbookBuildingListener = workbookBuildingListener;
this.sheets = sheets;
+ this.alreadyInit = alreadyInit;
}
@Override
@@ -47,12 +45,16 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
if (orderedBsrs == null) {
orderedBsrs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
}
- ReadSheet readSheet = new ReadSheet(sheetIndex, orderedBsrs[sheetIndex].getSheetname());
- sheets.add(readSheet);
- if (sheetIndex == context.readSheetHolder().getSheetNo()) {
- context.readWorkbookHolder().setIgnoreRecord03(Boolean.FALSE);
- } else {
- context.readWorkbookHolder().setIgnoreRecord03(Boolean.TRUE);
+ if (!alreadyInit) {
+ ReadSheet readSheet = new ReadSheet(sheetIndex, orderedBsrs[sheetIndex].getSheetname());
+ sheets.add(readSheet);
+ }
+ if (context.readSheetHolder() != null) {
+ if (sheetIndex == context.readSheetHolder().getSheetNo()) {
+ context.readWorkbookHolder().setIgnoreRecord03(Boolean.FALSE);
+ } else {
+ context.readWorkbookHolder().setIgnoreRecord03(Boolean.TRUE);
+ }
}
sheetIndex++;
}
@@ -64,7 +66,9 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
sheetIndex = 0;
orderedBsrs = null;
boundSheetRecords.clear();
- sheets.clear();
+ if (!alreadyInit) {
+ sheets.clear();
+ }
}
@Override
diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java
index 4e7041e..f9dd0d6 100644
--- a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java
+++ b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java
@@ -120,9 +120,9 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH
ReadRowHolder readRowHolder = analysisContext.readRowHolder();
readRowHolder.setCurrentRowAnalysisResult(cellDataMap);
int rowIndex = readRowHolder.getRowIndex();
- int headRowNumber = analysisContext.readSheetHolder().getHeadRowNumber();
+ int currentheadRowNumber = analysisContext.readSheetHolder().getHeadRowNumber();
- if (rowIndex >= headRowNumber) {
+ if (rowIndex >= currentheadRowNumber) {
// Now is data
for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) {
try {
@@ -135,6 +135,7 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH
throw new ExcelAnalysisException("Listen error!", exception);
}
}
+ break;
}
if (!readListener.hasNext(analysisContext)) {
throw new ExcelAnalysisStopException();
@@ -142,7 +143,7 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH
}
} else {
// Last head column
- if (headRowNumber == rowIndex + 1) {
+ if (currentheadRowNumber == rowIndex + 1) {
buildHead(analysisContext, cellDataMap);
}
@@ -158,6 +159,7 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH
throw new ExcelAnalysisException("Listen error!", exception);
}
}
+ break;
}
if (!readListener.hasNext(analysisContext)) {
throw new ExcelAnalysisStopException();
diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilder.java b/src/main/java/com/alibaba/excel/write/ExcelBuilder.java
index 0570d64..6dcf947 100644
--- a/src/main/java/com/alibaba/excel/write/ExcelBuilder.java
+++ b/src/main/java/com/alibaba/excel/write/ExcelBuilder.java
@@ -2,6 +2,7 @@ package com.alibaba.excel.write;
import java.util.List;
+import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
@@ -59,6 +60,13 @@ public interface ExcelBuilder {
@Deprecated
void merge(int firstRow, int lastRow, int firstCol, int lastCol);
+ /**
+ * Gets the written data
+ *
+ * @return
+ */
+ WriteContext writeContext();
+
/**
* Close io
*/
diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
index cedec44..2eb301a 100644
--- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
+++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
@@ -207,6 +207,11 @@ public class ExcelBuilderImpl implements ExcelBuilder {
context.writeSheetHolder().getSheet().addMergedRegion(cra);
}
+ @Override
+ public WriteContext writeContext() {
+ return context;
+ }
+
private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex, List fieldList) {
beforeRowCreate(n, relativeRowIndex);
Row row = WorkBookUtil.createRow(context.writeSheetHolder().getSheet(), n);
diff --git a/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsData.java b/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsData.java
new file mode 100644
index 0000000..73da1c3
--- /dev/null
+++ b/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsData.java
@@ -0,0 +1,11 @@
+package com.alibaba.easyexcel.test.core.multiplesheets;
+
+import lombok.Data;
+
+/**
+ * @author Jiaju Zhuang
+ */
+@Data
+public class MultipleSheetsData {
+ private String title;
+}
diff --git a/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsDataTest.java
new file mode 100644
index 0000000..579a821
--- /dev/null
+++ b/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsDataTest.java
@@ -0,0 +1,56 @@
+package com.alibaba.easyexcel.test.core.multiplesheets;
+
+import java.io.File;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+import com.alibaba.easyexcel.test.util.TestFileUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelReader;
+import com.alibaba.excel.read.metadata.ReadSheet;
+
+/**
+ *
+ * @author Jiaju Zhuang
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class MultipleSheetsDataTest {
+
+ private static File file07;
+ private static File file03;
+
+ @BeforeClass
+ public static void init() {
+ file07 = TestFileUtil.readFile("multiplesheets" + File.separator + "multiplesheets.xlsx");
+ file03 = TestFileUtil.readFile("multiplesheets" + File.separator + "multiplesheets.xls");
+ }
+
+ @Test
+ public void t01Read07() {
+ read(file07);
+ }
+
+ @Test
+ public void t02Read03() {
+ read(file03);
+ }
+
+ private void read(File file) {
+ MultipleSheetsListener multipleSheetsListener = new MultipleSheetsListener();
+ ExcelReader excelReader = EasyExcel.read(file, MultipleSheetsData.class, multipleSheetsListener).build();
+ List sheets = excelReader.excelExecutor().sheetList();
+ int count = 1;
+ for (ReadSheet readSheet : sheets) {
+ excelReader.read(readSheet);
+ Assert.assertEquals((long)multipleSheetsListener.getList().size(), (long)count);
+ count++;
+ }
+ excelReader.finish();
+ }
+
+}
diff --git a/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java b/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java
new file mode 100644
index 0000000..950f562
--- /dev/null
+++ b/src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java
@@ -0,0 +1,41 @@
+package com.alibaba.easyexcel.test.core.multiplesheets;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.alibaba.easyexcel.test.core.parameter.ParameterData;
+import com.alibaba.easyexcel.test.core.parameter.ParameterDataListener;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.alibaba.fastjson.JSON;
+
+/**
+ * @author Jiaju Zhuang
+ */
+public class MultipleSheetsListener extends AnalysisEventListener {
+ private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSheetsListener.class);
+ List list = new ArrayList();
+
+ @Override
+ public void invoke(MultipleSheetsData data, AnalysisContext context) {
+ list.add(data);
+ }
+
+ @Override
+ public void doAfterAllAnalysed(AnalysisContext context) {
+ Assert.assertEquals(list.get(0).getTitle(), "表1数据");
+ LOGGER.debug("All row:{}", JSON.toJSONString(list));
+ }
+
+ public List getList() {
+ return list;
+ }
+
+ public void setList(List list) {
+ this.list = list;
+ }
+}
diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
index b65f99e..a8e6a61 100644
--- a/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
+++ b/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
@@ -81,6 +81,7 @@ public class ReadTest {
*/
@Test
public void repeatedRead() {
+ // 方法1 如果 sheet1 sheet2 都是同一数据 监听器和头 都写到最外层
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build();
ReadSheet readSheet1 = EasyExcel.readSheet(0).build();
@@ -89,6 +90,17 @@ public class ReadTest {
excelReader.read(readSheet2);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
+
+ // 方法2 如果 sheet1 sheet2 数据不一致的话
+ fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
+ excelReader = EasyExcel.read(fileName).build();
+ // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
+ readSheet1 = EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
+ readSheet2 = EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
+ excelReader.read(readSheet1);
+ excelReader.read(readSheet2);
+ // 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
+ excelReader.finish();
}
/**
diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java
index 9d5e9f0..8fff02c 100644
--- a/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java
+++ b/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java
@@ -1,10 +1,13 @@
package com.alibaba.easyexcel.test.demo.web;
import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
@@ -33,10 +36,12 @@ public class WebTest {
*/
@GetMapping("download")
public void download(HttpServletResponse response) throws IOException {
- // 这里注意 有同学反应下载的文件名不对。这个时候 请别使用swagger 他会影像
+ // 这里注意 有同学反应下载的文件名不对。这个时候 请别使用swagger 他会有影响
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());
}
diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java
index 6636769..76c3c71 100644
--- a/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java
+++ b/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java
@@ -105,6 +105,7 @@ public class WriteTest {
*/
@Test
public void repeatedWrite() {
+ // 方法1 如果写到同一个sheet
String fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去读
ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
@@ -118,6 +119,36 @@ public class WriteTest {
}
/// 千万别忘记finish 会帮忙关闭流
excelWriter.finish();
+
+ // 方法2 如果写到不同的sheet 同一个对象
+ fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
+ // 这里 指定文件
+ excelWriter = EasyExcel.write(fileName, DemoData.class).build();
+ // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
+ for (int i = 0; i < 5; i++) {
+ // 每次都要创建writeSheet 这里注意必须指定sheetNo
+ writeSheet = EasyExcel.writerSheet(i, "模板").build();
+ // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
+ List data = data();
+ excelWriter.write(data, writeSheet);
+ }
+ /// 千万别忘记finish 会帮忙关闭流
+ excelWriter.finish();
+
+ // 方法3 如果写到不同的sheet 不同的对象
+ fileName = TestFileUtil.getPath() + "repeatedWrite" + System.currentTimeMillis() + ".xlsx";
+ // 这里 指定文件
+ excelWriter = EasyExcel.write(fileName).build();
+ // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
+ for (int i = 0; i < 5; i++) {
+ // 每次都要创建writeSheet 这里注意必须指定sheetNo。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变
+ writeSheet = EasyExcel.writerSheet(i, "模板").head(DemoData.class).build();
+ // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
+ List data = data();
+ excelWriter.write(data, writeSheet);
+ }
+ /// 千万别忘记finish 会帮忙关闭流
+ excelWriter.finish();
}
/**
@@ -297,12 +328,11 @@ public class WriteTest {
@Test
public void dynamicHeadWrite() {
String fileName = TestFileUtil.getPath() + "dynamicHeadWrite" + System.currentTimeMillis() + ".xlsx";
- // write的时候 不传入 class 在table的时候传入
EasyExcel.write(fileName)
// 这里放入动态头
.head(head()).sheet("模板")
- // table的时候 传入class 并且设置needHead =false
- .table().head(DemoData.class).needHead(Boolean.FALSE).doWrite(data());
+ // 当然这里数据也可以用 List> 去传入
+ .doWrite(data());
}
/**
diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
index b4b1c91..1e872c7 100644
--- a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
+++ b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
@@ -5,9 +5,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
-import org.apache.poi.ss.usermodel.Cell;
-import org.apache.poi.ss.usermodel.Sheet;
-import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
@@ -20,8 +18,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.util.TestFileUtil;
-import com.alibaba.excel.util.FileUtils;
-import com.alibaba.excel.util.IoUtils;
+import com.alibaba.excel.EasyExcel;
import ch.qos.logback.core.util.FileUtil;
diff --git a/src/test/resources/multiplesheets/multiplesheets.xls b/src/test/resources/multiplesheets/multiplesheets.xls
new file mode 100644
index 0000000..a560128
Binary files /dev/null and b/src/test/resources/multiplesheets/multiplesheets.xls differ
diff --git a/src/test/resources/multiplesheets/multiplesheets.xlsx b/src/test/resources/multiplesheets/multiplesheets.xlsx
new file mode 100644
index 0000000..f90680a
Binary files /dev/null and b/src/test/resources/multiplesheets/multiplesheets.xlsx differ
diff --git a/update.md b/update.md
index 80f088e..14d339c 100644
--- a/update.md
+++ b/update.md
@@ -4,6 +4,10 @@
* 新增支持读取单元格类型、写入指定单元格类型
* 支持通过模板填充数据
+# 2.0.2
+* 修复xls无法获取sheetList的bug [Issue #621](https://github.com/alibaba/easyexcel/issues/621)
+* 修复监听器转换异常会重复提示的bug
+
# 2.0.1
* 降级poi为3.1.7 兼容jdk6