Browse Source

支持导入、导出加密

pull/724/head
Jiaju Zhuang 5 years ago
parent
commit
44068c94f9
  1. 34
      quickstart.md
  2. 37
      src/main/java/com/alibaba/excel/ExcelReader.java
  3. 12
      src/main/java/com/alibaba/excel/ExcelWriter.java
  4. 12
      src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java
  5. 39
      src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
  6. 10
      src/main/java/com/alibaba/excel/analysis/ExcelReadExecutor.java
  7. 6
      src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java
  8. 14
      src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
  9. 42
      src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
  10. 18
      src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java
  11. 18
      src/main/java/com/alibaba/excel/annotation/ExcelIgnoreUnannotated.java
  12. 4
      src/main/java/com/alibaba/excel/context/AnalysisContext.java
  13. 57
      src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java
  14. 12
      src/main/java/com/alibaba/excel/context/WriteContext.java
  15. 162
      src/main/java/com/alibaba/excel/context/WriteContextImpl.java
  16. 1
      src/main/java/com/alibaba/excel/metadata/BasicParameter.java
  17. 8
      src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
  18. 18
      src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java
  19. 13
      src/main/java/com/alibaba/excel/read/metadata/ReadSheet.java
  20. 12
      src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java
  21. 17
      src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
  22. 9
      src/main/java/com/alibaba/excel/util/FileUtils.java
  23. 67
      src/main/java/com/alibaba/excel/util/SheetUtils.java
  24. 14
      src/main/java/com/alibaba/excel/util/WorkBookUtil.java
  25. 1
      src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  26. 13
      src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java
  27. 13
      src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java
  28. 15
      src/main/java/com/alibaba/excel/write/metadata/WriteWorkbook.java
  29. 17
      src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java
  30. 14
      src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptData.java
  31. 35
      src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataListener.java
  32. 88
      src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataTest.java
  33. 14
      src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsDataTest.java
  34. 1
      src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java
  35. 27
      src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java
  36. 7
      src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java
  37. 2
      src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java
  38. 73
      src/test/java/com/alibaba/easyexcel/test/temp/poi/Poi3Test.java
  39. 2
      src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiTest.java
  40. 2
      src/test/java/com/alibaba/easyexcel/test/temp/simple/Wirte.java
  41. 5
      update.md

34
quickstart.md

@ -21,7 +21,7 @@
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)
* [最简单的读](#simpleRead)
* [指定列的下标或者列名](#indexOrNameRead)
* [读多个sheet](#repeatedRead)
* [读多个或者全部sheet](#repeatedRead)
* [日期、数字或者自定义格式转换](#converterRead)
* [多行头](#complexHeaderRead)
* [同步的返回](#synchronousRead)
@ -180,7 +180,7 @@ public class IndexOrNameData {
##### 代码
```java
/**
* 读多个sheet,这里注意一个sheet不能读取多次,多次读取需要重新读取文件
* 读多个或者全部sheet,这里注意一个sheet不能读取多次,多次读取需要重新读取文件
* <p>
* 1. 创建excel对应的实体对象 参照{@link DemoData}
* <p>
@ -190,24 +190,21 @@ public class IndexOrNameData {
*/
@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();
ReadSheet readSheet2 = EasyExcel.readSheet(1).build();
excelReader.read(readSheet1);
excelReader.read(readSheet2);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
// 读取全部sheet
// 这里需要注意 DemoDataListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个DemoDataListener里面写
EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).doReadAll();
// 方法2 如果 sheet1 sheet2 数据不一致的话
// 读取部分sheet
fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
excelReader = EasyExcel.read(fileName).build();
ExcelReader 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);
ReadSheet readSheet1 =
EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
ReadSheet readSheet2 =
EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
// 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能
excelReader.read(readSheet1, readSheet2);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
}
@ -518,6 +515,11 @@ public class DemoData {
private Date date;
@ExcelProperty("数字标题")
private Double doubleData;
/**
* 忽略这个字段
*/
@ExcelIgnore
private String ignore;
}
```
##### 代码

37
src/main/java/com/alibaba/excel/ExcelReader.java

@ -2,6 +2,7 @@ package com.alibaba.excel;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
@ -147,27 +148,41 @@ public class ExcelReader {
/**
* Parse all sheet content by default
*
* @deprecated lease use {@link #readAll()}
*/
@Deprecated
public void read() {
ExcelReadExecutor excelReadExecutor = excelAnalyser.excelExecutor();
if (excelReadExecutor.sheetList().isEmpty()) {
LOGGER.warn("Excel doesn't have any sheets.");
return;
}
for (ReadSheet readSheet : excelReadExecutor.sheetList()) {
read(readSheet);
}
readAll();
}
/***
* Parse all sheet content by default
*/
public void readAll() {
checkFinished();
excelAnalyser.analysis(null, Boolean.TRUE);
}
/**
* Parse the specified sheetSheetNo start from 1
* Parse the specified sheetSheetNo start from 0
*
* @param readSheet
* Read sheet
*/
public ExcelReader read(ReadSheet readSheet) {
public ExcelReader read(ReadSheet... readSheet) {
return read(Arrays.asList(readSheet));
}
/**
* Read multiple sheets.
*
* @param readSheetList
* @return
*/
public ExcelReader read(List<ReadSheet> readSheetList) {
checkFinished();
excelAnalyser.analysis(readSheet);
excelAnalyser.analysis(readSheetList, Boolean.FALSE);
return this;
}

12
src/main/java/com/alibaba/excel/ExcelWriter.java

@ -138,17 +138,7 @@ public class ExcelWriter {
* @return this current writer
*/
public ExcelWriter write(List data, WriteSheet writeSheet) {
return write(data, writeSheet, (WriteTable)null);
}
public ExcelWriter write(List data, WriteSheet writeSheet, String password) {
return write(data, writeSheet, null, password);
}
private ExcelWriter write(List data, WriteSheet writeSheet, WriteTable writeTable, String password) {
excelBuilder.addContent(data, writeSheet, writeTable, password);
return this;
return write(data, writeSheet, null);
}
/**

12
src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java

@ -1,5 +1,7 @@
package com.alibaba.excel.analysis;
import java.util.List;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.metadata.ReadSheet;
@ -10,12 +12,14 @@ import com.alibaba.excel.read.metadata.ReadSheet;
*/
public interface ExcelAnalyser {
/**
* parse one sheet
* parse the sheet
*
* @param readSheet
* sheet to read
* @param readSheetList
* Which sheets you need to read.
* @param readAll
* The <code>readSheetList</code> parameter is ignored, and all sheets are read.
*/
void analysis(ReadSheet readSheet);
void analysis(List<ReadSheet> readSheetList, Boolean readAll);
/**
* Complete the entire read file.Release the cache and close stream

39
src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java

@ -1,8 +1,13 @@
package com.alibaba.excel.analysis;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.filesystem.DocumentFactoryHelper;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.IOUtils;
@ -19,7 +24,9 @@ import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.StringUtils;
/**
* @author jipengfei
@ -64,7 +71,8 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
InputStream decryptedStream = null;
try {
decryptedStream =
DocumentFactoryHelper.getDecryptedStream(poifsFileSystem.getRoot().getFileSystem(), null);
DocumentFactoryHelper.getDecryptedStream(poifsFileSystem.getRoot().getFileSystem(),
analysisContext.readWorkbookHolder().getPassword());
excelReadExecutor = new XlsxSaxAnalyser(analysisContext, decryptedStream);
return;
} finally {
@ -74,6 +82,9 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
poifsFileSystem.close();
}
}
if (analysisContext.readWorkbookHolder().getPassword() != null) {
Biff8EncryptionKey.setCurrentUserPassword(analysisContext.readWorkbookHolder().getPassword());
}
excelReadExecutor = new XlsSaxAnalyser(analysisContext, poifsFileSystem);
break;
case XLSX:
@ -84,17 +95,24 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
}
@Override
public void analysis(ReadSheet readSheet) {
public void analysis(List<ReadSheet> readSheetList, Boolean readAll) {
try {
analysisContext.currentSheet(excelReadExecutor, readSheet);
if (!readAll && CollectionUtils.isEmpty(readSheetList)) {
throw new IllegalArgumentException("Specify at least one read sheet.");
}
try {
excelReadExecutor.execute();
excelReadExecutor.execute(readSheetList, readAll);
} catch (ExcelAnalysisStopException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Custom stop!");
}
}
analysisContext.readSheetHolder().notifyAfterAllAnalysed(analysisContext);
// The last sheet is read
if (excelReadExecutor instanceof XlsSaxAnalyser) {
if (analysisContext.readSheetHolder() != null) {
analysisContext.readSheetHolder().notifyAfterAllAnalysed(analysisContext);
}
}
} catch (RuntimeException e) {
finish();
throw e;
@ -110,6 +128,7 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
return;
}
ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder();
try {
if (readWorkbookHolder.getReadCache() != null) {
readWorkbookHolder.getReadCache().destroy();
@ -146,6 +165,16 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
} catch (Throwable t) {
throwCanNotCloseIo(t);
}
clearEncrypt03();
}
private void clearEncrypt03() {
if (StringUtils.isEmpty(analysisContext.readWorkbookHolder().getPassword())
|| !ExcelTypeEnum.XLS.equals(analysisContext.readWorkbookHolder().getExcelType())) {
return;
}
Biff8EncryptionKey.setCurrentUserPassword(null);
}
private void throwCanNotCloseIo(Throwable t) {

10
src/main/java/com/alibaba/excel/analysis/ExcelReadExecutor.java

@ -19,8 +19,12 @@ public interface ExcelReadExecutor {
List<ReadSheet> sheetList();
/**
* Read sheet
* Read the sheet.
*
* @param readSheetList
* Which sheets you need to read.
* @param readAll
* The <code>readSheetList</code> parameter is ignored, and all sheets are read.
*/
void execute();
void execute(List<ReadSheet> readSheetList, Boolean readAll);
}

6
src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java

@ -10,7 +10,6 @@ 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;
@ -27,13 +26,14 @@ import com.alibaba.excel.read.metadata.ReadSheet;
public class XlsListSheetListener implements HSSFListener {
private POIFSFileSystem poifsFileSystem;
private List<ReadSheet> sheetList;
private XlsRecordHandler bofRecordHandler;
private BofRecordHandler bofRecordHandler;
public XlsListSheetListener(AnalysisContext analysisContext, POIFSFileSystem poifsFileSystem) {
this.poifsFileSystem = poifsFileSystem;
sheetList = new ArrayList<ReadSheet>();
bofRecordHandler = new BofRecordHandler(analysisContext, sheetList, false);
bofRecordHandler = new BofRecordHandler(analysisContext, sheetList, false, false);
bofRecordHandler.init();
bofRecordHandler.init(null, true);
}
@Override

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

@ -60,6 +60,8 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
private static final Logger LOGGER = LoggerFactory.getLogger(XlsSaxAnalyser.class);
private POIFSFileSystem poifsFileSystem;
private Boolean readAll;
private List<ReadSheet> readSheetList;
private int lastRowNumber;
private int lastColumnNumber;
/**
@ -91,7 +93,9 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
}
@Override
public void execute() {
public void execute(List<ReadSheet> readSheetList, Boolean readAll) {
this.readAll = readAll;
this.readSheetList = readSheetList;
MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);
formatListener = new FormatTrackingHSSFListener(listener);
workbookBuildingListener = new EventWorkbookBuilder.SheetRecordCollectingListener(formatListener);
@ -195,9 +199,9 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
// 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));
recordHandlers.add(new BofRecordHandler(analysisContext, sheets, false, true));
} else {
recordHandlers.add(new BofRecordHandler(analysisContext, sheets, true));
recordHandlers.add(new BofRecordHandler(analysisContext, sheets, true, true));
}
recordHandlers.add(new FormulaRecordHandler(stubWorkbook, formatListener));
recordHandlers.add(new LabelRecordHandler());
@ -211,6 +215,10 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
for (XlsRecordHandler x : recordHandlers) {
x.init();
if (x instanceof BofRecordHandler) {
BofRecordHandler bofRecordHandler = (BofRecordHandler)x;
bofRecordHandler.init(readSheetList, readAll);
}
}
}
}

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

@ -10,6 +10,7 @@ import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.util.SheetUtils;
/**
* Record handler
@ -21,13 +22,18 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
private BoundSheetRecord[] orderedBsrs;
private int sheetIndex;
private List<ReadSheet> sheets;
private Boolean readAll;
private List<ReadSheet> readSheetList;
private AnalysisContext context;
private boolean alreadyInit;
private boolean needInitSheet;
public BofRecordHandler(AnalysisContext context, List<ReadSheet> sheets, boolean alreadyInit) {
public BofRecordHandler(AnalysisContext context, List<ReadSheet> sheets, boolean alreadyInit,
boolean needInitSheet) {
this.context = context;
this.sheets = sheets;
this.alreadyInit = alreadyInit;
this.needInitSheet = needInitSheet;
}
@Override
@ -45,15 +51,34 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
if (orderedBsrs == null) {
orderedBsrs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
}
String sheetName = orderedBsrs[sheetIndex].getSheetname();
// Find the currently read sheet
ReadSheet readSheet = null;
if (!alreadyInit) {
ReadSheet readSheet = new ReadSheet(sheetIndex, orderedBsrs[sheetIndex].getSheetname());
readSheet = new ReadSheet(sheetIndex, sheetName);
sheets.add(readSheet);
}
if (context.readSheetHolder() != null) {
if (sheetIndex == context.readSheetHolder().getSheetNo()) {
if (needInitSheet) {
if (readSheet == null) {
for (ReadSheet sheet : sheets) {
if (sheet.getSheetNo() == sheetIndex) {
readSheet = sheet;
break;
}
}
}
assert readSheet != null : "Can't find the sheet.";
context.readWorkbookHolder().setIgnoreRecord03(Boolean.TRUE);
// Copy the parameter to the current sheet
readSheet = SheetUtils.match(readSheet, readSheetList, readAll,
context.readWorkbookHolder().getGlobalConfiguration());
if (readSheet != null) {
if (readSheet.getSheetNo() != 0) {
// Prompt for the end of the previous form read
context.readSheetHolder().notifyAfterAllAnalysed(context);
}
context.currentSheet(readSheet);
context.readWorkbookHolder().setIgnoreRecord03(Boolean.FALSE);
} else {
context.readWorkbookHolder().setIgnoreRecord03(Boolean.TRUE);
}
}
sheetIndex++;
@ -71,6 +96,11 @@ public class BofRecordHandler extends AbstractXlsRecordHandler {
}
}
public void init(List<ReadSheet> readSheetList, Boolean readAll) {
this.readSheetList = readSheetList;
this.readAll = readAll;
}
@Override
public int getOrder() {
return 0;

18
src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java

@ -15,6 +15,7 @@ import javax.xml.parsers.SAXParserFactory;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFRelation;
@ -33,6 +34,8 @@ import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.SheetUtils;
import com.alibaba.excel.util.StringUtils;
/**
*
@ -172,9 +175,16 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor {
}
@Override
public void execute() {
parseXmlSource(sheetMap.get(analysisContext.readSheetHolder().getSheetNo()),
new XlsxRowHandler(analysisContext, stylesTable));
public void execute(List<ReadSheet> readSheetList, Boolean readAll) {
for (ReadSheet readSheet : sheetList) {
readSheet = SheetUtils.match(readSheet, readSheetList, readAll,
analysisContext.readWorkbookHolder().getGlobalConfiguration());
if (readSheet != null) {
analysisContext.currentSheet(readSheet);
parseXmlSource(sheetMap.get(readSheet.getSheetNo()), new XlsxRowHandler(analysisContext, stylesTable));
// The last sheet is read
analysisContext.readSheetHolder().notifyAfterAllAnalysed(analysisContext);
}
}
}
}

18
src/main/java/com/alibaba/excel/annotation/ExcelIgnoreUnannotated.java

@ -0,0 +1,18 @@
package com.alibaba.excel.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Ignore all unannotated fields.
*
* @author Jiaju Zhuang
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ExcelIgnoreUnannotated {
}

4
src/main/java/com/alibaba/excel/context/AnalysisContext.java

@ -22,12 +22,10 @@ public interface AnalysisContext {
/**
* Select the current table
*
* @param excelReadExecutor
* Excel file Executor
* @param readSheet
* sheet to read
*/
void currentSheet(ExcelReadExecutor excelReadExecutor, ReadSheet readSheet);
void currentSheet(ReadSheet readSheet);
/**
* All information about the workbook you are currently working on

57
src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java

@ -5,8 +5,6 @@ import java.io.InputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.ExcelReadExecutor;
import com.alibaba.excel.analysis.v07.XlsxSaxAnalyser;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.read.metadata.ReadSheet;
@ -16,7 +14,6 @@ import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.StringUtils;
/**
*
@ -53,13 +50,9 @@ public class AnalysisContextImpl implements AnalysisContext {
}
@Override
public void currentSheet(ExcelReadExecutor excelReadExecutor, ReadSheet readSheet) {
if (readSheet == null) {
throw new IllegalArgumentException("Sheet argument cannot be null.");
}
public void currentSheet(ReadSheet readSheet) {
readSheetHolder = new ReadSheetHolder(readSheet, readWorkbookHolder);
currentReadHolder = readSheetHolder;
selectSheet(excelReadExecutor);
if (readWorkbookHolder.getHasReadSheet().contains(readSheetHolder.getSheetNo())) {
throw new ExcelAnalysisException("Cannot read sheet repeatedly.");
}
@ -69,54 +62,6 @@ public class AnalysisContextImpl implements AnalysisContext {
}
}
private void selectSheet(ExcelReadExecutor excelReadExecutor) {
if (excelReadExecutor instanceof XlsxSaxAnalyser) {
selectSheet07(excelReadExecutor);
} else {
selectSheet03();
}
}
private void selectSheet03() {
if (readSheetHolder.getSheetNo() != null && readSheetHolder.getSheetNo() >= 0) {
return;
}
if (!StringUtils.isEmpty(readSheetHolder.getSheetName())) {
LOGGER.warn("Excel 2003 does not support matching sheets by name, defaults to the first one.");
}
readSheetHolder.setSheetNo(0);
}
private void selectSheet07(ExcelReadExecutor excelReadExecutor) {
if (readSheetHolder.getSheetNo() != null && readSheetHolder.getSheetNo() >= 0) {
for (ReadSheet readSheetExcel : excelReadExecutor.sheetList()) {
if (readSheetExcel.getSheetNo().equals(readSheetHolder.getSheetNo())) {
readSheetHolder.setSheetName(readSheetExcel.getSheetName());
return;
}
}
throw new ExcelAnalysisException("Can not find sheet:" + readSheetHolder.getSheetNo());
}
if (!StringUtils.isEmpty(readSheetHolder.getSheetName())) {
for (ReadSheet readSheetExcel : excelReadExecutor.sheetList()) {
String sheetName = readSheetExcel.getSheetName();
if (sheetName == null) {
continue;
}
if (readSheetHolder.globalConfiguration().getAutoTrim()) {
sheetName = sheetName.trim();
}
if (sheetName.equals(readSheetHolder.getSheetName())) {
readSheetHolder.setSheetNo(readSheetExcel.getSheetNo());
return;
}
}
}
ReadSheet readSheetExcel = excelReadExecutor.sheetList().get(0);
readSheetHolder.setSheetNo(readSheetExcel.getSheetNo());
readSheetHolder.setSheetName(readSheetExcel.getSheetName());
}
@Override
public ReadWorkbookHolder readWorkbookHolder() {
return readWorkbookHolder;

12
src/main/java/com/alibaba/excel/context/WriteContext.java

@ -69,18 +69,6 @@ public interface WriteContext {
*/
void finish();
/**
* isEncrypt
* @return
*/
boolean isEncrypt();
/**
* setPassword
* @param password
* @return
*/
void setPassword(String password);
/**
* Current sheet

162
src/main/java/com/alibaba/excel/context/WriteContextImpl.java

@ -1,15 +1,27 @@
package com.alibaba.excel.context;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.StringUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.util.Map;
import java.util.UUID;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.Decryptor;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.DocumentOutputStream;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
@ -120,7 +132,6 @@ public class WriteContextImpl implements WriteContext {
WriteHandlerUtils.beforeSheetCreate(this);
// Initialization current sheet
initSheet(writeType);
WriteHandlerUtils.afterSheetCreate(this);
}
private void initCurrentSheetHolder(WriteSheet writeSheet) {
@ -147,6 +158,7 @@ public class WriteContextImpl implements WriteContext {
writeSheetHolder.setCachedSheet(currentSheet);
}
writeSheetHolder.setSheet(currentSheet);
WriteHandlerUtils.afterSheetCreate(this);
if (WriteTypeEnum.ADD.equals(writeType)) {
// Initialization head
initHead(writeSheetHolder.excelWriteHeadProperty());
@ -249,18 +261,23 @@ public class WriteContextImpl implements WriteContext {
if (writeWorkbookHolder == null) {
return;
}
try {
writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream());
if (isEncrypt()){
LOGGER.debug("start encrypt");
encrypt(writeWorkbookHolder);
LOGGER.debug("finish encrypt");
}
writeWorkbookHolder.getWorkbook().close();
boolean isOutputStreamEncrypt = false;
try {
isOutputStreamEncrypt = doOutputStreamEncrypt07();
} catch (Throwable t) {
throwCanNotCloseIo(t);
}
if (!isOutputStreamEncrypt) {
try {
writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream());
writeWorkbookHolder.getWorkbook().close();
} catch (Throwable t) {
throwCanNotCloseIo(t);
}
}
try {
Workbook workbook = writeWorkbookHolder.getWorkbook();
if (workbook instanceof SXSSFWorkbook) {
@ -269,6 +286,7 @@ public class WriteContextImpl implements WriteContext {
} catch (Throwable t) {
throwCanNotCloseIo(t);
}
try {
if (writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getOutputStream() != null) {
writeWorkbookHolder.getOutputStream().close();
@ -276,6 +294,15 @@ public class WriteContextImpl implements WriteContext {
} catch (Throwable t) {
throwCanNotCloseIo(t);
}
if (!isOutputStreamEncrypt) {
try {
doFileEncrypt07();
} catch (Throwable t) {
throwCanNotCloseIo(t);
}
}
try {
if (writeWorkbookHolder.getTempTemplateInputStream() != null) {
writeWorkbookHolder.getTempTemplateInputStream().close();
@ -283,21 +310,14 @@ public class WriteContextImpl implements WriteContext {
} catch (Throwable t) {
throwCanNotCloseIo(t);
}
clearEncrypt03();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Finished write.");
}
}
@Override
public boolean isEncrypt() {
return !StringUtils.isEmpty(writeWorkbookHolder.getPassword());
}
@Override
public void setPassword(String password) {
writeWorkbookHolder.setPassword(password);
}
private void throwCanNotCloseIo(Throwable t) {
throw new ExcelGenerateException("Can not close IO", t);
}
@ -322,28 +342,94 @@ public class WriteContextImpl implements WriteContext {
return writeWorkbookHolder.getWorkbook();
}
private void clearEncrypt03() {
if (StringUtils.isEmpty(writeWorkbookHolder.getPassword())
|| !ExcelTypeEnum.XLS.equals(writeWorkbookHolder.getExcelType())) {
return;
}
Biff8EncryptionKey.setCurrentUserPassword(null);
}
/**
* do encrypt
* @param writeWorkbookHolder
* To encrypt
*/
private void encrypt(WriteWorkbookHolder writeWorkbookHolder){
private boolean doOutputStreamEncrypt07() throws Exception {
if (StringUtils.isEmpty(writeWorkbookHolder.getPassword())
|| !ExcelTypeEnum.XLSX.equals(writeWorkbookHolder.getExcelType())) {
return false;
}
if (writeWorkbookHolder.getFile() != null) {
return false;
}
File tempXlsx = FileUtils.createTmpFile(UUID.randomUUID().toString() + ".xlsx");
FileOutputStream tempFileOutputStream = new FileOutputStream(tempXlsx);
try {
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.standard);
Encryptor enc = info.getEncryptor();
enc.confirmPassword(writeWorkbookHolder.getPassword());
OPCPackage opc = OPCPackage.open(writeWorkbookHolder.getFile(), PackageAccess.READ_WRITE);
OutputStream os = enc.getDataStream(fs);
opc.save(os);
opc.close();
//write the encrypted file back to the stream
FileOutputStream fos = new FileOutputStream(writeWorkbookHolder.getFile());
fs.writeFilesystem(fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
writeWorkbookHolder.getWorkbook().write(tempFileOutputStream);
} finally {
try {
writeWorkbookHolder.getWorkbook().close();
tempFileOutputStream.close();
} catch (Exception e) {
if (!tempXlsx.delete()) {
throw new ExcelGenerateException("Can not delete temp File!");
}
throw e;
}
}
POIFSFileSystem fileSystem = null;
try {
fileSystem = openFileSystemAndEncrypt(tempXlsx);
fileSystem.writeFilesystem(writeWorkbookHolder.getOutputStream());
} finally {
if (fileSystem != null) {
fileSystem.close();
}
if (!tempXlsx.delete()) {
throw new ExcelGenerateException("Can not delete temp File!");
}
}
return true;
}
/**
* To encrypt
*/
private void doFileEncrypt07() throws Exception {
if (StringUtils.isEmpty(writeWorkbookHolder.getPassword())
|| !ExcelTypeEnum.XLSX.equals(writeWorkbookHolder.getExcelType())) {
return;
}
if (writeWorkbookHolder.getFile() == null) {
return;
}
FileOutputStream fileOutputStream = null;
POIFSFileSystem fileSystem = null;
try {
fileSystem = openFileSystemAndEncrypt(writeWorkbookHolder.getFile());
fileOutputStream = new FileOutputStream(writeWorkbookHolder.getFile());
fileSystem.writeFilesystem(fileOutputStream);
} finally {
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (fileSystem != null) {
fileSystem.close();
}
}
}
private POIFSFileSystem openFileSystemAndEncrypt(File file) throws Exception {
POIFSFileSystem fileSystem = new POIFSFileSystem();
Encryptor encryptor = new EncryptionInfo(EncryptionMode.standard).getEncryptor();
encryptor.confirmPassword(writeWorkbookHolder.getPassword());
OPCPackage opcPackage = null;
try {
opcPackage = OPCPackage.open(file, PackageAccess.READ_WRITE);
OutputStream outputStream = encryptor.getDataStream(fileSystem);
opcPackage.save(outputStream);
} finally {
opcPackage.close();
}
return fileSystem;
}
}

1
src/main/java/com/alibaba/excel/metadata/BasicParameter.java

@ -74,4 +74,5 @@ public class BasicParameter {
public void setUse1904windowing(Boolean use1904windowing) {
this.use1904windowing = use1904windowing;
}
}

8
src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java

@ -13,9 +13,11 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.format.NumberFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.converters.AutoConverter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.HeadKindEnum;
@ -120,6 +122,8 @@ public class ExcelHeadProperty {
tempClass = tempClass.getSuperclass();
}
ExcelIgnoreUnannotated excelIgnoreUnannotated =
(ExcelIgnoreUnannotated)headClazz.getAnnotation(ExcelIgnoreUnannotated.class);
// Screening of field
List<Field> defaultFieldList = new ArrayList<Field>();
Map<Integer, Field> customFiledMap = new TreeMap<Integer, Field>();
@ -130,7 +134,9 @@ public class ExcelHeadProperty {
continue;
}
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
if (excelProperty == null && convertAllFiled != null && !convertAllFiled) {
boolean noExcelProperty = excelProperty == null
&& ((convertAllFiled != null && !convertAllFiled) || excelIgnoreUnannotated != null);
if (noExcelProperty) {
ignoreMap.put(field.getName(), field);
continue;
}

18
src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java

@ -222,10 +222,28 @@ public class ExcelReaderBuilder {
return this;
}
/**
* Whether the encryption
*
* @param password
* @return
*/
public ExcelReaderBuilder password(String password) {
readWorkbook.setPassword(password);
return this;
}
public ExcelReader build() {
return new ExcelReader(readWorkbook);
}
public ExcelReader doReadAll() {
ExcelReader excelReader = build();
excelReader.readAll();
excelReader.finish();
return excelReader;
}
public ExcelReaderSheetBuilder sheet() {
return sheet(null, null);
}

13
src/main/java/com/alibaba/excel/read/metadata/ReadSheet.java

@ -42,6 +42,19 @@ public class ReadSheet extends ReadBasicParameter {
this.sheetName = sheetName;
}
public void copyBasicParameter(ReadSheet other) {
if (other == null) {
return;
}
this.setHeadRowNumber(other.getHeadRowNumber());
this.setCustomReadListenerList(other.getCustomReadListenerList());
this.setHead(other.getHead());
this.setClazz(other.getClazz());
this.setCustomConverterList(other.getCustomConverterList());
this.setAutoTrim(other.getAutoTrim());
this.setUse1904windowing(other.getUse1904windowing());
}
@Override
public String toString() {
return "ReadSheet{" + "sheetNo=" + sheetNo + ", sheetName='" + sheetName + '\'' + "} " + super.toString();

12
src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java

@ -59,6 +59,10 @@ public class ReadWorkbook extends ReadBasicParameter {
* Select the cache.Default use {@link com.alibaba.excel.cache.selector.SimpleReadCacheSelector}
*/
private ReadCacheSelector readCacheSelector;
/**
* Whether the encryption
*/
private String password;
/**
* The default is all excel objects.Default is true.
* <p>
@ -164,4 +168,12 @@ public class ReadWorkbook extends ReadBasicParameter {
public void setReadCacheSelector(ReadCacheSelector readCacheSelector) {
this.readCacheSelector = readCacheSelector;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

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

@ -8,8 +8,6 @@ import java.util.Set;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.cache.ReadCache;
import com.alibaba.excel.cache.selector.EternalReadCacheSelector;
@ -28,7 +26,6 @@ import com.alibaba.excel.support.ExcelTypeEnum;
* @author Jiaju Zhuang
*/
public class ReadWorkbookHolder extends AbstractReadHolder {
private static final Logger LOGGER = LoggerFactory.getLogger(ReadWorkbookHolder.class);
/**
* current param
@ -82,7 +79,10 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
* Temporary files when reading excel
*/
private File tempFile;
/**
* Whether the encryption
*/
private String password;
/**
* The default is all excel objects.if true , you can use {@link com.alibaba.excel.annotation.ExcelIgnore} ignore a
* field. if false , you must use {@link com.alibaba.excel.annotation.ExcelProperty} to use a filed.
@ -174,6 +174,7 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
}
this.hasReadSheet = new HashSet<Integer>();
this.ignoreRecord03 = Boolean.FALSE;
this.password = readWorkbook.getPassword();
}
public ReadWorkbook getReadWorkbook() {
@ -312,6 +313,14 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
this.ignoreRecord03 = ignoreRecord03;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public HolderEnum holderType() {
return HolderEnum.WORKBOOK;

9
src/main/java/com/alibaba/excel/util/FileUtils.java

@ -157,6 +157,15 @@ public class FileUtils {
return directory;
}
public static File createTmpFile(String fileName) {
String tmpDir = System.getProperty(JAVA_IO_TMPDIR);
if (tmpDir == null) {
throw new RuntimeException(
"Systems temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + " jvm property!");
}
return new File(tmpDir, fileName);
}
/**
*
* @param directory

67
src/main/java/com/alibaba/excel/util/SheetUtils.java

@ -0,0 +1,67 @@
package com.alibaba.excel.util;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.read.metadata.ReadSheet;
/**
* Sheet utils
*
* @author Jiaju Zhuang
*/
public class SheetUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(SheetUtils.class);
private SheetUtils() {}
/**
* Match the parameters to the actual sheet
*
* @param readSheet
* actual sheet
* @param parameterReadSheetList
* parameters
* @param readAll
* @return
*/
public static ReadSheet match(ReadSheet readSheet, List<ReadSheet> parameterReadSheetList, Boolean readAll,
GlobalConfiguration globalConfiguration) {
if (readAll) {
return readSheet;
}
for (ReadSheet parameterReadSheet : parameterReadSheetList) {
if (parameterReadSheet == null) {
continue;
}
if (parameterReadSheet.getSheetNo() == null && parameterReadSheet.getSheetName() == null) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("The first is read by default.");
}
parameterReadSheet.setSheetNo(0);
}
boolean match = (parameterReadSheet.getSheetNo() != null
&& parameterReadSheet.getSheetNo().equals(readSheet.getSheetNo()));
if (!match) {
String parameterSheetName = parameterReadSheet.getSheetName();
if (!StringUtils.isEmpty(parameterSheetName)) {
boolean autoTrim = (parameterReadSheet.getAutoTrim() != null && parameterReadSheet.getAutoTrim())
|| (parameterReadSheet.getAutoTrim() == null && globalConfiguration.getAutoTrim());
if (autoTrim) {
parameterSheetName = parameterSheetName.trim();
}
match = parameterSheetName.equals(readSheet.getSheetName());
}
}
if (match) {
readSheet.copyBasicParameter(parameterReadSheet);
return readSheet;
}
}
return null;
}
}

14
src/main/java/com/alibaba/excel/util/WorkBookUtil.java

@ -1,10 +1,16 @@
package com.alibaba.excel.util;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
@ -48,6 +54,10 @@ public class WorkBookUtil {
}
writeWorkbookHolder.setCachedWorkbook(hssfWorkbook);
writeWorkbookHolder.setWorkbook(hssfWorkbook);
if (writeWorkbookHolder.getPassword() != null) {
Biff8EncryptionKey.setCurrentUserPassword(writeWorkbookHolder.getPassword());
hssfWorkbook.writeProtectWorkbook(writeWorkbookHolder.getPassword(), StringUtils.EMPTY);
}
}
public static Sheet createSheet(Workbook workbook, String sheetName) {

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

@ -103,7 +103,6 @@ public class ExcelBuilderImpl implements ExcelBuilder {
}
context.currentSheet(writeSheet, WriteTypeEnum.ADD);
context.currentTable(writeTable);
context.setPassword(password);
if (excelWriteAddExecutor == null) {
excelWriteAddExecutor = new ExcelWriteAddExecutor(context);
}

13
src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java

@ -90,6 +90,19 @@ public class ExcelWriterBuilder {
return this;
}
/**
* Whether the encryption.
* <p>
* WARRING:Encryption is when the entire file is read into memory, so it is very memory intensive.
*
* @param password
* @return
*/
public ExcelWriterBuilder password(String password) {
writeWorkbook.setPassword(password);
return this;
}
/**
* The default is all excel objects.if true , you can use {@link com.alibaba.excel.annotation.ExcelIgnore} ignore a
* field. if false , you must use {@link com.alibaba.excel.annotation.ExcelProperty} to use a filed.

13
src/main/java/com/alibaba/excel/write/builder/ExcelWriterSheetBuilder.java

@ -159,19 +159,6 @@ public class ExcelWriterSheetBuilder {
excelWriter.finish();
}
/**
* write with password
* @param data
* @param password
*/
public void doWrite(List data,String password) {
if (excelWriter == null) {
throw new ExcelGenerateException("Must use 'EasyExcelFactory.write().sheet()' to call this method");
}
excelWriter.write(data, build(), password);
excelWriter.finish();
}
public ExcelWriterTableBuilder table() {
return table(null);
}

15
src/main/java/com/alibaba/excel/write/metadata/WriteWorkbook.java

@ -50,6 +50,13 @@ public class WriteWorkbook extends WriteBasicParameter {
* Mandatory use 'inputStream' .Default is false
*/
private Boolean mandatoryUseInputStream;
/**
* Whether the encryption
* <p>
* WARRING:Encryption is when the entire file is read into memory, so it is very memory intensive.
*
*/
private String password;
/**
* The default is all excel objects.Default is true.
* <p>
@ -140,4 +147,12 @@ public class WriteWorkbook extends WriteBasicParameter {
public void setWriteHandler(com.alibaba.excel.event.WriteHandler writeHandler) {
this.writeHandler = writeHandler;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

17
src/main/java/com/alibaba/excel/write/metadata/holder/WriteWorkbookHolder.java

@ -1,15 +1,12 @@
package com.alibaba.excel.write.metadata.holder;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -96,9 +93,8 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
* prevent duplicate creation of sheet objects
*/
private Map<Integer, WriteSheetHolder> hasBeenInitializedSheet;
/**
* password
* Whether the encryption
*/
private String password;
@ -140,6 +136,7 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
this.mandatoryUseInputStream = writeWorkbook.getMandatoryUseInputStream();
}
this.hasBeenInitializedSheet = new HashMap<Integer, WriteSheetHolder>();
this.password = writeWorkbook.getPassword();
}
private void copyTemplate() throws IOException {
@ -257,11 +254,6 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
this.mandatoryUseInputStream = mandatoryUseInputStream;
}
@Override
public HolderEnum holderType() {
return HolderEnum.WORKBOOK;
}
public String getPassword() {
return password;
}
@ -269,4 +261,9 @@ public class WriteWorkbookHolder extends AbstractWriteHolder {
public void setPassword(String password) {
this.password = password;
}
@Override
public HolderEnum holderType() {
return HolderEnum.WORKBOOK;
}
}

14
src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptData.java

@ -0,0 +1,14 @@
package com.alibaba.easyexcel.test.core.encrypt;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* @author Jiaju Zhuang
*/
@Data
public class EncryptData {
@ExcelProperty("姓名")
private String name;
}

35
src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataListener.java

@ -0,0 +1,35 @@
package com.alibaba.easyexcel.test.core.encrypt;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
/**
* @author Jiaju Zhuang
*/
public class EncryptDataListener extends AnalysisEventListener<EncryptData> {
private static final Logger LOGGER = LoggerFactory.getLogger(EncryptDataListener.class);
List<EncryptData> list = new ArrayList<EncryptData>();
@Override
public void invoke(EncryptData data, AnalysisContext context) {
list.add(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
Assert.assertEquals(list.size(), 10);
Assert.assertEquals(list.get(0).getName(), "姓名0");
Assert.assertEquals((int)(context.readSheetHolder().getSheetNo()), 0);
Assert.assertEquals(
context.readSheetHolder().getExcelReadHeadProperty().getHeadMap().get(0).getHeadNameList().get(0), "姓名");
LOGGER.debug("First row:{}", JSON.toJSONString(list.get(0)));
}
}

88
src/test/java/com/alibaba/easyexcel/test/core/encrypt/EncryptDataTest.java

@ -0,0 +1,88 @@
package com.alibaba.easyexcel.test.core.encrypt;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
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.core.simple.SimpleData;
import com.alibaba.easyexcel.test.core.simple.SimpleDataListener;
import com.alibaba.easyexcel.test.core.simple.SimpleDataSheetNameListener;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.FileUtils;
/**
*
* @author Jiaju Zhuang
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class EncryptDataTest {
private static File file07;
private static File file03;
private static File file07OutputStream;
private static File file03OutputStream;
@BeforeClass
public static void init() {
file07 = TestFileUtil.createNewFile("encrypt07.xlsx");
file03 = TestFileUtil.createNewFile("encrypt03.xls");
file07OutputStream = TestFileUtil.createNewFile("encryptOutputStream07.xlsx");
file03OutputStream = TestFileUtil.createNewFile("encryptOutputStream03.xls");
}
@Test
public void t01ReadAndWrite07() {
readAndWrite(file07);
}
@Test
public void t02ReadAndWrite03() {
readAndWrite(file03);
}
@Test
public void t01ReadAndWriteStream07() throws Exception {
readAndWriteStream(file07OutputStream, ExcelTypeEnum.XLSX);
}
@Test
public void t02ReadAndWriteStream03() throws Exception {
readAndWriteStream(file03OutputStream, ExcelTypeEnum.XLSX);
}
private void readAndWrite(File file) {
EasyExcel.write(file, EncryptData.class).password("123456").sheet().doWrite(data());
EasyExcel.read(file, EncryptData.class, new EncryptDataListener()).password("123456").sheet().doRead();
}
private void readAndWriteStream(File file, ExcelTypeEnum excelType) throws Exception {
FileOutputStream fileOutputStream = new FileOutputStream(file);
EasyExcel.write(fileOutputStream, EncryptData.class).password("123456").excelType(excelType).sheet()
.doWrite(data());
fileOutputStream.close();
FileInputStream fileInputStream = new FileInputStream(file);
EasyExcel.read(fileInputStream, EncryptData.class, new EncryptDataListener()).password("123456").sheet()
.doRead();
}
private List<SimpleData> data() {
List<SimpleData> list = new ArrayList<SimpleData>();
for (int i = 0; i < 10; i++) {
SimpleData simpleData = new SimpleData();
simpleData.setName("姓名" + i);
list.add(simpleData);
}
return list;
}
}

14
src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsDataTest.java

@ -40,6 +40,16 @@ public class MultipleSheetsDataTest {
read(file03);
}
@Test
public void t03Read07All() {
readAll(file07);
}
@Test
public void t04Read03All() {
readAll(file03);
}
private void read(File file) {
MultipleSheetsListener multipleSheetsListener = new MultipleSheetsListener();
ExcelReader excelReader = EasyExcel.read(file, MultipleSheetsData.class, multipleSheetsListener).build();
@ -53,4 +63,8 @@ public class MultipleSheetsDataTest {
excelReader.finish();
}
private void readAll(File file) {
EasyExcel.read(file, MultipleSheetsData.class, new MultipleSheetsListener()).doReadAll();
}
}

1
src/test/java/com/alibaba/easyexcel/test/core/multiplesheets/MultipleSheetsListener.java

@ -27,6 +27,7 @@ public class MultipleSheetsListener extends AnalysisEventListener<MultipleSheets
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
LOGGER.debug("A form is read finished.");
Assert.assertEquals(list.get(0).getTitle(), "表1数据");
LOGGER.debug("All row:{}", JSON.toJSONString(list));
}

27
src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java

@ -72,7 +72,7 @@ public class ReadTest {
}
/**
* 读多个sheet,这里注意一个sheet不能读取多次多次读取需要重新读取文件
* 读多个或者全部sheet,这里注意一个sheet不能读取多次多次读取需要重新读取文件
* <p>
* 1. 创建excel对应的实体对象 参照{@link DemoData}
* <p>
@ -82,24 +82,21 @@ 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();
ReadSheet readSheet2 = EasyExcel.readSheet(1).build();
excelReader.read(readSheet1);
excelReader.read(readSheet2);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
// 读取全部sheet
// 这里需要注意 DemoDataListener的doAfterAllAnalysed 会在每个sheet读取完毕后调用一次。然后所有sheet都会往同一个DemoDataListener里面写
EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).doReadAll();
// 方法2 如果 sheet1 sheet2 数据不一致的话
// 读取部分sheet
fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
excelReader = EasyExcel.read(fileName).build();
ExcelReader 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);
ReadSheet readSheet1 =
EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
ReadSheet readSheet2 =
EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
// 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能
excelReader.read(readSheet1, readSheet2);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
}

7
src/test/java/com/alibaba/easyexcel/test/demo/write/DemoData.java

@ -2,6 +2,8 @@ package com.alibaba.easyexcel.test.demo.write;
import java.util.Date;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@ -19,4 +21,9 @@ public class DemoData {
private Date date;
@ExcelProperty("数字标题")
private Double doubleData;
/**
* 忽略这个字段
*/
@ExcelIgnore
private String ignore;
}

2
src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java

@ -57,7 +57,7 @@ public class WriteTest {
// 这里 需要指定写用哪个class去读
ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
excelWriter.write(data(), writeSheet,"12345");
excelWriter.write(data(), writeSheet);
// 进行加密
/// 千万别忘记finish 会帮忙关闭流
excelWriter.finish();

73
src/test/java/com/alibaba/easyexcel/test/temp/poi/Poi3Test.java

@ -0,0 +1,73 @@
package com.alibaba.easyexcel.test.temp.poi;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.util.FileUtils;
/**
* 测试poi
*
* @author Jiaju Zhuang
**/
@Ignore
public class Poi3Test {
private static final Logger LOGGER = LoggerFactory.getLogger(Poi3Test.class);
@Test
public void Encryption() throws Exception {
String file = TestFileUtil.getPath() + "large" + File.separator + "large07.xlsx";
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
Encryptor enc = info.getEncryptor();
enc.confirmPassword("foobaa");
OPCPackage opc = OPCPackage.open(new File(file), PackageAccess.READ_WRITE);
OutputStream os = enc.getDataStream(fs);
opc.save(os);
opc.close();
// Write out the encrypted version
FileOutputStream fos = new FileOutputStream("D:\\test\\99999999999.xlsx");
fs.writeFilesystem(fos);
fos.close();
fs.close();
}
@Test
public void Encryption2() throws Exception {
Biff8EncryptionKey.setCurrentUserPassword("123456");
POIFSFileSystem fs = new POIFSFileSystem(new File("d:/test/simple03.xls"), true);
HSSFWorkbook hwb = new HSSFWorkbook(fs.getRoot(), true);
Biff8EncryptionKey.setCurrentUserPassword(null);
System.out.println(hwb.getSheetAt(0).getSheetName());
}
}

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

@ -22,6 +22,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.util.TestFileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.util.FileUtils;
/**

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

@ -33,7 +33,7 @@ public class Wirte {
String fileName = TestFileUtil.getPath() + "t22" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel.write(fileName).sheet("模板").head(head()).doWrite(data());
EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
}
private List<List<String>> head() {

5
update.md

@ -2,10 +2,13 @@
* 新增支持导入、导出支持公式
* 新增支持读取单元格类型、写入指定单元格类型
* 支持通过模板填充数据
* 新增写支持 禁用头样式 autoHeadStyle
* 新增写支持 禁用头样式 `autoHeadStyle`
* 用map读取数据 空的单元格也会有个 null的数据
* 转换报错 能获取到对应的行号和列号
* 优化读取全部sheet方案
* 新增注解`ExcelIgnoreUnannotated` 支持忽略未加`ExcelProperty`注解的字段
* 支持导出加密 [Issue #361](https://github.com/alibaba/easyexcel/issues/361)
* 支持导入加密 [Issue #295](https://github.com/alibaba/easyexcel/issues/295)
# 2.0.5
* 优化07版超大文件读取方案

Loading…
Cancel
Save