diff --git a/pom.xml b/pom.xml
index f85fd40..0e5b790 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.alibaba
easyexcel
- 2.0.0-beta1
+ 2.0.0-beta2
jar
easyexcel
diff --git a/quickstart.md b/quickstart.md
index 6312800..7098784 100644
--- a/quickstart.md
+++ b/quickstart.md
@@ -1,5 +1,13 @@
# easyexcel核心功能
## 目录
+### 前言
+#### 关于@Data
+读写的对象都用到了[Lombok](https://www.projectlombok.org/),他会自动生成`get`,`set` ,如果不需要自己创建对象并生成`get`,`set` 。
+#### 以下功能目前不支持
+* 单个文件的并发写入、读取
+* 读取图片
+* 宏
+#### 开源项目不容易,如果觉得本项目对您的工作还是有帮助的话,请在右上角帮忙点个★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)
* [最简单的读](#simpleRead)
@@ -853,6 +861,67 @@ public class LongestMatchColumnWidthData {
![img](img/readme/quickstart/write/customHandlerWrite.png)
##### 对象
参照:[对象](#simpleWriteObject)
+##### 定义拦截器
+````java
+/**
+ * 自定义拦截器。对第一行第一列的头超链接到:https://github.com/alibaba/easyexcel
+ *
+ * @author Jiaju Zhuang
+ */
+public class CustomCellWriteHandler implements CellWriteHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CustomCellWriteHandler.class);
+
+ @Override
+ public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
+ Head head, int relativeRowIndex, boolean isHead) {
+
+ }
+
+ @Override
+ public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData,
+ Cell cell, Head head, int relativeRowIndex, boolean isHead) {
+ // 这里可以对cell进行任何操作
+ LOGGER.info("第{}行,第{}列写入完成。", cell.getRowIndex(), cell.getColumnIndex());
+ if (isHead && cell.getColumnIndex() == 0) {
+ CreationHelper createHelper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper();
+ Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL);
+ hyperlink.setAddress("https://github.com/alibaba/easyexcel");
+ cell.setHyperlink(hyperlink);
+ }
+ }
+
+}
+````
+````java
+/**
+ * 自定义拦截器.对第一列第一行和第二行的数据新增下拉框,显示 测试1 测试2
+ *
+ * @author Jiaju Zhuang
+ */
+public class CustomSheetWriteHandler implements SheetWriteHandler {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(CustomSheetWriteHandler.class);
+
+ @Override
+ public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
+
+ }
+
+ @Override
+ public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
+ LOGGER.info("第{}个Sheet写入成功。", writeSheetHolder.getSheetNo());
+
+ // 区间设置 第一列第一行和第二行的数据。由于第一行是头,所以第一、二行的数据实际上是第二三行
+ CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 2, 0, 0);
+ DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();
+ DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[] {"测试1", "测试2"});
+ DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
+ writeSheetHolder.getSheet().addValidationData(dataValidation);
+ }
+}
+
+````
##### 代码
```java
/**
diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
index dcf1d84..d21b8db 100644
--- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
+++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
@@ -116,6 +116,20 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
} catch (Throwable e) {
throw new ExcelAnalysisException("Can not close IO", e);
}
+ try {
+ if (readWorkbookHolder.getOpcPackage() != null) {
+ readWorkbookHolder.getOpcPackage().close();
+ }
+ } catch (Throwable e) {
+ throw new ExcelAnalysisException("Can not close IO", e);
+ }
+ try {
+ if (readWorkbookHolder.getPoifsFileSystem() != null) {
+ readWorkbookHolder.getPoifsFileSystem().close();
+ }
+ } catch (Throwable e) {
+ throw new ExcelAnalysisException("Can not close IO", e);
+ }
try {
if (analysisContext.readWorkbookHolder().getAutoCloseStream()
&& readWorkbookHolder.getInputStream() != null) {
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 996e33a..a5072a1 100644
--- a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
+++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
@@ -73,6 +73,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
this.analysisContext = context;
this.records = new TreeMap();
this.poifsFileSystem = poifsFileSystem;
+ analysisContext.readWorkbookHolder().setPoifsFileSystem(poifsFileSystem);
}
@Override
@@ -130,6 +131,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
thisColumn = handler.getColumn();
cellData = handler.getCellData();
if (cellData != null) {
+ cellData.checkEmpty();
records.put(thisColumn, cellData);
}
break;
diff --git a/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java
index 9d228d2..cca10f6 100644
--- a/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java
+++ b/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java
@@ -16,11 +16,11 @@ public class SharedStringsTableHandler extends DefaultHandler {
/**
* The final piece of data
*/
- private String currentData;
+ private StringBuilder currentData;
/**
* Current element data
*/
- private String currentElementData;
+ private StringBuilder currentElementData;
private ReadCache readCache;
@@ -30,22 +30,36 @@ public class SharedStringsTableHandler extends DefaultHandler {
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) {
- if (SI_TAG.equals(name)) {
- currentData = "";
+ if (T_TAG.equals(name)) {
+ currentElementData = null;
+ } else if (SI_TAG.equals(name)) {
+ currentData = null;
}
}
@Override
public void endElement(String uri, String localName, String name) {
if (T_TAG.equals(name)) {
- currentData += currentElementData;
+ if (currentElementData != null) {
+ if (currentData == null) {
+ currentData = new StringBuilder();
+ }
+ currentData.append(currentElementData);
+ }
} else if (SI_TAG.equals(name)) {
- readCache.put(currentData);
+ if (currentData == null) {
+ readCache.put(null);
+ } else {
+ readCache.put(currentData.toString());
+ }
}
}
@Override
public void characters(char[] ch, int start, int length) {
- currentElementData = new String(ch, start, length);
+ if (currentElementData == null) {
+ currentElementData = new StringBuilder();
+ }
+ currentElementData.append(new String(ch, start, length));
}
}
diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java
index 748306a..f16f926 100644
--- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java
+++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java
@@ -59,6 +59,7 @@ public class XlsxSaxAnalyser implements ExcelExecutor {
ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder();
OPCPackage pkg = readOpcPackage(readWorkbookHolder, decryptedStream);
+ readWorkbookHolder.setOpcPackage(pkg);
PackagePart sharedStringsTablePackagePart =
pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType()).get(0);
diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
index 671693b..0ee8ab3 100644
--- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
+++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
@@ -120,6 +120,7 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
} else if (currentCellData.getType() == CellDataTypeEnum.DIRECT_STRING) {
currentCellData.setType(CellDataTypeEnum.STRING);
}
+ currentCellData.checkEmpty();
curRowContent.put(curCol, currentCellData);
}
// This is a special form of string
@@ -130,6 +131,7 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
stringValue = stringValue.trim();
}
currentCellData.setStringValue(stringValue);
+ currentCellData.checkEmpty();
curRowContent.put(curCol, currentCellData);
}
}
diff --git a/src/main/java/com/alibaba/excel/metadata/BasicParameter.java b/src/main/java/com/alibaba/excel/metadata/BasicParameter.java
index dfcf782..89d7851 100644
--- a/src/main/java/com/alibaba/excel/metadata/BasicParameter.java
+++ b/src/main/java/com/alibaba/excel/metadata/BasicParameter.java
@@ -1,6 +1,5 @@
package com.alibaba.excel.metadata;
-import java.util.ArrayList;
import java.util.List;
import com.alibaba.excel.converters.Converter;
@@ -22,7 +21,7 @@ public class BasicParameter {
/**
* Custom type conversions override the default
*/
- private List customConverterList = new ArrayList();
+ private List customConverterList;
/**
* Automatic trim includes sheet name and content
*/
diff --git a/src/main/java/com/alibaba/excel/metadata/CellData.java b/src/main/java/com/alibaba/excel/metadata/CellData.java
index db73ce8..0a1ffeb 100644
--- a/src/main/java/com/alibaba/excel/metadata/CellData.java
+++ b/src/main/java/com/alibaba/excel/metadata/CellData.java
@@ -1,6 +1,7 @@
package com.alibaba.excel.metadata;
import com.alibaba.excel.enums.CellDataTypeEnum;
+import com.alibaba.excel.util.StringUtils;
/**
* Excel internal cell data
@@ -168,6 +169,31 @@ public class CellData {
this.dataFormatString = dataFormatString;
}
+ /**
+ * Ensure that the object does not appear null
+ */
+ public void checkEmpty() {
+ switch (type) {
+ case STRING:
+ case ERROR:
+ if (StringUtils.isEmpty(stringValue)) {
+ type = CellDataTypeEnum.EMPTY;
+ }
+ return;
+ case NUMBER:
+ if (doubleValue == null) {
+ type = CellDataTypeEnum.EMPTY;
+ }
+ return;
+ case BOOLEAN:
+ if (booleanValue == null) {
+ type = CellDataTypeEnum.EMPTY;
+ }
+ return;
+ default:
+ }
+ }
+
@Override
public String toString() {
switch (type) {
diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
index 2f117e1..a1200d5 100644
--- a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
+++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
@@ -137,8 +137,8 @@ public class ExcelHeadProperty {
continue;
}
if (customFiledMap.containsKey(excelProperty.index())) {
- throw new ExcelGenerateException("The index of " + customFiledMap.get(excelProperty.index()).getName()
- + " and " + field.getName() + " must be inconsistent");
+ throw new ExcelGenerateException("The index of '" + customFiledMap.get(excelProperty.index()).getName()
+ + "' and '" + field.getName() + "' must be inconsistent");
}
customFiledMap.put(excelProperty.index(), field);
}
diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
index bfcc050..9b77c8c 100644
--- a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
+++ b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java
@@ -6,6 +6,8 @@ import java.io.InputStream;
import java.util.HashSet;
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;
@@ -90,6 +92,14 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
* Prevent repeating sheet
*/
private Set hasReadSheet;
+ /**
+ * Package
+ */
+ private OPCPackage opcPackage;
+ /**
+ * File System
+ */
+ private POIFSFileSystem poifsFileSystem;
public ReadWorkbookHolder(ReadWorkbook readWorkbook) {
super(readWorkbook, null, readWorkbook.getConvertAllFiled());
@@ -232,6 +242,22 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
this.defaultReturnMap = defaultReturnMap;
}
+ public OPCPackage getOpcPackage() {
+ return opcPackage;
+ }
+
+ public void setOpcPackage(OPCPackage opcPackage) {
+ this.opcPackage = opcPackage;
+ }
+
+ public POIFSFileSystem getPoifsFileSystem() {
+ return poifsFileSystem;
+ }
+
+ public void setPoifsFileSystem(POIFSFileSystem poifsFileSystem) {
+ this.poifsFileSystem = poifsFileSystem;
+ }
+
@Override
public HolderEnum holderType() {
return HolderEnum.WORKBOOK;
diff --git a/src/main/java/com/alibaba/excel/util/BooleanUtils.java b/src/main/java/com/alibaba/excel/util/BooleanUtils.java
index afd1495..c09506b 100644
--- a/src/main/java/com/alibaba/excel/util/BooleanUtils.java
+++ b/src/main/java/com/alibaba/excel/util/BooleanUtils.java
@@ -10,6 +10,8 @@ public class BooleanUtils {
private static final String TRUE_NUMBER = "1";
private static final String FALSE_NUMBER = "0";
+ private BooleanUtils() {}
+
/**
* String to boolean
*
diff --git a/src/main/java/com/alibaba/excel/util/CollectionUtils.java b/src/main/java/com/alibaba/excel/util/CollectionUtils.java
index fff57ff..f413be1 100644
--- a/src/main/java/com/alibaba/excel/util/CollectionUtils.java
+++ b/src/main/java/com/alibaba/excel/util/CollectionUtils.java
@@ -5,11 +5,13 @@ import java.util.Map;
/**
* Collection utils
- *
+ *
* @author jipengfei
*/
public class CollectionUtils {
+ private CollectionUtils() {}
+
public static boolean isEmpty(Collection> collection) {
return (collection == null || collection.isEmpty());
}
diff --git a/src/main/java/com/alibaba/excel/util/FileUtils.java b/src/main/java/com/alibaba/excel/util/FileUtils.java
index 717ddfe..9738b50 100644
--- a/src/main/java/com/alibaba/excel/util/FileUtils.java
+++ b/src/main/java/com/alibaba/excel/util/FileUtils.java
@@ -25,6 +25,8 @@ public class FileUtils {
private static final String CACHE = "excache";
private static final int WRITE_BUFF_SIZE = 8192;
+ private FileUtils() {}
+
/**
* Reads the contents of a file into a byte array. * The file is always closed.
*
diff --git a/src/main/java/com/alibaba/excel/util/IoUtils.java b/src/main/java/com/alibaba/excel/util/IoUtils.java
index 9405c91..d590511 100644
--- a/src/main/java/com/alibaba/excel/util/IoUtils.java
+++ b/src/main/java/com/alibaba/excel/util/IoUtils.java
@@ -17,6 +17,8 @@ public class IoUtils {
*/
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
+ private IoUtils() {}
+
/**
* Gets the contents of an InputStream as a byte[].
*
diff --git a/src/main/java/com/alibaba/excel/util/PositionUtils.java b/src/main/java/com/alibaba/excel/util/PositionUtils.java
index 3151040..090bbdf 100644
--- a/src/main/java/com/alibaba/excel/util/PositionUtils.java
+++ b/src/main/java/com/alibaba/excel/util/PositionUtils.java
@@ -5,6 +5,8 @@ package com.alibaba.excel.util;
*/
public class PositionUtils {
+ private PositionUtils() {}
+
public static int getRow(String currentCellIndex) {
int row = 0;
if (currentCellIndex != null) {
diff --git a/src/main/java/com/alibaba/excel/util/StringUtils.java b/src/main/java/com/alibaba/excel/util/StringUtils.java
index 8210a19..25ed127 100644
--- a/src/main/java/com/alibaba/excel/util/StringUtils.java
+++ b/src/main/java/com/alibaba/excel/util/StringUtils.java
@@ -2,11 +2,13 @@ package com.alibaba.excel.util;
/**
* String utils
- *
+ *
* @author jipengfei
*/
public class StringUtils {
+ private StringUtils() {}
+
public static boolean isEmpty(Object str) {
return (str == null || "".equals(str));
}
diff --git a/src/main/java/com/alibaba/excel/util/StyleUtil.java b/src/main/java/com/alibaba/excel/util/StyleUtil.java
index 3031048..d0e1bd3 100644
--- a/src/main/java/com/alibaba/excel/util/StyleUtil.java
+++ b/src/main/java/com/alibaba/excel/util/StyleUtil.java
@@ -17,6 +17,8 @@ import com.alibaba.excel.write.metadata.style.WriteFont;
*/
public class StyleUtil {
+ private StyleUtil() {}
+
/**
* @param workbook
* @return
diff --git a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java
index 1fa7834..b9579b1 100644
--- a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java
+++ b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java
@@ -22,6 +22,8 @@ import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
*/
public class WorkBookUtil {
+ private WorkBookUtil() {}
+
public static Workbook createWorkBook(WriteWorkbookHolder writeWorkbookHolder)
throws IOException, InvalidFormatException {
if (ExcelTypeEnum.XLSX.equals(writeWorkbookHolder.getExcelType())) {
diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java
new file mode 100644
index 0000000..cba9bae
--- /dev/null
+++ b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java
@@ -0,0 +1,63 @@
+package com.alibaba.easyexcel.test.temp;
+
+import java.io.File;
+import java.io.FileInputStream;
+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.read.DemoData;
+import com.alibaba.easyexcel.test.demo.read.DemoDataListener;
+import com.alibaba.easyexcel.test.util.TestFileUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.ExcelReader;
+import com.alibaba.excel.read.metadata.ReadSheet;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.alibaba.fastjson.JSON;
+
+/**
+ * 临时测试
+ *
+ * @author Jiaju Zhuang
+ **/
+@Ignore
+public class Lock2Test {
+ private static final Logger LOGGER = LoggerFactory.getLogger(Lock2Test.class);
+
+ @Test
+ public void test() throws Exception {
+ File file = new File("D:\\test\\test001.xlsx");
+
+ List