Browse Source

Merge branch 'master' into 2.1.0-beta1

# Conflicts:
#	pom.xml
#	src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
#	update.md
bugfix
Jiaju Zhuang 5 years ago
parent
commit
14696aa67d
  1. 79
      quickstart.md
  2. 9
      src/main/java/com/alibaba/excel/ExcelWriter.java
  3. 60
      src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java
  4. 26
      src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
  5. 28
      src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
  6. 8
      src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java
  7. 8
      src/main/java/com/alibaba/excel/write/ExcelBuilder.java
  8. 5
      src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  9. 11
      src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsData.java
  10. 56
      src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsDataTest.java
  11. 41
      src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java
  12. 12
      src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
  13. 9
      src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java
  14. 36
      src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java
  15. 7
      src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
  16. BIN
      src/test/resources/multiplesheets/multiplesheets.xls
  17. BIN
      src/test/resources/multiplesheets/multiplesheets.xlsx
  18. 4
      update.md

79
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不能读取多次,多次读取需要重新读取文件
* <p>1. 创建excel对应的实体对象 参照{@link DemoData}
* <p>2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
* <p>3. 直接读即可
* <p>
* 1. 创建excel对应的实体对象 参照{@link DemoData}
* <p>
* 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
* <p>
* 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
/**
/**
* 重复多次写入
* <p>
* 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<DemoData> 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<DemoData> data = data();
excelWriter.write(data, writeSheet);
}
/// 千万别忘记finish 会帮忙关闭流
excelWriter.finish();
}
```
@ -867,18 +915,19 @@ public class WidthAndHeightData {
* <p>
* 思路是这样子的,先创建List<String>头格式的sheet仅仅写入头,然后通过table 不写入头的方式 去写入数据
*
* <p>1. 创建excel对应的实体对象 参照{@link DemoData}
* <p>2. 然后写入table即可
* <p>
* 1. 创建excel对应的实体对象 参照{@link DemoData}
* <p>
* 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<List<String>> 去传入
.doWrite(data());
}
private List<List<String>> 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());
}
```

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

60
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<ReadSheet> sheetList;
private XlsRecordHandler bofRecordHandler;
public XlsListSheetListener(AnalysisContext analysisContext, POIFSFileSystem poifsFileSystem) {
this.poifsFileSystem = poifsFileSystem;
sheetList = new ArrayList<ReadSheet>();
bofRecordHandler = new BofRecordHandler(analysisContext, sheetList, false);
bofRecordHandler.init();
}
@Override
public void processRecord(Record record) {
bofRecordHandler.processRecord(record);
}
public List<ReadSheet> 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;
}
}

26
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<Integer, CellData> records;
private List<ReadSheet> sheets = new ArrayList<ReadSheet>();
private List<ReadSheet> sheets;
private HSSFWorkbook stubWorkbook;
private List<XlsRecordHandler> recordHandlers = new ArrayList<XlsRecordHandler>();
private AnalysisContext analysisContext;
public XlsSaxAnalyser(AnalysisContext context, POIFSFileSystem poifsFileSystem) throws IOException {
public XlsSaxAnalyser(AnalysisContext context, POIFSFileSystem poifsFileSystem) {
this.analysisContext = context;
this.records = new TreeMap<Integer, CellData>();
this.poifsFileSystem = poifsFileSystem;
@ -80,6 +85,11 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
@Override
public List<ReadSheet> 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<Integer, CellData>();
sheets = new ArrayList<ReadSheet>();
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<ReadSheet>();
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());

28
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<ReadSheet> sheets;
private AnalysisContext context;
private EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener;
private boolean alreadyInit;
public BofRecordHandler(EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener,
AnalysisContext context, List<ReadSheet> sheets) {
public BofRecordHandler(AnalysisContext context, List<ReadSheet> 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

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

8
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
*/

5
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<Field> fieldList) {
beforeRowCreate(n, relativeRowIndex);
Row row = WorkBookUtil.createRow(context.writeSheetHolder().getSheet(), n);

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

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

41
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<MultipleSheetsData> {
private static final Logger LOGGER = LoggerFactory.getLogger(MultipleSheetsListener.class);
List<MultipleSheetsData> list = new ArrayList<MultipleSheetsData>();
@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<MultipleSheetsData> getList() {
return list;
}
public void setList(List<MultipleSheetsData> list) {
this.list = list;
}
}

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

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

36
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<DemoData> 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<DemoData> 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<List<String>> 去传入
.doWrite(data());
}
/**

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

BIN
src/test/resources/multiplesheets/multiplesheets.xls

Binary file not shown.

BIN
src/test/resources/multiplesheets/multiplesheets.xlsx

Binary file not shown.

4
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

Loading…
Cancel
Save