Browse Source

Merge pull request #551 from alibaba/2.0.0-beta4

2.0.0 beta4
pull/561/head v2.0.0-beta4
Jiaju Zhuang 5 years ago committed by GitHub
parent
commit
5f5e6e62ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      .github/ISSUE_TEMPLATE/1question.md
  2. 2
      pom.xml
  3. 1
      quickstart.md
  4. 12
      src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
  5. 14
      src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
  6. 22
      src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java
  7. 15
      src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
  8. 1
      src/main/java/com/alibaba/excel/util/BooleanUtils.java
  9. 6
      src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  10. 2
      src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiFormatTest.java
  11. 4
      src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java
  12. 51
      src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java
  13. 58
      src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatTest.java
  14. 51
      src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java
  15. 5
      update.md

18
.github/ISSUE_TEMPLATE/1question.md

@ -1,18 +0,0 @@
name: 使用疑问
about: 请先阅读“快速使用”,上面无法解决再提交问题
name: 给出建议
about: 给出一些建议的能
title: ''
labels: help wanted
labels: suggest
assignees: ''
---
**异常代码**
```java
这里写你的代码
```
**异常提示**
请提供完整的异常提示
**建议描述**

2
pom.xml

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId> <artifactId>easyexcel</artifactId>
<version>2.0.0-beta3</version> <version>2.0.0-beta4</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>easyexcel</name> <name>easyexcel</name>

1
quickstart.md

@ -13,6 +13,7 @@
* ExcelReaderSheetBuilder ExcelWriterSheetBuilder 构建出一个 ReadSheet WriteSheet对象,可以理解成excel里面的一页,每一页都要构建一个 * ExcelReaderSheetBuilder ExcelWriterSheetBuilder 构建出一个 ReadSheet WriteSheet对象,可以理解成excel里面的一页,每一页都要构建一个
* ReadListener 在每一行读取完毕后都会调用ReadListener来处理数据 * ReadListener 在每一行读取完毕后都会调用ReadListener来处理数据
* WriteHandler 在每一个操作包括创建单元格、创建表格等都会调用WriteHandler来处理数据 * WriteHandler 在每一个操作包括创建单元格、创建表格等都会调用WriteHandler来处理数据
* 所有配置都是继承的,Workbook的配置会被Sheet继承,所以在用EasyExcel设置参数的时候,在EasyExcel...sheet()方法之前作用域是整个sheet,之后针对单个sheet
#### 开源项目不容易,如果觉得本项目对您的工作还是有帮助的话,请在右上角帮忙点个★Star。 #### 开源项目不容易,如果觉得本项目对您的工作还是有帮助的话,请在右上角帮忙点个★Star。
### 读 ### 读
DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/java/com/alibaba/easyexcel/demo/read/ReadTest.java](/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java) DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/java/com/alibaba/easyexcel/demo/read/ReadTest.java](/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java)

12
src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java

@ -14,6 +14,8 @@ import org.apache.poi.hssf.eventusermodel.HSSFListener;
import org.apache.poi.hssf.eventusermodel.HSSFRequest; import org.apache.poi.hssf.eventusermodel.HSSFRequest;
import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener; import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;
import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@ -83,6 +85,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
@Override @Override
public void execute() { public void execute() {
analysisContext.readSheetHolder().getSheetNo();
MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this); MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);
formatListener = new FormatTrackingHSSFListener(listener); formatListener = new FormatTrackingHSSFListener(listener);
workbookBuildingListener = new EventWorkbookBuilder.SheetRecordCollectingListener(formatListener); workbookBuildingListener = new EventWorkbookBuilder.SheetRecordCollectingListener(formatListener);
@ -121,6 +124,10 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
@Override @Override
public void processRecord(Record record) { public void processRecord(Record record) {
// Not data from the current sheet
if (ignoreRecord(record)) {
return;
}
int thisRow = -1; int thisRow = -1;
int thisColumn = -1; int thisColumn = -1;
CellData cellData = null; CellData cellData = null;
@ -164,6 +171,11 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
processLastCellOfRow(record); processLastCellOfRow(record);
} }
private boolean ignoreRecord(Record record) {
return analysisContext.readWorkbookHolder().getIgnoreRecord03() && record.getSid() != BoundSheetRecord.sid
&& record.getSid() != BOFRecord.sid;
}
private void processLastCellOfRow(Record record) { private void processLastCellOfRow(Record record) {
// Handle end of row // Handle end of row
if (record instanceof LastCellOfRowDummyRecord) { if (record instanceof LastCellOfRowDummyRecord) {

14
src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java

@ -23,7 +23,6 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
private int sheetIndex; private int sheetIndex;
private List<ReadSheet> sheets; private List<ReadSheet> sheets;
private AnalysisContext context; private AnalysisContext context;
private boolean analyAllSheet;
private EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener; private EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener;
public BofRecordHandler(EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener, public BofRecordHandler(EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener,
@ -48,21 +47,20 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
if (orderedBsrs == null) { if (orderedBsrs == null) {
orderedBsrs = BoundSheetRecord.orderByBofPosition(boundSheetRecords); orderedBsrs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
} }
sheetIndex++; ReadSheet readSheet = new ReadSheet(sheetIndex, orderedBsrs[sheetIndex].getSheetname());
ReadSheet readSheet = new ReadSheet(sheetIndex, orderedBsrs[sheetIndex - 1].getSheetname());
sheets.add(readSheet); sheets.add(readSheet);
if (this.analyAllSheet) { if (sheetIndex == context.readSheetHolder().getSheetNo()) {
context.currentSheet(null, readSheet); context.readWorkbookHolder().setIgnoreRecord03(Boolean.FALSE);
} else {
context.readWorkbookHolder().setIgnoreRecord03(Boolean.TRUE);
} }
sheetIndex++;
} }
} }
} }
@Override @Override
public void init() { public void init() {
if (context.readSheetHolder() == null) {
this.analyAllSheet = true;
}
sheetIndex = 0; sheetIndex = 0;
orderedBsrs = null; orderedBsrs = null;
boundSheetRecords.clear(); boundSheetRecords.clear();

22
src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java

@ -13,6 +13,11 @@ import com.alibaba.excel.cache.ReadCache;
public class SharedStringsTableHandler extends DefaultHandler { public class SharedStringsTableHandler extends DefaultHandler {
private static final String T_TAG = "t"; private static final String T_TAG = "t";
private static final String SI_TAG = "si"; private static final String SI_TAG = "si";
/**
* Mac 2016 2017 will have this extra field to ignore
*/
private static final String RPH_TAG = "rPh";
/** /**
* The final piece of data * The final piece of data
*/ */
@ -23,6 +28,14 @@ public class SharedStringsTableHandler extends DefaultHandler {
private StringBuilder currentElementData; private StringBuilder currentElementData;
private ReadCache readCache; private ReadCache readCache;
/**
* Some fields in the T tag need to be ignored
*/
private boolean ignoreTagt = false;
/**
* The only time you need to read the characters in the T tag is when it is used
*/
private boolean isTagt = false;
public SharedStringsTableHandler(ReadCache readCache) { public SharedStringsTableHandler(ReadCache readCache) {
this.readCache = readCache; this.readCache = readCache;
@ -32,8 +45,11 @@ public class SharedStringsTableHandler extends DefaultHandler {
public void startElement(String uri, String localName, String name, Attributes attributes) { public void startElement(String uri, String localName, String name, Attributes attributes) {
if (T_TAG.equals(name)) { if (T_TAG.equals(name)) {
currentElementData = null; currentElementData = null;
isTagt = true;
} else if (SI_TAG.equals(name)) { } else if (SI_TAG.equals(name)) {
currentData = null; currentData = null;
} else if (RPH_TAG.equals(name)) {
ignoreTagt = true;
} }
} }
@ -46,17 +62,23 @@ public class SharedStringsTableHandler extends DefaultHandler {
} }
currentData.append(currentElementData); currentData.append(currentElementData);
} }
isTagt = false;
} else if (SI_TAG.equals(name)) { } else if (SI_TAG.equals(name)) {
if (currentData == null) { if (currentData == null) {
readCache.put(null); readCache.put(null);
} else { } else {
readCache.put(currentData.toString()); readCache.put(currentData.toString());
} }
} else if (RPH_TAG.equals(name)) {
ignoreTagt = false;
} }
} }
@Override @Override
public void characters(char[] ch, int start, int length) { public void characters(char[] ch, int start, int length) {
if (!isTagt || ignoreTagt) {
return;
}
if (currentElementData == null) { if (currentElementData == null) {
currentElementData = new StringBuilder(); currentElementData = new StringBuilder();
} }

15
src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java

@ -101,6 +101,12 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
*/ */
private POIFSFileSystem poifsFileSystem; private POIFSFileSystem poifsFileSystem;
/**
* Excel 2003 cannot read specific sheet. It can only read sheet by sheet.So when you specify one sheet, you ignore
* the others.
*/
private Boolean ignoreRecord03;
public ReadWorkbookHolder(ReadWorkbook readWorkbook) { public ReadWorkbookHolder(ReadWorkbook readWorkbook) {
super(readWorkbook, null, readWorkbook.getConvertAllFiled()); super(readWorkbook, null, readWorkbook.getConvertAllFiled());
this.readWorkbook = readWorkbook; this.readWorkbook = readWorkbook;
@ -144,6 +150,7 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
this.defaultReturnMap = readWorkbook.getDefaultReturnMap(); this.defaultReturnMap = readWorkbook.getDefaultReturnMap();
} }
this.hasReadSheet = new HashSet<Integer>(); this.hasReadSheet = new HashSet<Integer>();
this.ignoreRecord03 = Boolean.FALSE;
} }
public ReadWorkbook getReadWorkbook() { public ReadWorkbook getReadWorkbook() {
@ -258,6 +265,14 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
this.poifsFileSystem = poifsFileSystem; this.poifsFileSystem = poifsFileSystem;
} }
public Boolean getIgnoreRecord03() {
return ignoreRecord03;
}
public void setIgnoreRecord03(Boolean ignoreRecord03) {
this.ignoreRecord03 = ignoreRecord03;
}
@Override @Override
public HolderEnum holderType() { public HolderEnum holderType() {
return HolderEnum.WORKBOOK; return HolderEnum.WORKBOOK;

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

@ -8,7 +8,6 @@ package com.alibaba.excel.util;
public class BooleanUtils { public class BooleanUtils {
private static final String TRUE_NUMBER = "1"; private static final String TRUE_NUMBER = "1";
private static final String FALSE_NUMBER = "0";
private BooleanUtils() {} private BooleanUtils() {}

6
src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java

@ -174,7 +174,8 @@ public class ExcelBuilderImpl implements ExcelBuilder {
if (cellIndex != 0) { if (cellIndex != 0) {
cellIndex++; cellIndex++;
} }
for (int i = 0; i < oneRowData.size() - dataIndex; i++) { int size = oneRowData.size() - dataIndex;
for (int i = 0; i < size; i++) {
doAddBasicTypeToExcel(oneRowData, null, row, relativeRowIndex, dataIndex++, cellIndex++); doAddBasicTypeToExcel(oneRowData, null, row, relativeRowIndex, dataIndex++, cellIndex++);
} }
} }
@ -184,7 +185,8 @@ public class ExcelBuilderImpl implements ExcelBuilder {
beforeCellCreate(row, head, relativeRowIndex); beforeCellCreate(row, head, relativeRowIndex);
Cell cell = WorkBookUtil.createCell(row, cellIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex);
Object value = oneRowData.get(dataIndex); Object value = oneRowData.get(dataIndex);
CellData cellData = converterAndSet(context.currentWriteHolder(), value.getClass(), cell, value, null); CellData cellData =
converterAndSet(context.currentWriteHolder(), value == null ? null : value.getClass(), cell, value, null);
afterCellCreate(head, cellData, cell, relativeRowIndex); afterCellCreate(head, cellData, cell, relativeRowIndex);
} }

2
src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiFormatTest.java

@ -28,7 +28,7 @@ public class PoiFormatTest {
@Test @Test
public void lastRowNum() throws IOException { public void lastRowNum() throws IOException {
String file = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; String file = "D:\\test\\原文件.xlsx";
SXSSFWorkbook xssfWorkbook = new SXSSFWorkbook(new XSSFWorkbook(file)); SXSSFWorkbook xssfWorkbook = new SXSSFWorkbook(new XSSFWorkbook(file));
SXSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0); SXSSFSheet xssfSheet = xssfWorkbook.getSheetAt(0);
LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum()); LOGGER.info("一共行数:{}", xssfSheet.getLastRowNum());

4
src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java

@ -23,8 +23,8 @@ public class HgTest {
@Test @Test
public void hh() throws IOException { public void hh() throws IOException {
List<Object> list = EasyExcel.read(new FileInputStream("D:\\test\\hg2.xlsx")).autoTrim(Boolean.FALSE).sheet() List<Object> list =
.headRowNumber(0).doReadSync(); EasyExcel.read(new FileInputStream("D:\\test\\原文件.xlsx")).headRowNumber(0).sheet().doReadSync();
for (Object data : list) { for (Object data : list) {
LOGGER.info("返回数据:{}", JSON.toJSONString(data)); LOGGER.info("返回数据:{}", JSON.toJSONString(data));
} }

51
src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatListener.java

@ -0,0 +1,51 @@
package com.alibaba.easyexcel.test.temp.simple;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.demo.read.DemoDataListener;
import com.alibaba.easyexcel.test.temp.LockData;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
/**
* 模板的读取类
*
* @author Jiaju Zhuang
*/
public class RepeatListener extends AnalysisEventListener<LockData> {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoDataListener.class);
/**
* 每隔5条存储数据库实际使用中可以3000条然后清理list 方便内存回收
*/
private static final int BATCH_COUNT = 5;
List<LockData> list = new ArrayList<LockData>();
@Override
public void invoke(LockData data, AnalysisContext context) {
LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));
list.add(data);
if (list.size() >= BATCH_COUNT) {
saveData();
list.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
saveData();
LOGGER.info("所有数据解析完成!");
}
/**
* 加上存储数据库
*/
private void saveData() {
LOGGER.info("{}条数据,开始存储数据库!", list.size());
LOGGER.info("存储数据库成功!");
}
}

58
src/test/java/com/alibaba/easyexcel/test/temp/simple/RepeatTest.java

@ -0,0 +1,58 @@
package com.alibaba.easyexcel.test.temp.simple;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.temp.LockData;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSON;
/**
* 测试poi
*
* @author Jiaju Zhuang
**/
@Ignore
public class RepeatTest {
private static final Logger LOGGER = LoggerFactory.getLogger(RepeatTest.class);
@Test
public void hh() throws IOException {
ExcelReader reader =
EasyExcel.read(new FileInputStream("D:\\test\\hg2.xls"), LockData.class, new RepeatListener())
.headRowNumber(0).build();
ReadSheet r1 = EasyExcel.readSheet(0).build();
ReadSheet r2 = EasyExcel.readSheet(2).build();
reader.read(r1);
reader.read(r2);
reader.finish();
}
@Test
public void hh2() throws IOException {
ExcelReader reader =
EasyExcel.read(new FileInputStream("D:\\test\\sheet.xls"), LockData.class, new RepeatListener())
.headRowNumber(0).build();
ReadSheet r2 = EasyExcel.readSheet(1).build();
reader.read(r2);
reader.finish();
}
@Test
public void hh1() throws IOException {
ExcelReader reader =
EasyExcel.read(new FileInputStream("D:\\test\\hg2.xls"), LockData.class, new RepeatListener())
.headRowNumber(0).build();
ReadSheet r2 = EasyExcel.readSheet(0).build();
reader.read(r2);
reader.finish();
}
}

51
src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java

@ -0,0 +1,51 @@
package com.alibaba.easyexcel.test.temp.simple;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.demo.write.DemoData;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
/**
* 测试poi
*
* @author Jiaju Zhuang
**/
@Ignore
public class Wirte {
private static final Logger LOGGER = LoggerFactory.getLogger(Wirte.class);
@Test
public void simpleWrite() {
// 写法1
String fileName = TestFileUtil.getPath() + "ttttttttt11" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel.write(fileName).sheet("模板").doWrite(data());
}
private List<List<Object>> data() {
List<List<Object>> list = new ArrayList<List<Object>>();
for (int i = 0; i < 10; i++) {
List<Object> list1 = new ArrayList<Object>();
list1.add("字符串" + i);
list1.add(new Date());
list1.add(0.56);
list.add(list1);
}
return list;
}
}

5
update.md

@ -1,3 +1,8 @@
# 2.0.0-beta4
* 修改在传入List<List<Object>>判断行数错误 [Issue #526](https://github.com/alibaba/easyexcel/issues/526)
* 修复在mac 2016 2017导出的excel 可能存在多余字段的问题
* 修复03版 读取无法指定sheet的问题 [Issue #533](https://github.com/alibaba/easyexcel/issues/533)
# 2.0.0-beta3 # 2.0.0-beta3
* 导出完成移除临时目录 [Issue #386](https://github.com/alibaba/easyexcel/issues/386) * 导出完成移除临时目录 [Issue #386](https://github.com/alibaba/easyexcel/issues/386)
* 新增读取返回头数据 * 新增读取返回头数据

Loading…
Cancel
Save