diff --git a/pom.xml b/pom.xml index 78bf2fae..958a85d7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 2.0.1 + 2.0.2 jar easyexcel diff --git a/quickstart.md b/quickstart.md index dd4f3d6c..9ca53df9 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 c99787d1..e669b56e 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; @@ -297,4 +298,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 00000000..62d55175 --- /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 ddabd8cc..19aa2563 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 324d3e3e..384f7518 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,14 +45,18 @@ 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); } sheetIndex++; + if (context.readSheetHolder() != null) { + if (sheetIndex == context.readSheetHolder().getSheetNo()) { + context.readWorkbookHolder().setIgnoreRecord03(Boolean.FALSE); + } else { + context.readWorkbookHolder().setIgnoreRecord03(Boolean.TRUE); + } + } } } } @@ -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 4e7041e6..f9dd0d66 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 119854a2..a801cc4c 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; @@ -51,6 +52,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 6f0ae1c4..3ac3c5b4 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -113,6 +113,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/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java index d3c07f5f..fe23b2a1 100644 --- a/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java @@ -24,7 +24,6 @@ import com.alibaba.excel.write.metadata.WriteWorkbook; * @author Jiaju Zhuang */ public class WriteWorkbookHolder extends AbstractWriteHolder { - private static final Logger LOGGER = LoggerFactory.getLogger(WriteWorkbookHolder.class); /*** * poi Workbook */ 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 00000000..73da1c31 --- /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 00000000..a309027a --- /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 t020Read03() { + 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 00000000..950f562b --- /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 b65f99ea..a8e6a61f 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 9d5e9f08..8fff02ca 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 66367692..76c3c716 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 ea6dba15..9113960e 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 @@ -3,6 +3,7 @@ package com.alibaba.easyexcel.test.temp.poi; import java.io.File; import java.io.IOException; +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; @@ -15,6 +16,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; /** * 测试poi diff --git a/src/test/resources/multiplesheets/multiplesheets.xls b/src/test/resources/multiplesheets/multiplesheets.xls new file mode 100644 index 00000000..a5601288 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 00000000..f90680a1 Binary files /dev/null and b/src/test/resources/multiplesheets/multiplesheets.xlsx differ diff --git a/update.md b/update.md index 7af609f4..7c1cbb83 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +# 2.0.2 +* 修复xls无法获取sheetList的bug [Issue #621](https://github.com/alibaba/easyexcel/issues/621) +* 修复监听器转换异常会重复提示的bug + # 2.0.1 * 降级poi为3.1.7 兼容jdk6