diff --git a/pom.xml b/pom.xml index 0e5b790..5bf10d7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 2.0.0-beta2 + 2.0.0-beta3 jar easyexcel diff --git a/quickstart.md b/quickstart.md index 7098784..e84d070 100644 --- a/quickstart.md +++ b/quickstart.md @@ -7,6 +7,12 @@ * 单个文件的并发写入、读取 * 读取图片 * 宏 +#### 关于常见类解析 +* EasyExcel 入口类,用于构建开始各种操作 +* ExcelReaderBuilder ExcelWriterBuilder 构建出一个 ReadWorkbook WriteWorkbook,可以理解成一个excel对象,一个excel只要构建一个 +* ExcelReaderSheetBuilder ExcelWriterSheetBuilder 构建出一个 ReadSheet WriteSheet对象,可以理解成excel里面的一页,每一页都要构建一个 +* ReadListener 在每一行读取完毕后都会调用ReadListener来处理数据 +* WriteHandler 在每一个操作包括创建单元格、创建表格等都会调用WriteHandler来处理数据 #### 开源项目不容易,如果觉得本项目对您的工作还是有帮助的话,请在右上角帮忙点个★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) @@ -16,7 +22,10 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja * [日期、数字或者自定义格式转换](#converterRead) * [多行头](#complexHeaderRead) * [同步的返回](#synchronousRead) +* [读取表头数据](#headerRead) +* [数据转换等异常处理](#exceptionRead) * [web中的读](#webRead) + ### 写 DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java](/src/test/java/com/alibaba/easyexcel/test/demo/write/WriteTest.java) * [最简单的写](#simpleWrite) @@ -331,6 +340,88 @@ public class CustomStringStringConverter implements Converter { } ``` +### 读取表头数据 +##### excel示例 +参照:[excel示例](#simpleReadExcel) +##### 对象 +参照:[对象](#simpleReadObject) +##### 监听器 +参照:[监听器](#simpleReadListener) +里面多了一个方法,只要重写invokeHeadMap方法即可 +```java + /** + * 这里会一行行的返回头 + * + * @param headMap + * @param context + */ + @Override + public void invokeHeadMap(Map headMap, AnalysisContext context) { + LOGGER.info("解析到一条头数据:{}", JSON.toJSONString(headMap)); + } +``` +##### 代码 +```java + /** + * 读取表头数据 + * + *

+ * 1. 创建excel对应的实体对象 参照{@link DemoData} + *

+ * 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoHeadDataListener} + *

+ * 3. 直接读即可 + */ + @Test + public void headerRead() { + String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; + // 这里 需要指定读用哪个class去读,然后读取第一个sheet 然后千万别忘记 finish + EasyExcel.read(fileName, DemoData.class, new DemoHeadDataListener()).sheet().doRead(); + } +``` + +### 数据转换等异常处理 +##### excel示例 +参照:[excel示例](#simpleReadExcel) +##### 对象 +参照:[对象](#simpleReadObject) +##### 监听器 +参照:[监听器](#simpleReadListener) +里面多了一个方法,只要重写onException方法即可 +```java + /** + * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。 + * + * @param exception + * @param context + * @throws Exception + */ + @Override + public void onException(Exception exception, AnalysisContext context) { + LOGGER.error("解析失败,但是继续解析下一行", exception); + } +``` +##### 代码 +```java + /** + * 数据转换等异常处理 + * + *

+ * 1. 创建excel对应的实体对象 参照{@link DemoData} + *

+ * 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoHeadDataListener} + *

+ * 3. 直接读即可 + */ + @Test + public void exceptionRead() { + String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; + // 这里 需要指定读用哪个class去读,然后读取第一个sheet 然后千万别忘记 finish + EasyExcel.read(fileName, DemoData.class, new DemoHeadDataListener()).sheet().doRead(); + } +``` + + ### web中的读 ##### 示例代码 DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java](/src/test/java/com/alibaba/easyexcel/test/demo/web/WebTest.java) diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java index d21b8db..5adc237 100644 --- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java @@ -15,6 +15,7 @@ import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContextImpl; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelAnalysisStopException; +import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; @@ -113,40 +114,44 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { if (readWorkbookHolder.getReadCache() != null) { readWorkbookHolder.getReadCache().destroy(); } - } catch (Throwable e) { - throw new ExcelAnalysisException("Can not close IO", e); + } catch (Throwable t) { + throwCanNotCloseIo(t); } try { if (readWorkbookHolder.getOpcPackage() != null) { readWorkbookHolder.getOpcPackage().close(); } - } catch (Throwable e) { - throw new ExcelAnalysisException("Can not close IO", e); + } catch (Throwable t) { + throwCanNotCloseIo(t); } try { if (readWorkbookHolder.getPoifsFileSystem() != null) { readWorkbookHolder.getPoifsFileSystem().close(); } - } catch (Throwable e) { - throw new ExcelAnalysisException("Can not close IO", e); + } catch (Throwable t) { + throwCanNotCloseIo(t); } try { if (analysisContext.readWorkbookHolder().getAutoCloseStream() && readWorkbookHolder.getInputStream() != null) { readWorkbookHolder.getInputStream().close(); } - } catch (Throwable e) { - throw new ExcelAnalysisException("Can not close IO", e); + } catch (Throwable t) { + throwCanNotCloseIo(t); } try { if (readWorkbookHolder.getTempFile() != null) { FileUtils.delete(readWorkbookHolder.getTempFile()); } - } catch (Throwable e) { - throw new ExcelAnalysisException("Can not close IO", e); + } catch (Throwable t) { + throwCanNotCloseIo(t); } } + private void throwCanNotCloseIo(Throwable t) { + throw new ExcelAnalysisException("Can not close IO", t); + } + @Override public com.alibaba.excel.analysis.ExcelExecutor excelExecutor() { return excelExecutor; diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index ebe0d26..6ad7fcb 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -9,6 +9,7 @@ import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -343,39 +344,52 @@ public class WriteContextImpl implements WriteContext { if (writeWorkbookHolder == null) { return; } + try { writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream()); writeWorkbookHolder.getWorkbook().close(); - } catch (Throwable e) { - throw new ExcelGenerateException("Can not close IO", e); + } catch (Throwable t) { + throwCanNotCloseIo(t); + } + try { + Workbook workbook = writeWorkbookHolder.getWorkbook(); + if (workbook instanceof SXSSFWorkbook) { + ((SXSSFWorkbook)workbook).dispose(); + } + } catch (Throwable t) { + throwCanNotCloseIo(t); } try { if (writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getOutputStream() != null) { writeWorkbookHolder.getOutputStream().close(); } - } catch (Throwable e) { - throw new ExcelGenerateException("Can not close IO", e); + } catch (Throwable t) { + throwCanNotCloseIo(t); } try { if (writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getTemplateInputStream() != null) { writeWorkbookHolder.getTemplateInputStream().close(); } - } catch (Throwable e) { - throw new ExcelGenerateException("Can not close IO", e); + } catch (Throwable t) { + throwCanNotCloseIo(t); } try { if (!writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getFile() != null && writeWorkbookHolder.getOutputStream() != null) { writeWorkbookHolder.getOutputStream().close(); } - } catch (Throwable e) { - throw new ExcelGenerateException("Can not close IO", e); + } catch (Throwable t) { + throwCanNotCloseIo(t); } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Finished write."); } } + private void throwCanNotCloseIo(Throwable t) { + throw new ExcelGenerateException("Can not close IO", t); + } + @Override public Sheet getCurrentSheet() { return writeSheetHolder.getSheet(); diff --git a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java index 4d596db..89bca75 100644 --- a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java +++ b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java @@ -1,7 +1,11 @@ package com.alibaba.excel.event; +import java.util.Map; + import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.read.listener.ReadListener; +import com.alibaba.excel.util.ConverterUtils; /** * Receives the return of each piece of data parsed @@ -10,6 +14,19 @@ import com.alibaba.excel.read.listener.ReadListener; */ public abstract class AnalysisEventListener implements ReadListener { + @Override + public void invokeHead(Map headMap, AnalysisContext context) { + invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context.currentReadHolder()), context); + } + + /** + * Returns the header as a map.Override the current method to receive header data. + * + * @param headMap + * @param context + */ + public void invokeHeadMap(Map headMap, AnalysisContext context) {} + /** * All listeners receive this method when any one Listener does an error report. If an exception is thrown here, the * entire read will terminate. diff --git a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java index bf4a8cf..522369e 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java +++ b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java @@ -18,6 +18,7 @@ import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.read.metadata.holder.ReadHolder; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; +import com.alibaba.excel.util.ConverterUtils; import net.sf.cglib.beans.BeanMap; @@ -28,6 +29,9 @@ import net.sf.cglib.beans.BeanMap; */ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener> { + @Override + public void invokeHead(Map cellDataMap, AnalysisContext context) {} + @Override public void invoke(Map cellDataMap, AnalysisContext context) { ReadHolder currentReadHolder = context.currentReadHolder(); @@ -48,7 +52,7 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener map.put(entry.getKey(), null); continue; } - map.put(entry.getKey(), (String)convertValue(cellData, String.class, null, + map.put(entry.getKey(), (String)ConverterUtils.convertToJavaObject(cellData, String.class, null, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration())); } return map; @@ -61,8 +65,8 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener list.add(null); continue; } - list.add((String)convertValue(cellData, String.class, null, currentReadHolder.converterMap(), - currentReadHolder.globalConfiguration())); + list.add((String)ConverterUtils.convertToJavaObject(cellData, String.class, null, + currentReadHolder.converterMap(), currentReadHolder.globalConfiguration())); } return list; } @@ -90,8 +94,8 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener continue; } ExcelContentProperty excelContentProperty = contentPropertyMap.get(index); - Object value = convertValue(cellData, excelContentProperty.getField().getType(), excelContentProperty, - currentReadHolder.converterMap(), currentReadHolder.globalConfiguration()); + Object value = ConverterUtils.convertToJavaObject(cellData, excelContentProperty.getField().getType(), + excelContentProperty, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration()); if (value != null) { map.put(excelContentProperty.getField().getName(), value); } @@ -100,29 +104,6 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener return resultModel; } - private Object convertValue(CellData cellData, Class clazz, ExcelContentProperty contentProperty, - Map converterMap, GlobalConfiguration globalConfiguration) { - if (clazz == CellData.class) { - return new CellData(cellData); - } - Converter converter = null; - if (contentProperty != null) { - converter = contentProperty.getConverter(); - } - if (converter == null) { - converter = converterMap.get(ConverterKeyBuild.buildKey(clazz, cellData.getType())); - } - if (converter == null) { - throw new ExcelDataConvertException( - "Converter not found, convert " + cellData.getType() + " to " + clazz.getName()); - } - try { - return converter.convertToJavaData(cellData, contentProperty, globalConfiguration); - } catch (Exception e) { - throw new ExcelDataConvertException("Convert data " + cellData + " to " + clazz + " error ", e); - } - } - @Override public void doAfterAllAnalysed(AnalysisContext context) {} } diff --git a/src/main/java/com/alibaba/excel/read/listener/ReadListener.java b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java index 09ce3c7..142c531 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ReadListener.java +++ b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java @@ -1,7 +1,10 @@ package com.alibaba.excel.read.listener; +import java.util.Map; + import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.Listener; +import com.alibaba.excel.metadata.CellData; /** * Interface to listen for read results @@ -20,7 +23,15 @@ public interface ReadListener extends Listener { void onException(Exception exception, AnalysisContext context) throws Exception; /** - * when analysis one row trigger invoke function. + * When analysis one head row trigger invoke function. + * + * @param headMap + * @param context + */ + void invokeHead(Map headMap, AnalysisContext context); + + /** + * When analysis one row trigger invoke function. * * @param data * one row value. Is is same as {@link AnalysisContext#readRowHolder()} diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java index 61aa813..4e7041e 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/AbstractReadHolder.java @@ -26,6 +26,7 @@ import com.alibaba.excel.read.listener.ReadListenerRegistryCenter; import com.alibaba.excel.read.listener.event.AnalysisFinishEvent; import com.alibaba.excel.read.metadata.ReadBasicParameter; import com.alibaba.excel.read.metadata.property.ExcelReadHeadProperty; +import com.alibaba.excel.util.ConverterUtils; import com.alibaba.excel.util.StringUtils; /** @@ -118,8 +119,11 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH Map cellDataMap = event.getAnalysisResult(); ReadRowHolder readRowHolder = analysisContext.readRowHolder(); readRowHolder.setCurrentRowAnalysisResult(cellDataMap); + int rowIndex = readRowHolder.getRowIndex(); + int headRowNumber = analysisContext.readSheetHolder().getHeadRowNumber(); - if (readRowHolder.getRowIndex() >= analysisContext.readSheetHolder().getHeadRowNumber()) { + if (rowIndex >= headRowNumber) { + // Now is data for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) { try { readListener.invoke(readRowHolder.getCurrentRowAnalysisResult(), analysisContext); @@ -136,11 +140,29 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH throw new ExcelAnalysisStopException(); } } - return; - } - // Now is header - if (analysisContext.readSheetHolder().getHeadRowNumber().equals(readRowHolder.getRowIndex() + 1)) { - buildHead(analysisContext, cellDataMap); + } else { + // Last head column + if (headRowNumber == rowIndex + 1) { + buildHead(analysisContext, cellDataMap); + } + + // Now is header + for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) { + try { + readListener.invokeHead(cellDataMap, analysisContext); + } catch (Exception e) { + for (ReadListener readListenerException : analysisContext.currentReadHolder().readListenerList()) { + try { + readListenerException.onException(e, analysisContext); + } catch (Exception exception) { + throw new ExcelAnalysisException("Listen error!", exception); + } + } + } + if (!readListener.hasNext(analysisContext)) { + throw new ExcelAnalysisStopException(); + } + } } } @@ -155,7 +177,8 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH if (!HeadKindEnum.CLASS.equals(analysisContext.currentReadHolder().excelReadHeadProperty().getHeadKind())) { return; } - Map dataMap = buildStringMap(cellDataMap, analysisContext.currentReadHolder()); + Map dataMap = + ConverterUtils.convertToStringMap(cellDataMap, analysisContext.currentReadHolder()); ExcelReadHeadProperty excelHeadPropertyData = analysisContext.readSheetHolder().excelReadHeadProperty(); Map headMapData = excelHeadPropertyData.getHeadMap(); Map contentPropertyMapData = excelHeadPropertyData.getContentPropertyMap(); @@ -192,30 +215,6 @@ public abstract class AbstractReadHolder extends AbstractHolder implements ReadH excelHeadPropertyData.setContentPropertyMap(tmpContentPropertyMap); } - private Map buildStringMap(Map cellDataMap, ReadHolder readHolder) { - Map stringMap = new HashMap(cellDataMap.size() * 4 / 3 + 1); - for (Map.Entry entry : cellDataMap.entrySet()) { - CellData cellData = entry.getValue(); - if (cellData.getType() == CellDataTypeEnum.EMPTY) { - stringMap.put(entry.getKey(), null); - continue; - } - Converter converter = - readHolder.converterMap().get(ConverterKeyBuild.buildKey(String.class, cellData.getType())); - if (converter == null) { - throw new ExcelDataConvertException( - "Converter not found, convert " + cellData.getType() + " to String"); - } - try { - stringMap.put(entry.getKey(), - (String)(converter.convertToJavaData(cellData, null, readHolder.globalConfiguration()))); - } catch (Exception e) { - throw new ExcelDataConvertException("Convert data " + cellData + " to String error ", e); - } - } - return stringMap; - } - public List getReadListenerList() { return readListenerList; } diff --git a/src/main/java/com/alibaba/excel/util/ConverterUtils.java b/src/main/java/com/alibaba/excel/util/ConverterUtils.java new file mode 100644 index 0000000..7445b4c --- /dev/null +++ b/src/main/java/com/alibaba/excel/util/ConverterUtils.java @@ -0,0 +1,87 @@ +package com.alibaba.excel.util; + +import java.util.HashMap; +import java.util.Map; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.converters.ConverterKeyBuild; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.exception.ExcelDataConvertException; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.read.metadata.holder.ReadHolder; + +/** + * Converting objects + * + * @author Jiaju Zhuang + **/ +public class ConverterUtils { + + private ConverterUtils() {} + + /** + * Convert it into a String map + * + * @param cellDataMap + * @param readHolder + * @return + */ + public static Map convertToStringMap(Map cellDataMap, ReadHolder readHolder) { + Map stringMap = new HashMap(cellDataMap.size() * 4 / 3 + 1); + for (Map.Entry entry : cellDataMap.entrySet()) { + CellData cellData = entry.getValue(); + if (cellData.getType() == CellDataTypeEnum.EMPTY) { + stringMap.put(entry.getKey(), null); + continue; + } + Converter converter = + readHolder.converterMap().get(ConverterKeyBuild.buildKey(String.class, cellData.getType())); + if (converter == null) { + throw new ExcelDataConvertException( + "Converter not found, convert " + cellData.getType() + " to String"); + } + try { + stringMap.put(entry.getKey(), + (String)(converter.convertToJavaData(cellData, null, readHolder.globalConfiguration()))); + } catch (Exception e) { + throw new ExcelDataConvertException("Convert data " + cellData + " to String error ", e); + } + } + return stringMap; + } + + /** + * Convert it into a Java object + * + * @param cellData + * @param clazz + * @param contentProperty + * @param converterMap + * @param globalConfiguration + * @return + */ + public static Object convertToJavaObject(CellData cellData, Class clazz, ExcelContentProperty contentProperty, + Map converterMap, GlobalConfiguration globalConfiguration) { + if (clazz == CellData.class) { + return new CellData(cellData); + } + Converter converter = null; + if (contentProperty != null) { + converter = contentProperty.getConverter(); + } + if (converter == null) { + converter = converterMap.get(ConverterKeyBuild.buildKey(clazz, cellData.getType())); + } + if (converter == null) { + throw new ExcelDataConvertException( + "Converter not found, convert " + cellData.getType() + " to " + clazz.getName()); + } + try { + return converter.convertToJavaData(cellData, contentProperty, globalConfiguration); + } catch (Exception e) { + throw new ExcelDataConvertException("Convert data " + cellData + " to " + clazz + " error ", e); + } + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataTest.java index 62fea8a..5acd5db 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationDataTest.java @@ -27,12 +27,12 @@ public class AnnotationDataTest { } @Test - public void T01ReadAndWrite07() throws Exception { + public void t01ReadAndWrite07() throws Exception { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() throws Exception { + public void t02ReadAndWrite03() throws Exception { readAndWrite(file03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameDataTest.java index 148f719..cd069c8 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/annotation/AnnotationIndexAndNameDataTest.java @@ -27,12 +27,12 @@ public class AnnotationIndexAndNameDataTest { } @Test - public void T01ReadAndWrite07() { + public void t01ReadAndWrite07() { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() { + public void t02ReadAndWrite03() { readAndWrite(file03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityDataTest.java index 49af7fe..258f055 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityDataTest.java @@ -42,12 +42,12 @@ public class CompatibilityDataTest { } @Test - public void T01ReadAndWrite07() throws Exception { + public void t01ReadAndWrite07() throws Exception { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() throws Exception { + public void t02ReadAndWrite03() throws Exception { readAndWrite(file03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityParameterDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityParameterDataTest.java index d075f33..2e3b735 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityParameterDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/compatibility/CompatibilityParameterDataTest.java @@ -31,7 +31,7 @@ public class CompatibilityParameterDataTest { } @Test - public void T01ReadAndWrite() throws Exception { + public void t01ReadAndWrite() throws Exception { readAndWrite1(file); readAndWrite2(file); readAndWrite3(file); diff --git a/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataTest.java index a223e25..a339e9e 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/converter/ConverterDataTest.java @@ -38,12 +38,12 @@ public class ConverterDataTest { } @Test - public void T01ReadAndWrite07() throws Exception { + public void t01ReadAndWrite07() throws Exception { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() throws Exception { + public void t02ReadAndWrite03() throws Exception { readAndWrite(file03); } @@ -53,22 +53,22 @@ public class ConverterDataTest { } @Test - public void T03ReadAllConverter07() { + public void t03ReadAllConverter07() { readAllConverter("converter" + File.separator + "converter07.xlsx"); } @Test - public void T04ReadAllConverter03() { + public void t04ReadAllConverter03() { readAllConverter("converter" + File.separator + "converter03.xls"); } @Test - public void T05WriteImage07() throws Exception { + public void t05WriteImage07() throws Exception { writeImage(fileImage07); } @Test - public void T06WriteImage03() throws Exception { + public void t06WriteImage03() throws Exception { writeImage(fileImage03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataTest.java index 93210cf..f52549d 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/exception/ExceptionDataTest.java @@ -31,12 +31,12 @@ public class ExceptionDataTest { } @Test - public void T01ReadAndWrite07() throws Exception { + public void t01ReadAndWrite07() throws Exception { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() throws Exception { + public void t02ReadAndWrite03() throws Exception { readAndWrite(file03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/head/ComplexHeadDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/head/ComplexHeadDataTest.java index 9e654fd..f893684 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/head/ComplexHeadDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/head/ComplexHeadDataTest.java @@ -26,12 +26,12 @@ public class ComplexHeadDataTest { } @Test - public void T01ReadAndWrite07() { + public void t01ReadAndWrite07() { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() { + public void t02ReadAndWrite03() { readAndWrite(file03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataTest.java index 9b5330d..6e63a0b 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/head/ListHeadDataTest.java @@ -28,12 +28,12 @@ public class ListHeadDataTest { } @Test - public void T01ReadAndWrite07() throws Exception { + public void t01ReadAndWrite07() throws Exception { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() throws Exception { + public void t02ReadAndWrite03() throws Exception { readAndWrite(file03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/head/NoHeadDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/head/NoHeadDataTest.java index 934750c..a62adbb 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/head/NoHeadDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/head/NoHeadDataTest.java @@ -26,12 +26,12 @@ public class NoHeadDataTest { } @Test - public void T01ReadAndWrite07() { + public void t01ReadAndWrite07() { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() { + public void t02ReadAndWrite03() { readAndWrite(file03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/parameter/ParameterDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/parameter/ParameterDataTest.java index cc97cd0..c7c305d 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/parameter/ParameterDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/parameter/ParameterDataTest.java @@ -35,7 +35,7 @@ public class ParameterDataTest { } @Test - public void T01ReadAndWrite() throws Exception { + public void t01ReadAndWrite() throws Exception { readAndWrite1(); readAndWrite2(); readAndWrite3(); diff --git a/src/test/java/com/alibaba/easyexcel/test/core/repetition/RepetitionDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/repetition/RepetitionDataTest.java index 5005764..4c0d8aa 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/repetition/RepetitionDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/repetition/RepetitionDataTest.java @@ -38,12 +38,12 @@ public class RepetitionDataTest { } @Test - public void T01ReadAndWrite07() { + public void t01ReadAndWrite07() { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() { + public void t02ReadAndWrite03() { readAndWrite(file03); } @@ -57,12 +57,12 @@ public class RepetitionDataTest { } @Test - public void T03ReadAndWriteTable07() { + public void t03ReadAndWriteTable07() { readAndWriteTable(fileTable07); } @Test - public void T04ReadAndWriteTable03() { + public void t04ReadAndWriteTable03() { readAndWriteTable(fileTable03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataListener.java b/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataListener.java index 757cb07..b8925f8 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataListener.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataListener.java @@ -2,6 +2,7 @@ package com.alibaba.easyexcel.test.core.simple; import java.util.ArrayList; import java.util.List; +import java.util.Map; import org.junit.Assert; import org.slf4j.Logger; @@ -18,6 +19,12 @@ public class SimpleDataListener extends AnalysisEventListener { private static final Logger LOGGER = LoggerFactory.getLogger(SimpleDataListener.class); List list = new ArrayList(); + @Override + public void invokeHeadMap(Map headMap, AnalysisContext context) { + LOGGER.debug("Head is:{}", JSON.toJSONString(headMap)); + Assert.assertEquals(headMap.get(0), "姓名"); + } + @Override public void invoke(SimpleData data, AnalysisContext context) { list.add(data); diff --git a/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java index fee56e5..2d3c75b 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/simple/SimpleDataTest.java @@ -30,12 +30,12 @@ public class SimpleDataTest { } @Test - public void T01ReadAndWrite07() { + public void t01ReadAndWrite07() { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() { + public void t02ReadAndWrite03() { readAndWrite(file03); } @@ -45,17 +45,17 @@ public class SimpleDataTest { } @Test - public void T03SynchronousRead07() { + public void t03SynchronousRead07() { synchronousRead(file07); } @Test - public void T04SynchronousRead03() { + public void t04SynchronousRead03() { synchronousRead(file03); } @Test - public void T05SheetNameRead07() { + public void t05SheetNameRead07() { EasyExcel.read(TestFileUtil.readFile("simple" + File.separator + "simple07.xlsx"), SimpleData.class, new SimpleDataSheetNameListener()).sheet("simple").doRead(); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataTest.java index d52aee7..4e17094 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/style/StyleDataTest.java @@ -44,17 +44,17 @@ public class StyleDataTest { } @Test - public void T01ReadAndWrite07() { + public void t01ReadAndWrite07() { readAndWrite(file07); } @Test - public void T02ReadAndWrite03() { + public void t02ReadAndWrite03() { readAndWrite(file03); } @Test - public void T03AbstractVerticalCellStyleStrategy() { + public void t03AbstractVerticalCellStyleStrategy() { AbstractVerticalCellStyleStrategy verticalCellStyleStrategy = new AbstractVerticalCellStyleStrategy() { @Override protected WriteCellStyle headCellStyle(Head head) { @@ -112,7 +112,7 @@ public class StyleDataTest { } @Test - public void T04LoopMergeStrategy() { + public void t04LoopMergeStrategy() { EasyExcel.write(file07, StyleData.class).sheet().registerWriteHandler(new LoopMergeStrategy(2, 1)) .doWrite(data10()); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataTest.java index 369bc8b..adf6313 100644 --- a/src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/core/template/TemplateDataTest.java @@ -29,12 +29,12 @@ public class TemplateDataTest { } @Test - public void T01ReadAndWrite07() { + public void t01ReadAndWrite07() { readAndWrite07(file07); } @Test - public void T02ReadAndWrite03() { + public void t02ReadAndWrite03() { readAndWrite03(file03); } diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java b/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java new file mode 100644 index 0000000..bc55052 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/demo/read/DemoHeadDataListener.java @@ -0,0 +1,73 @@ +package com.alibaba.easyexcel.test.demo.read; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +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 DemoHeadDataListener extends AnalysisEventListener { + private static final Logger LOGGER = LoggerFactory.getLogger(DemoHeadDataListener.class); + /** + * 每隔5条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 + */ + private static final int BATCH_COUNT = 5; + List list = new ArrayList(); + + /** + * 在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行。 + * + * @param exception + * @param context + * @throws Exception + */ + @Override + public void onException(Exception exception, AnalysisContext context) { + LOGGER.error("解析失败,但是继续解析下一行", exception); + } + + /** + * 这里会一行行的返回头 + * + * @param headMap + * @param context + */ + @Override + public void invokeHeadMap(Map headMap, AnalysisContext context) { + LOGGER.info("解析到一条头数据:{}", JSON.toJSONString(headMap)); + } + + @Override + public void invoke(DemoData data, AnalysisContext context) { + LOGGER.info("解析到一条数据:{}", JSON.toJSONString(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("存储数据库成功!"); + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java b/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java index 90524d3..b65f99e 100644 --- a/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/demo/read/ReadTest.java @@ -134,6 +134,40 @@ public class ReadTest { .headRowNumber(1).doRead(); } + /** + * 读取表头数据 + * + *

+ * 1. 创建excel对应的实体对象 参照{@link DemoData} + *

+ * 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoHeadDataListener} + *

+ * 3. 直接读即可 + */ + @Test + public void headerRead() { + String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; + // 这里 需要指定读用哪个class去读,然后读取第一个sheet 然后千万别忘记 finish + EasyExcel.read(fileName, DemoData.class, new DemoHeadDataListener()).sheet().doRead(); + } + + /** + * 数据转换等异常处理 + * + *

+ * 1. 创建excel对应的实体对象 参照{@link DemoData} + *

+ * 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoHeadDataListener} + *

+ * 3. 直接读即可 + */ + @Test + public void exceptionRead() { + String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx"; + // 这里 需要指定读用哪个class去读,然后读取第一个sheet 然后千万别忘记 finish + EasyExcel.read(fileName, DemoData.class, new DemoHeadDataListener()).sheet().doRead(); + } + /** * 同步的返回,不推荐使用,如果数据量大会把数据放到内存里面 */ diff --git a/update.md b/update.md index 7f672d5..e9e7d5e 100644 --- a/update.md +++ b/update.md @@ -1,3 +1,7 @@ +# 2.0.0-beta3 +* 导出完成移除临时目录 [Issue #386](https://github.com/alibaba/easyexcel/issues/386) +* 新增读取返回头数据 + # 2.0.0-beta2 * 加速gc回收 [Issue #511](https://github.com/alibaba/easyexcel/issues/511) * 修改空字符串读取可能读取上个字段的数据的bug