From c8d64352d63ac3b78756d94addedeab9e5d600de Mon Sep 17 00:00:00 2001 From: zhuangjiaju Date: Thu, 18 Jul 2019 22:13:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=BB=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/alibaba/excel/ExcelReader.java | 187 ++++++++++----- .../java/com/alibaba/excel/ExcelWriter.java | 4 +- .../excel/analysis/BaseSaxAnalyser.java | 112 --------- .../alibaba/excel/analysis/ExcelAnalyser.java | 22 +- .../excel/analysis/ExcelAnalyserImpl.java | 107 +++------ .../alibaba/excel/analysis/ExcelExecutor.java | 18 ++ .../excel/analysis/v03/XlsSaxAnalyser.java | 65 +++-- .../v07/SharedStringsTableHandler.java | 10 +- .../analysis/v07/XlsxHandlerFactory.java | 19 +- .../excel/analysis/v07/XlsxRowHandler.java | 6 +- .../excel/analysis/v07/XlsxSaxAnalyser.java | 222 +++++++----------- .../v07/handlers/DefaultCellHandler.java | 11 +- .../handlers/ProcessResultCellHandler.java | 22 +- .../java/com/alibaba/excel/cache/Cache.java | 27 --- .../java/com/alibaba/excel/cache/Ehcache.java | 4 +- .../com/alibaba/excel/cache/Ehcache2.java | 15 +- .../com/alibaba/excel/cache/EhcacheFile.java | 2 +- .../com/alibaba/excel/cache/EhcacheMix.java | 2 +- .../com/alibaba/excel/cache/ReadCache.java | 34 +++ ....java => SharedStringsTableReadCache.java} | 4 +- .../excel/context/AnalysisContext.java | 116 +++------ .../excel/context/AnalysisContextImpl.java | 193 +++------------ .../alibaba/excel/context/WriteContext.java | 4 +- .../excel/context/WriteContextImpl.java | 54 ++--- .../converters/ConverterRegistryCenter.java | 9 - .../converters/date/DateNumberConverter.java | 8 +- .../converters/date/DateStringConverter.java | 4 +- .../string/StringNumberConverter.java | 2 +- .../excel/event/AnalysisEventListener.java | 8 +- .../event/AnalysisEventRegistryCenter.java | 35 --- .../event/EachRowAnalysisFinishEvent.java | 1 + .../excel/event/ModelBuildEventListener.java | 81 ------- .../excel/metadata/BasicParameter.java | 26 +- .../java/com/alibaba/excel/metadata/Head.java | 13 +- .../com/alibaba/excel/metadata/Workbook.java | 43 ++++ ...r.java => AbstractWriteConfiguration.java} | 204 ++++++++++++++-- .../metadata/holder/ReadConfiguration.java | 39 +++ .../excel/metadata/holder/SheetHolder.java | 114 ++++++--- .../excel/metadata/holder/TableHolder.java | 54 +++-- .../excel/metadata/holder/WorkbookHolder.java | 219 ++++++++++++++--- ...nSelector.java => WriteConfiguration.java} | 4 +- .../property/ExcelContentProperty.java | 14 ++ .../metadata/property/ExcelHeadProperty.java | 60 ++--- .../read/builder/ExcelReaderBuilder.java | 21 ++ .../listener/ModelBuildEventListener.java | 98 ++++++++ .../listener}/ReadListener.java | 19 +- .../listener/ReadListenerRegistryCenter.java | 35 +++ .../alibaba/excel/support/ExcelTypeEnum.java | 41 ++-- .../util/{POITempFile.java => FileUtils.java} | 45 +++- .../com/alibaba/excel/util/NumberUtils.java | 2 +- .../com/alibaba/excel/util/WorkBookUtil.java | 28 ++- .../alibaba/excel/write/ExcelBuilderImpl.java | 34 +-- .../write/builder/ExcelWriterBuilder.java | 22 +- 53 files changed, 1406 insertions(+), 1137 deletions(-) delete mode 100644 src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java create mode 100644 src/main/java/com/alibaba/excel/analysis/ExcelExecutor.java delete mode 100644 src/main/java/com/alibaba/excel/cache/Cache.java create mode 100644 src/main/java/com/alibaba/excel/cache/ReadCache.java rename src/main/java/com/alibaba/excel/cache/{SharedStringsTableCache.java => SharedStringsTableReadCache.java} (79%) delete mode 100644 src/main/java/com/alibaba/excel/converters/ConverterRegistryCenter.java delete mode 100644 src/main/java/com/alibaba/excel/event/AnalysisEventRegistryCenter.java delete mode 100644 src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java rename src/main/java/com/alibaba/excel/metadata/holder/{AbstractConfigurationSelector.java => AbstractWriteConfiguration.java} (60%) create mode 100644 src/main/java/com/alibaba/excel/metadata/holder/ReadConfiguration.java rename src/main/java/com/alibaba/excel/metadata/holder/{ConfigurationSelector.java => WriteConfiguration.java} (93%) create mode 100644 src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java create mode 100644 src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java rename src/main/java/com/alibaba/excel/{event => read/listener}/ReadListener.java (59%) create mode 100644 src/main/java/com/alibaba/excel/read/listener/ReadListenerRegistryCenter.java rename src/main/java/com/alibaba/excel/util/{POITempFile.java => FileUtils.java} (55%) diff --git a/src/main/java/com/alibaba/excel/ExcelReader.java b/src/main/java/com/alibaba/excel/ExcelReader.java index a6c320a..6cfecbd 100644 --- a/src/main/java/com/alibaba/excel/ExcelReader.java +++ b/src/main/java/com/alibaba/excel/ExcelReader.java @@ -3,11 +3,16 @@ package com.alibaba.excel; import java.io.InputStream; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.alibaba.excel.analysis.ExcelAnalyser; import com.alibaba.excel.analysis.ExcelAnalyserImpl; +import com.alibaba.excel.analysis.ExcelExecutor; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.parameter.AnalysisParam; import com.alibaba.excel.support.ExcelTypeEnum; @@ -18,34 +23,42 @@ import com.alibaba.excel.support.ExcelTypeEnum; * @author jipengfei */ public class ExcelReader { + private static final Logger LOGGER = LoggerFactory.getLogger(ExcelReader.class); /** * Analyser */ - private ExcelAnalyser analyser; + private ExcelAnalyser excelAnalyser; + + private boolean finished = false; /** * Create new reader * - * @param in the POI filesystem that contains the Workbook stream - * @param excelTypeEnum 03 or 07 + * @param in + * the POI filesystem that contains the Workbook stream + * @param excelTypeEnum + * 03 or 07 * @param customContent - * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext - * @param eventListener Callback method after each row is parsed. + * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext + * @param eventListener + * Callback method after each row is parsed. */ @Deprecated public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent, - AnalysisEventListener eventListener) { + AnalysisEventListener eventListener) { this(in, excelTypeEnum, customContent, eventListener, true); } /** * Create new reader * - * @param in the POI filesystem that contains the Workbook stream + * @param in + * the POI filesystem that contains the Workbook stream * @param customContent - * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext - * @param eventListener Callback method after each row is parsed + * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext + * @param eventListener + * Callback method after each row is parsed */ public ExcelReader(InputStream in, Object customContent, AnalysisEventListener eventListener) { this(in, customContent, eventListener, null, true); @@ -54,21 +67,25 @@ public class ExcelReader { /** * Create new reader * - * @param in the POI filesystem that contains the Workbook stream + * @param in + * the POI filesystem that contains the Workbook stream * @param customContent - * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext - * @param eventListener Callback method after each row is parsed + * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext + * @param eventListener + * Callback method after each row is parsed */ public ExcelReader(InputStream in, Object customContent, AnalysisEventListener eventListener, - List converters) { + List converters) { this(in, customContent, eventListener, converters, true); } /** * Create new reader * - * @param param old param Deprecated - * @param eventListener Callback method after each row is parsed. + * @param param + * old param Deprecated + * @param eventListener + * Callback method after each row is parsed. */ @Deprecated public ExcelReader(AnalysisParam param, AnalysisEventListener eventListener) { @@ -78,19 +95,22 @@ public class ExcelReader { /** * Create new reader * - * @param in the POI filesystem that contains the Workbook stream - * @param excelTypeEnum 03 or 07 + * @param in + * the POI filesystem that contains the Workbook stream + * @param excelTypeEnum + * 03 or 07 * @param customContent - * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext - * @param eventListener Callback method after each row is parsed. - * @param trim The content of the form is empty and needs to be empty. The purpose is to be - * fault-tolerant, because there are often table contents with spaces that can not be - * converted into custom types. For example: '1234 ' contain a space cannot be converted - * to int. + * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext + * @param eventListener + * Callback method after each row is parsed. + * @param trim + * The content of the form is empty and needs to be empty. The purpose is to be fault-tolerant, because + * there are often table contents with spaces that can not be converted into custom types. For example: + * '1234 ' contain a space cannot be converted to int. */ @Deprecated public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent, - AnalysisEventListener eventListener, boolean trim) { + AnalysisEventListener eventListener, boolean trim) { this(in, excelTypeEnum, customContent, eventListener, null, trim); } @@ -99,31 +119,30 @@ public class ExcelReader { * * @param in * @param customContent - * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext + * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext * @param eventListener - * @param trim The content of the form is empty and needs to be empty. The purpose is to be - * fault-tolerant, because there are often table contents with spaces that can not be - * converted into custom types. For example: '1234 ' contain a space cannot be converted - * to int. + * @param trim + * The content of the form is empty and needs to be empty. The purpose is to be fault-tolerant, because + * there are often table contents with spaces that can not be converted into custom types. For example: + * '1234 ' contain a space cannot be converted to int. */ public ExcelReader(InputStream in, Object customContent, AnalysisEventListener eventListener, - List converters, boolean trim) { + List converters, boolean trim) { this(in, ExcelTypeEnum.valueOf(in), customContent, eventListener, converters, trim); } public ExcelReader(InputStream in, Object excelTypeEnum, AnalysisEventListener eventListener, - boolean trim) { + boolean trim) { this(in, ExcelTypeEnum.valueOf(in), null, eventListener, null, trim); } public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent, - AnalysisEventListener eventListener, List converters, boolean trim) { + AnalysisEventListener eventListener, List converters, boolean trim) { validateParam(in, eventListener); analyser = new ExcelAnalyserImpl(in, excelTypeEnum, customContent, eventListener, trim); initConverters(analyser, converters); } - private void initConverters(ExcelAnalyser analyser, List converters) { if (converters != null && converters.size() > 0) { for (Converter c : converters) { @@ -136,58 +155,118 @@ public class ExcelReader { * Parse all sheet content by default */ public void read() { - read(null, null);; + ExcelExecutor excelExecutor = excelAnalyser.excelExecutor(); + if (excelExecutor.sheetList().isEmpty()) { + LOGGER.warn("Excel doesn't have any sheets."); + return; + } + for (Sheet sheet : excelExecutor.sheetList()) { + read(sheet); + } } /** * Parse the specified sheet,SheetNo start from 1 * - * @param sheet Read sheet + * @param sheet + * Read sheet */ public void read(Sheet sheet) { - read(sheet, null); + checkFinished(); + excelAnalyser.analysis(sheet); } /** * Parse the specified sheet * - * @param sheet Read sheet - * @param clazz object parsed into each row of value + * @param sheet + * Read sheet + * @param clazz + * object parsed into each row of value + * + * @deprecated Set the class in the sheet before read */ + @Deprecated public void read(Sheet sheet, Class clazz) { - analyser.beforeAnalysis(); if (sheet != null) { sheet.setClazz(clazz); - analyser.analysis(sheet); - } else { - analyser.analysis(); } + read(sheet); + } + + /** + * Context for the entire execution process + * + * @return + */ + public AnalysisContext analysisContext() { + checkFinished(); + return excelAnalyser.analysisContext(); + } + + /** + * Current executor + * + * @return + */ + public ExcelExecutor excelExecutor() { + checkFinished(); + return excelAnalyser.excelExecutor(); } /** * Parse the workBook get all sheets * * @return workBook all sheets + * + * @deprecated please use {@link #excelExecutor()} */ + @Deprecated public List getSheets() { - return analyser.getSheets(); + return excelExecutor().sheetList(); } + /** + * + * @return + * @deprecated please use {@link #analysisContext()} + */ + @Deprecated public AnalysisContext getAnalysisContext() { - return analyser.getAnalysisContext(); + return analysisContext(); } /** - * validate param - * - * @param in - * @param eventListener + * Complete the entire read file.Release the cache and close stream. */ - private void validateParam(InputStream in, AnalysisEventListener eventListener) { -// if (eventListener == null) { -// throw new IllegalArgumentException("AnalysisEventListener can not null"); -// } else if (in == null) { -// throw new IllegalArgumentException("InputStream can not null"); -// } + public void finish() { + if (finished) { + return; + } + finished = true; + excelAnalyser.finish(); + } + + /** + * Prevents calls to {@link #finish} from freeing the cache + * + * @throws Throwable + */ + @Override + protected void finalize() { + if (finished) { + return; + } + try { + excelAnalyser.finish(); + } catch (Exception e) { + LOGGER.warn("Destroy object failed", e); + } + } + + private void checkFinished() { + if (finished) { + throw new ExcelAnalysisException("Can not use a finished reader."); + } } } diff --git a/src/main/java/com/alibaba/excel/ExcelWriter.java b/src/main/java/com/alibaba/excel/ExcelWriter.java index 85677d7..603198d 100644 --- a/src/main/java/com/alibaba/excel/ExcelWriter.java +++ b/src/main/java/com/alibaba/excel/ExcelWriter.java @@ -48,7 +48,7 @@ public class ExcelWriter { public ExcelWriter(InputStream templateInputStream, OutputStream outputStream, ExcelTypeEnum excelType, boolean needHead, Map customConverterMap, List customWriteHandlerList) { Workbook workbook = new Workbook(); - workbook.setTemplateInputStream(templateInputStream); + workbook.setInputStream(templateInputStream); workbook.setOutputStream(outputStream); workbook.setExcelType(excelType); workbook.setNeedHead(needHead); @@ -135,7 +135,7 @@ public class ExcelWriter { List customWriteHandlerList = new ArrayList(); customWriteHandlerList.add(writeHandler); Workbook workbook = new Workbook(); - workbook.setTemplateInputStream(templateInputStream); + workbook.setInputStream(templateInputStream); workbook.setOutputStream(outputStream); workbook.setExcelType(typeEnum); workbook.setNeedHead(needHead); diff --git a/src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java deleted file mode 100644 index 678cdfc..0000000 --- a/src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.alibaba.excel.analysis; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.converters.ConverterKey; -import com.alibaba.excel.converters.ConverterRegistryCenter; -import com.alibaba.excel.converters.DefaultConverterLoader; -import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.excel.event.AnalysisEventRegistryCenter; -import com.alibaba.excel.event.AnalysisFinishEvent; -import com.alibaba.excel.metadata.property.ExcelHeadProperty; -import com.alibaba.excel.metadata.Sheet; - -/** - * @author jipengfei - */ -public abstract class BaseSaxAnalyser implements ConverterRegistryCenter, AnalysisEventRegistryCenter, ExcelAnalyser { - - protected AnalysisContext analysisContext; - - private LinkedHashMap> listeners = - new LinkedHashMap>(); - - private Map converters = new HashMap(); - - /** - * execute method - */ - protected abstract void execute(); - - @Override - public void register(String name, AnalysisEventListener listener) { - if (!listeners.containsKey(name)) { - listeners.put(name, listener); - } - } - - @Override - public void register(Converter converter) { - converters.put(new ConverterKey(converter.supportJavaTypeKey(),converter.supportExcelTypeKey()), converter); - } - - @Override - public void beforeAnalysis() { - registerDefaultConverters(); - } - - private void registerDefaultConverters() { - converters.putAll(DefaultConverterLoader.loadDefaultReadConverter()); - } - - @Override - public Map getConverters() { - return converters; - } - - @Override - public void analysis(Sheet sheetParam) { - analysisContext.setCurrentSheet(sheetParam); - execute(); - } - - @Override - public void analysis() { - execute(); - } - - @Override - public AnalysisContext getAnalysisContext() { - return analysisContext; - } - - /** - */ - @Override - public void cleanAllListeners() { - listeners.clear(); - } - - @Override - public void cleanListener(String name) { - listeners.remove(name); - } - - @SuppressWarnings("unchecked") - @Override - public void notify(AnalysisFinishEvent event) { - analysisContext.setCurrentRowAnalysisResult(event.getAnalysisResult()); - /** Parsing header content **/ - if (analysisContext.getCurrentRowNum() < analysisContext.getCurrentSheet().getReadHeadRowNumber()) { - if (analysisContext.getCurrentRowNum() <= analysisContext.getCurrentSheet().getReadHeadRowNumber() - 1) { - buildExcelHeadProperty(null, (List)analysisContext.getCurrentRowAnalysisResult()); - } - } else { - for (Entry> entry : listeners.entrySet()) { - entry.getValue().invoke(analysisContext.getCurrentRowAnalysisResult(), analysisContext); - } - } - } - - private void buildExcelHeadProperty(Class clazz, List headOneRow) { - ExcelHeadProperty excelHeadProperty = - ExcelHeadProperty.buildExcelHeadProperty(this.analysisContext.getExcelHeadProperty(), clazz, headOneRow); - this.analysisContext.setExcelHeadProperty(excelHeadProperty); - } -} diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java index 01f8f85..2617934 100644 --- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java @@ -1,7 +1,5 @@ package com.alibaba.excel.analysis; -import java.util.List; - import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.metadata.Sheet; @@ -11,9 +9,6 @@ import com.alibaba.excel.metadata.Sheet; * @author jipengfei */ public interface ExcelAnalyser { - - void beforeAnalysis(); - /** * parse one sheet * @@ -22,21 +17,22 @@ public interface ExcelAnalyser { void analysis(Sheet sheetParam); /** - * parse all sheets + * Complete the entire read file.Release the cache and close stream */ - void analysis(); + void finish(); /** - * get all sheet of workbook - * - * @return all sheets + * Acquisition excel executor + * + * @return */ - List getSheets(); - + ExcelExecutor excelExecutor(); + /** * get the analysis context. + * * @return analysis context */ - AnalysisContext getAnalysisContext(); + AnalysisContext analysisContext(); } diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java index bbc045b..2312477 100644 --- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java @@ -1,21 +1,12 @@ package com.alibaba.excel.analysis; -import java.io.InputStream; -import java.util.Collection; -import java.util.List; -import java.util.Map; - import com.alibaba.excel.analysis.v03.XlsSaxAnalyser; import com.alibaba.excel.analysis.v07.XlsxSaxAnalyser; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContextImpl; -import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.converters.ConverterKey; -import com.alibaba.excel.converters.ConverterRegistryCenter; -import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.metadata.Sheet; -import com.alibaba.excel.event.ModelBuildEventListener; +import com.alibaba.excel.metadata.Workbook; import com.alibaba.excel.support.ExcelTypeEnum; /** @@ -25,93 +16,49 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { private AnalysisContext analysisContext; - private BaseSaxAnalyser saxAnalyser; - - public ExcelAnalyserImpl(InputStream inputStream, ExcelTypeEnum excelTypeEnum, Object custom, - AnalysisEventListener eventListener, boolean trim) { - ConverterRegistryCenter center = new ConverterRegistryCenter() { - @Override - public void register(Converter converter) { - saxAnalyser.register(converter); - } + private ExcelExecutor excelExecutor; - @Override - public Map getConverters() { - return saxAnalyser.getConverters(); - } - }; - analysisContext = new AnalysisContextImpl(inputStream, excelTypeEnum, custom, - eventListener, center, trim); - this.saxAnalyser = getSaxAnalyser(); + public ExcelAnalyserImpl(Workbook workbook) { + analysisContext = new AnalysisContextImpl(workbook); + choiceExcelExecutor(); } - private BaseSaxAnalyser getSaxAnalyser() { - if (saxAnalyser != null) { - return this.saxAnalyser; - } + private void choiceExcelExecutor() { try { - if (analysisContext.getExcelType() != null) { - switch (analysisContext.getExcelType()) { - case XLS: - this.saxAnalyser = new XlsSaxAnalyser(analysisContext); - break; - case XLSX: - this.saxAnalyser = new XlsxSaxAnalyser(analysisContext); - break; - } - } else { - try { - this.saxAnalyser = new XlsxSaxAnalyser(analysisContext); - } catch (Exception e) { - if (!analysisContext.getInputStream().markSupported()) { - throw new ExcelAnalysisException( - "Xls must be available markSupported,you can do like this new " - + "BufferedInputStream(new FileInputStream(\"/xxxx\")) "); - } - this.saxAnalyser = new XlsSaxAnalyser(analysisContext); - } + ExcelTypeEnum excelType = analysisContext.currentWorkbookHolder().getExcelType(); + if (excelType == null) { + excelExecutor = new XlsxSaxAnalyser(analysisContext); + return; + } + switch (excelType) { + case XLS: + excelExecutor = new XlsSaxAnalyser(analysisContext); + break; + case XLSX: + excelExecutor = new XlsxSaxAnalyser(analysisContext); + break; + default: } } catch (Exception e) { throw new ExcelAnalysisException("File type error,io must be available markSupported,you can do like " + "this new BufferedInputStream(new FileInputStream(\\\"/xxxx\\\")) \"", e); } - - return this.saxAnalyser; - } - - @Override - public void analysis(Sheet sheetParam) { - analysisContext.setCurrentSheet(sheetParam); - analysis(); - } - @Override - public AnalysisContext getAnalysisContext() { - return analysisContext; } + @Override - public void analysis() { - saxAnalyser.execute(); + public void analysis(Sheet sheet) { + analysisContext.currentSheet(sheet); + excelExecutor.execute(); analysisContext.getEventListener().doAfterAllAnalysed(analysisContext); } @Override - public List getSheets() { - return this.saxAnalyser.getSheets(); - } - - private void registerListeners(BaseSaxAnalyser saxAnalyser) { - saxAnalyser.cleanAllListeners(); - if (analysisContext.getCurrentSheet() != null && analysisContext.getCurrentSheet().getClazz() != null) { - saxAnalyser.register("model_build_listener", new ModelBuildEventListener(this.saxAnalyser.getConverters())); - } - if (analysisContext.getEventListener() != null) { - saxAnalyser.register("user_define_listener", analysisContext.getEventListener()); - } + public com.alibaba.excel.analysis.ExcelExecutor excelExecutor() { + return excelExecutor; } @Override - public void beforeAnalysis() { - BaseSaxAnalyser saxAnalyser = getSaxAnalyser(); - registerListeners(saxAnalyser); + public AnalysisContext analysisContext() { + return analysisContext; } } diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelExecutor.java b/src/main/java/com/alibaba/excel/analysis/ExcelExecutor.java new file mode 100644 index 0000000..dc575ba --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/ExcelExecutor.java @@ -0,0 +1,18 @@ +package com.alibaba.excel.analysis; + +import java.util.List; + +import com.alibaba.excel.metadata.Sheet; + +/** + * Excel file Executor + * + * @author zhuangjiaju + */ +public interface ExcelExecutor { + + List sheetList(); + + void execute(); + +} 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 b832a3c..13f8496 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -1,32 +1,53 @@ package com.alibaba.excel.analysis.v03; -import com.alibaba.excel.analysis.BaseSaxAnalyser; -import com.alibaba.excel.analysis.v03.handlers.*; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder; +import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; +import org.apache.poi.hssf.eventusermodel.HSSFEventFactory; +import org.apache.poi.hssf.eventusermodel.HSSFListener; +import org.apache.poi.hssf.eventusermodel.HSSFRequest; +import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener; +import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; + +import com.alibaba.excel.analysis.ExcelExecutor; +import com.alibaba.excel.analysis.v03.handlers.BOFRecordHandler; +import com.alibaba.excel.analysis.v03.handlers.BlankOrErrorRecordHandler; +import com.alibaba.excel.analysis.v03.handlers.FormulaRecordHandler; +import com.alibaba.excel.analysis.v03.handlers.LabelRecordHandler; +import com.alibaba.excel.analysis.v03.handlers.MissingCellDummyRecordHandler; +import com.alibaba.excel.analysis.v03.handlers.NoteRecordHandler; +import com.alibaba.excel.analysis.v03.handlers.NumberRecordHandler; +import com.alibaba.excel.analysis.v03.handlers.RKRecordHandler; +import com.alibaba.excel.analysis.v03.handlers.SSTRecordHandler; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.EachRowAnalysisFinishEvent; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.util.CollectionUtils; -import org.apache.poi.hssf.eventusermodel.*; -import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; -import org.apache.poi.hssf.record.*; -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; /** - * /** * A text extractor for Excel files. *

* Returns the textual content of the file, suitable for * indexing by - * something like Lucene, but not really * intended for display to the user. *

*

* To turn an excel file into - * a CSV or similar, then see * the XLS2CSVmra example *

* * @see - * XLS2CSVmra + * /** * A text extractor for Excel files. * + *

+ * * Returns the textual content of the file, suitable for * indexing by something like Lucene, but not really * + * intended for display to the user. * + *

+ * * + *

+ * * To turn an excel file into a CSV or similar, then see * the XLS2CSVmra example * + *

+ * * * @see XLS2CSVmra * * @author jipengfei */ -public class XlsSaxAnalyser extends BaseSaxAnalyser implements HSSFListener { +public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor { private boolean outputFormulaValues = true; private POIFSFileSystem fs; private int lastRowNumber; @@ -41,6 +62,7 @@ public class XlsSaxAnalyser extends BaseSaxAnalyser implements HSSFListener { private List sheets = new ArrayList(); private HSSFWorkbook stubWorkbook; private List recordHandlers = new ArrayList(); + public XlsSaxAnalyser(AnalysisContext context) throws IOException { this.analysisContext = context; this.records = new ArrayList(); @@ -54,6 +76,11 @@ public class XlsSaxAnalyser extends BaseSaxAnalyser implements HSSFListener { return sheets; } + @Override + public List sheetList() { + return null; + } + @Override public void execute() { MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this); @@ -93,7 +120,7 @@ public class XlsSaxAnalyser extends BaseSaxAnalyser implements HSSFListener { int thisRow = -1; int thisColumn = -1; String thisStr = null; - for(XlsRecordHandler handler : this.recordHandlers) { + for (XlsRecordHandler handler : this.recordHandlers) { if (handler.support(record)) { handler.processRecord(record); thisRow = handler.getRow(); @@ -162,7 +189,7 @@ public class XlsSaxAnalyser extends BaseSaxAnalyser implements HSSFListener { Collections.sort(recordHandlers); } - for(XlsRecordHandler x : recordHandlers) { + for (XlsRecordHandler x : recordHandlers) { x.init(); } } 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 40d413d..e187b07 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java @@ -6,7 +6,7 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -import com.alibaba.excel.cache.Cache; +import com.alibaba.excel.cache.ReadCache; /** * Sax read sharedStringsTable.xml @@ -19,10 +19,10 @@ public class SharedStringsTableHandler extends DefaultHandler { private String currentData; private boolean isT; private int index = 0; - private Cache cache; + private ReadCache readCache; - public SharedStringsTableHandler(Cache cache) { - this.cache = cache; + public SharedStringsTableHandler(ReadCache readCache) { + this.readCache = readCache; } @Override @@ -44,7 +44,7 @@ public class SharedStringsTableHandler extends DefaultHandler { @Override public void characters(char[] ch, int start, int length) throws SAXException { if (isT) { - cache.put(index++, new String(ch, start, length)); + readCache.put(index++, new String(ch, start, length)); if (index % 100000 == 0) { LOGGER.info("row:{} ,mem:{},data:{}", index, Runtime.getRuntime().totalMemory()); } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java index 875b94b..7fd1dc1 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java @@ -6,23 +6,20 @@ import java.util.List; import com.alibaba.excel.analysis.v07.handlers.CountRowCellHandler; import com.alibaba.excel.analysis.v07.handlers.DefaultCellHandler; import com.alibaba.excel.analysis.v07.handlers.ProcessResultCellHandler; -import com.alibaba.excel.cache.Cache; import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.event.AnalysisEventRegistryCenter; +/** + * Build handler + * + * @author Dan Zheng + */ public class XlsxHandlerFactory { - public static List buildCellHandlers(AnalysisContext analysisContext, - AnalysisEventRegistryCenter registerCenter, Cache cahe) { + public static List buildCellHandlers(AnalysisContext analysisContext) { List result = new ArrayList(); result.add(new CountRowCellHandler(analysisContext)); - DefaultCellHandler defaultCellHandler = buildXlsxRowResultHandler(analysisContext, registerCenter, cahe); + DefaultCellHandler defaultCellHandler = new DefaultCellHandler(analysisContext); result.add(defaultCellHandler); - result.add(new ProcessResultCellHandler(registerCenter, defaultCellHandler)); + result.add(new ProcessResultCellHandler(analysisContext, defaultCellHandler)); return result; } - - private static DefaultCellHandler buildXlsxRowResultHandler(AnalysisContext analysisContext, - AnalysisEventRegistryCenter registerCenter, Cache cahe) { - return new DefaultCellHandler(analysisContext, registerCenter, cahe); - } } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java index a2dba82..1a1bbee 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java @@ -6,9 +6,7 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -import com.alibaba.excel.cache.Cache; import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.event.AnalysisEventRegistryCenter; /** * @@ -19,8 +17,8 @@ public class XlsxRowHandler extends DefaultHandler { private List cellHandlers; private XlsxRowResultHolder rowResultHolder; - public XlsxRowHandler(AnalysisEventRegistryCenter registerCenter, Cache cache, AnalysisContext analysisContext) { - this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext, registerCenter, cache); + public XlsxRowHandler(AnalysisContext analysisContext) { + this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext); for (XlsxCellHandler cellHandler : cellHandlers) { if (cellHandler instanceof XlsxRowResultHolder) { this.rowResultHolder = (XlsxRowResultHolder)cellHandler; 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 0d5c964..7a356f6 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -1,133 +1,120 @@ package com.alibaba.excel.analysis.v07; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.UUID; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; -import org.apache.poi.openxml4j.exceptions.OpenXML4JException; import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.usermodel.XSSFRelation; -import org.apache.xmlbeans.XmlException; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument; import org.xml.sax.ContentHandler; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; -import com.alibaba.excel.analysis.BaseSaxAnalyser; -import com.alibaba.excel.cache.Cache; -import com.alibaba.excel.cache.EhcacheFile; +import com.alibaba.excel.analysis.ExcelExecutor; +import com.alibaba.excel.cache.Ehcache; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.metadata.Sheet; +import com.alibaba.excel.metadata.holder.WorkbookHolder; +import com.alibaba.excel.util.FileUtils; /** * * @author jipengfei */ -public class XlsxSaxAnalyser extends BaseSaxAnalyser { +public class XlsxSaxAnalyser implements ExcelExecutor { + private AnalysisContext analysisContext; + private List sheetList; + private Map sheetMap; - private XSSFReader xssfReader; + public XlsxSaxAnalyser(AnalysisContext analysisContext) throws Exception { + this.analysisContext = analysisContext; + analysisContext.setCurrentRowNum(0); + WorkbookHolder workbookHolder = analysisContext.currentWorkbookHolder(); + if (workbookHolder.getReadCache() == null) { + workbookHolder.setReadCache(new Ehcache()); + } + OPCPackage pkg = readOpcPackage(workbookHolder); - private Cache cache; + // Analysis sharedStringsTable.xml + analysisSharedStringsTable(pkg, workbookHolder); - private List sheetSourceList = new ArrayList(); + XSSFReader xssfReader = new XSSFReader(pkg); - private boolean use1904WindowDate = false; + analysisUse1904WindowDate(xssfReader, workbookHolder); - public XlsxSaxAnalyser(AnalysisContext analysisContext) throws IOException, OpenXML4JException, XmlException { - this.analysisContext = analysisContext; - - analysisContext.setCurrentRowNum(0); - // OPCPackage pkg = - // OPCPackage.open(new File("D:\\git\\easyexcel\\src\\test\\resources\\read\\large\\large07.xlsx")); -// InputStream input = -// Thread.currentThread().getContextClassLoader().getResourceAsStream("read/large/large07.xlsx"); -// File ff = new File("D:\\git\\easyexcel\\src\\test\\resources\\read\\large\\large0722.xlsx"); -// OutputStream os = new FileOutputStream(ff); -// int bytesRead = 0; -// byte[] buffer = new byte[8192]; -// while ((bytesRead = input.read(buffer, 0, 8192)) != -1) { -// os.write(buffer, 0, bytesRead); -// } -// os.close(); -// input.close(); -// OPCPackage pkg = OPCPackage.open(ff); - - OPCPackage pkg = - OPCPackage.open(Thread.currentThread().getContextClassLoader().getResourceAsStream("read/large/large07.xlsx")); - this.xssfReader = new XSSFReader(pkg); - ArrayList parts = pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType()); - PackagePart packagePart = parts.get(0); - // InputStream sheet = Thread.currentThread().getContextClassLoader() - // .getResourceAsStream("read/large/large07/xl/sharedStrings.xml"); - InputStream sheet = packagePart.getInputStream(); - InputSource sheetSource1 = new InputSource(sheet); - this.cache = new EhcacheFile(); - try { - SAXParserFactory saxFactory = SAXParserFactory.newInstance(); - saxFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - saxFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); - saxFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - SAXParser saxParser = saxFactory.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - ContentHandler handler = new SharedStringsTableHandler(cache); - xmlReader.setContentHandler(handler); - xmlReader.parse(sheetSource1); - sheet.close(); - } catch (Exception e) { - e.printStackTrace(); - throw new ExcelAnalysisException(e); - } - cache.finish(); - // this.cache=new SharedStringsTableCache(xssfReader.getSharedStringsTable()); - // InputStream workbookXml = xssfReader.getWorkbookData(); - // WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml); - // CTWorkbook wb = ctWorkbook.getWorkbook(); - // CTWorkbookPr prefix = wb.getWorkbookPr(); - // if (prefix != null) { - // this.use1904WindowDate = prefix.getDate1904(); - // } - this.analysisContext.setUse1904WindowDate(use1904WindowDate); - - // sheetSourceList.add(new SheetSource("test", Thread.currentThread().getContextClassLoader() - // .getResourceAsStream("read/large/large07/xl/worksheets/sheet1.xml"))); - XSSFReader.SheetIterator ite; - sheetSourceList = new ArrayList(); - - ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); + sheetList = new ArrayList(); + sheetMap = new HashMap(); + XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); + int index = 0; while (ite.hasNext()) { InputStream inputStream = ite.next(); - String sheetName = ite.getSheetName(); - SheetSource sheetSource = new SheetSource(sheetName, inputStream); - sheetSourceList.add(sheetSource); + Sheet sheet = new Sheet(); + sheet.setSheetNo(index); + sheet.setSheetName(ite.getSheetName()); + sheetList.add(sheet); + sheetMap.put(index, inputStream); + index++; } } - @Override - protected void execute() { - Sheet sheetParam = analysisContext.getCurrentSheet(); - if (sheetParam != null && sheetParam.getSheetNo() > 0 && sheetSourceList.size() >= sheetParam.getSheetNo()) { - InputStream sheetInputStream = sheetSourceList.get(sheetParam.getSheetNo() - 1).getInputStream(); - parseXmlSource(sheetInputStream); - - } else { - int i = 0; - for (SheetSource sheetSource : sheetSourceList) { - i++; - analysisContext.setCurrentSheet(new Sheet(i, sheetParam.getReadHeadRowNumber())); - parseXmlSource(sheetSource.getInputStream()); - } + private void analysisUse1904WindowDate(XSSFReader xssfReader, WorkbookHolder workbookHolder) throws Exception { + InputStream workbookXml = xssfReader.getWorkbookData(); + WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml); + CTWorkbook wb = ctWorkbook.getWorkbook(); + CTWorkbookPr prefix = wb.getWorkbookPr(); + if (prefix != null && prefix.getDate1904()) { + workbookHolder.setUse1904windowing(Boolean.TRUE); + } + } + + private void analysisSharedStringsTable(OPCPackage pkg, WorkbookHolder workbookHolder) throws Exception { + ContentHandler handler = new SharedStringsTableHandler(workbookHolder.getReadCache()); + parseXmlSource(pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType()).get(0).getInputStream(), + handler); + workbookHolder.getReadCache().putFinished(); + } + + private OPCPackage readOpcPackage(WorkbookHolder workbookHolder) throws Exception { + if (workbookHolder.getFile() != null) { + return OPCPackage.open(workbookHolder.getFile()); + } + if (workbookHolder.getMandatoryUseInputStream()) { + return OPCPackage.open(workbookHolder.getInputStream()); } + File readTempFile = FileUtils.createCacheTmpFile(); + workbookHolder.setReadTempFile(readTempFile); + File tempFile = new File(readTempFile.getPath(), UUID.randomUUID().toString() + ".xlsx"); + FileUtils.writeToFile(readTempFile, workbookHolder.getInputStream()); + return OPCPackage.open(tempFile); } - private void parseXmlSource(InputStream inputStream) { - InputSource sheetSource = new InputSource(inputStream); + @Override + public List sheetList() { + return sheetList; + } + + @Override + public void execute() { + parseXmlSource(sheetMap.get(analysisContext.currentSheetHolder().getSheetNo()), + new XlsxRowHandler(analysisContext)); + } + + private void parseXmlSource(InputStream inputStream, ContentHandler handler) { + InputSource inputSource = new InputSource(inputStream); try { SAXParserFactory saxFactory = SAXParserFactory.newInstance(); saxFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); @@ -135,55 +122,20 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser { saxFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); SAXParser saxParser = saxFactory.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); - ContentHandler handler = new XlsxRowHandler(this, cache, analysisContext); xmlReader.setContentHandler(handler); - xmlReader.parse(sheetSource); + xmlReader.parse(inputSource); inputStream.close(); } catch (Exception e) { - e.printStackTrace(); throw new ExcelAnalysisException(e); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + throw new ExcelAnalysisException("Can not close 'inputStream'!"); + } + } } } - @Override - public List getSheets() { - List sheets = new ArrayList(); - int i = 1; - for (SheetSource sheetSource : sheetSourceList) { - Sheet sheet = new Sheet(i, 0); - sheet.setSheetName(sheetSource.getSheetName()); - i++; - sheets.add(sheet); - } - - return sheets; - } - - class SheetSource { - - private String sheetName; - - private InputStream inputStream; - - public SheetSource(String sheetName, InputStream inputStream) { - this.sheetName = sheetName; - this.inputStream = inputStream; - } - - public String getSheetName() { - return sheetName; - } - - public void setSheetName(String sheetName) { - this.sheetName = sheetName; - } - - public InputStream getInputStream() { - return inputStream; - } - - public void setInputStream(InputStream inputStream) { - this.inputStream = inputStream; - } - } } 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 23ac8f9..e10d520 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 @@ -13,11 +13,9 @@ import org.xml.sax.Attributes; import com.alibaba.excel.analysis.v07.XlsxCellHandler; import com.alibaba.excel.analysis.v07.XlsxRowResultHolder; -import com.alibaba.excel.cache.Cache; import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.enums.CellDataTypeEnum; -import com.alibaba.excel.event.AnalysisEventRegistryCenter; import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.util.PositionUtils; @@ -25,8 +23,6 @@ import com.alibaba.excel.util.StringUtils; public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder { private final AnalysisContext analysisContext; - private final AnalysisEventRegistryCenter registerCenter; - private final Cache cahe; private String currentTag; private String currentCellIndex; private int curRow; @@ -34,10 +30,8 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder private CellData[] curRowContent = new CellData[20]; private CellData currentCellData; - public DefaultCellHandler(AnalysisContext analysisContext, AnalysisEventRegistryCenter registerCenter, Cache cahe) { + public DefaultCellHandler(AnalysisContext analysisContext) { this.analysisContext = analysisContext; - this.registerCenter = registerCenter; - this.cahe = cahe; } @Override @@ -84,7 +78,8 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder ensureSize(); // Have to go "sharedStrings.xml" and get it if (currentCellData.getType() == CellDataTypeEnum.STRING) { - currentCellData.setStringValue(cahe.get(Integer.valueOf(currentCellData.getStringValue()))); + currentCellData.setStringValue(analysisContext.currentWorkbookHolder().getReadCache() + .get(Integer.valueOf(currentCellData.getStringValue()))); } curRowContent[curCol] = currentCellData; } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java index a0b8c92..3e592c0 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java @@ -1,19 +1,20 @@ package com.alibaba.excel.analysis.v07.handlers; -import org.xml.sax.Attributes; import static com.alibaba.excel.constant.ExcelXmlConstants.ROW_TAG; + +import org.xml.sax.Attributes; + import com.alibaba.excel.analysis.v07.XlsxCellHandler; import com.alibaba.excel.analysis.v07.XlsxRowResultHolder; -import com.alibaba.excel.event.AnalysisEventRegistryCenter; +import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.EachRowAnalysisFinishEvent; public class ProcessResultCellHandler implements XlsxCellHandler { - private AnalysisEventRegistryCenter registerCenter; + private AnalysisContext analysisContext; private XlsxRowResultHolder rowResultHandler; - public ProcessResultCellHandler(AnalysisEventRegistryCenter registerCenter, - XlsxRowResultHolder rowResultHandler) { - this.registerCenter = registerCenter; + public ProcessResultCellHandler(AnalysisContext analysisContext, XlsxRowResultHolder rowResultHandler) { + this.analysisContext = analysisContext; this.rowResultHandler = rowResultHandler; } @@ -23,14 +24,13 @@ public class ProcessResultCellHandler implements XlsxCellHandler { } @Override - public void startHandle(String name, Attributes attributes) { - - } + public void startHandle(String name, Attributes attributes) {} @Override public void endHandle(String name) { - registerCenter.notify(new EachRowAnalysisFinishEvent(rowResultHandler.getCurRowContent(), - rowResultHandler.getColumnSize())); + analysisContext.currentSheetHolder().notifyAll( + new EachRowAnalysisFinishEvent(rowResultHandler.getCurRowContent(), rowResultHandler.getColumnSize()), + analysisContext); rowResultHandler.clearResult(); } diff --git a/src/main/java/com/alibaba/excel/cache/Cache.java b/src/main/java/com/alibaba/excel/cache/Cache.java deleted file mode 100644 index 893796a..0000000 --- a/src/main/java/com/alibaba/excel/cache/Cache.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.alibaba.excel.cache; - -/** - * cache - * - * @author zhuangjiaju - */ -public interface Cache { - - /** - * put - * - * @param key - * @param value - */ - void put(Integer key, String value); - - /** - * get - * - * @param key - * @return - */ - String get(Integer key); - - void finish(); -} diff --git a/src/main/java/com/alibaba/excel/cache/Ehcache.java b/src/main/java/com/alibaba/excel/cache/Ehcache.java index 9e6cf21..ff54fed 100644 --- a/src/main/java/com/alibaba/excel/cache/Ehcache.java +++ b/src/main/java/com/alibaba/excel/cache/Ehcache.java @@ -24,10 +24,10 @@ import com.alibaba.excel.util.StringUtils; * * @author zhuangjiaju */ -public class Ehcache implements Cache { +public class Ehcache implements ReadCache { private static final Logger LOGGER = LoggerFactory.getLogger(Ehcache.class); private static final int BATCH = 500; - // private org.ehcache.Cache cache; + // private org.ehcache.ReadCache cache; int index = 0; int expirekey = 0; private Map cache = new HashMap(); diff --git a/src/main/java/com/alibaba/excel/cache/Ehcache2.java b/src/main/java/com/alibaba/excel/cache/Ehcache2.java index 0569d2e..4a6aa4c 100644 --- a/src/main/java/com/alibaba/excel/cache/Ehcache2.java +++ b/src/main/java/com/alibaba/excel/cache/Ehcache2.java @@ -3,23 +3,16 @@ package com.alibaba.excel.cache; import java.util.HashMap; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** - * Default cache + * + * Putting temporary data directly into a map is a little more efficient but very memory intensive * * @author zhuangjiaju */ -public class Ehcache2 implements Cache { - private static final Logger LOGGER = LoggerFactory.getLogger(Ehcache2.class); - - int index = 0; - // private org.ehcache.Cache cache; - +public class MapCache implements ReadCache { private Map cache = new HashMap(); - public Ehcache2() {} + public MapCache() {} @Override public void put(Integer key, String value) { diff --git a/src/main/java/com/alibaba/excel/cache/EhcacheFile.java b/src/main/java/com/alibaba/excel/cache/EhcacheFile.java index db6493c..2a2f5a2 100644 --- a/src/main/java/com/alibaba/excel/cache/EhcacheFile.java +++ b/src/main/java/com/alibaba/excel/cache/EhcacheFile.java @@ -24,7 +24,7 @@ import com.alibaba.excel.util.StringUtils; * * @author zhuangjiaju */ -public class EhcacheFile implements Cache { +public class EhcacheFile implements ReadCache { private static final Logger LOGGER = LoggerFactory.getLogger(EhcacheFile.class); private static final int BATCH = 500; int index = 0; diff --git a/src/main/java/com/alibaba/excel/cache/EhcacheMix.java b/src/main/java/com/alibaba/excel/cache/EhcacheMix.java index 4308559..c9eef8f 100644 --- a/src/main/java/com/alibaba/excel/cache/EhcacheMix.java +++ b/src/main/java/com/alibaba/excel/cache/EhcacheMix.java @@ -24,7 +24,7 @@ import com.alibaba.excel.util.StringUtils; * * @author zhuangjiaju */ -public class EhcacheMix implements Cache { +public class EhcacheMix implements ReadCache { private static final Logger LOGGER = LoggerFactory.getLogger(EhcacheMix.class); private static final int BATCH = 500; int index = 0; diff --git a/src/main/java/com/alibaba/excel/cache/ReadCache.java b/src/main/java/com/alibaba/excel/cache/ReadCache.java new file mode 100644 index 0000000..ce4cd9b --- /dev/null +++ b/src/main/java/com/alibaba/excel/cache/ReadCache.java @@ -0,0 +1,34 @@ +package com.alibaba.excel.cache; + +/** + * Read cache + * + * @author zhuangjiaju + */ +public interface ReadCache { + /** + * Automatically generate the key and put it in the cache.Key start from 0 + * + * @param value + */ + void put(String value); + + /** + * Get + * + * @param key + * @return + */ + String get(Integer key); + + /** + * 所有 + */ + void putFinished(); + + /** + * + */ + void destroy(); + +} diff --git a/src/main/java/com/alibaba/excel/cache/SharedStringsTableCache.java b/src/main/java/com/alibaba/excel/cache/SharedStringsTableReadCache.java similarity index 79% rename from src/main/java/com/alibaba/excel/cache/SharedStringsTableCache.java rename to src/main/java/com/alibaba/excel/cache/SharedStringsTableReadCache.java index 8599478..078d9b6 100644 --- a/src/main/java/com/alibaba/excel/cache/SharedStringsTableCache.java +++ b/src/main/java/com/alibaba/excel/cache/SharedStringsTableReadCache.java @@ -7,10 +7,10 @@ import org.apache.poi.xssf.model.SharedStringsTable; * * @author zhuangjiaju */ -public class SharedStringsTableCache implements Cache { +public class SharedStringsTableReadCache implements ReadCache { private SharedStringsTable sharedStringsTable; - public SharedStringsTableCache(SharedStringsTable sharedStringsTable) { + public SharedStringsTableReadCache(SharedStringsTable sharedStringsTable) { this.sharedStringsTable = sharedStringsTable; } diff --git a/src/main/java/com/alibaba/excel/context/AnalysisContext.java b/src/main/java/com/alibaba/excel/context/AnalysisContext.java index 6025d24..44a9e3b 100644 --- a/src/main/java/com/alibaba/excel/context/AnalysisContext.java +++ b/src/main/java/com/alibaba/excel/context/AnalysisContext.java @@ -1,77 +1,76 @@ package com.alibaba.excel.context; -import java.io.InputStream; - -import com.alibaba.excel.converters.ConverterRegistryCenter; -import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.excel.metadata.property.ExcelHeadProperty; -import com.alibaba.excel.metadata.Sheet; -import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.event.EachRowAnalysisFinishEvent; +import com.alibaba.excel.metadata.holder.ReadConfiguration; +import com.alibaba.excel.metadata.holder.SheetHolder; +import com.alibaba.excel.metadata.holder.WorkbookHolder; /** * * A context is the main anchorage point of a excel reader. + * * @author jipengfei */ public interface AnalysisContext { - /** - * Custom attribute + * Select the current table + * + * @param sheet */ - Object getCustom(); + void currentSheet(com.alibaba.excel.metadata.Sheet sheet); /** - * get current sheet + * All information about the workbook you are currently working on * - * @return current analysis sheet + * @return */ - Sheet getCurrentSheet(); + WorkbookHolder currentWorkbookHolder(); /** - * set current sheet - * @param sheet + * All information about the sheet you are currently working on + * + * @return */ - void setCurrentSheet(Sheet sheet); + SheetHolder currentSheetHolder(); /** + * Configuration of currently operated cell * - * get excel type - * @return excel type + * @return */ - ExcelTypeEnum getExcelType(); + ReadConfiguration currentConfiguration(); /** - * get in io - * @return file io + * set current result + * + * @param result */ - InputStream getInputStream(); + void setCurrentRowAnalysisResult(Object result); /** - * - * custom listener - * @return listener + * get current result + * + * @return get current result */ - AnalysisEventListener getEventListener(); + Object currentRowAnalysisResult(); - /** - * get the converter registry center. - * @return converter registry center. - */ - ConverterRegistryCenter getConverterRegistryCenter(); /** * get current row + * * @return */ - Integer getCurrentRowNum(); + Integer currentRowNum(); /** - * set current row num + * set current row num + * * @param row */ void setCurrentRowNum(Integer row); /** - * get total row ,Data may be inaccurate + * get total row , Data may be inaccurate + * * @return */ @Deprecated @@ -83,53 +82,4 @@ public interface AnalysisContext { * @param totalCount */ void setTotalCount(Integer totalCount); - - /** - * get excel head - * @return - */ - ExcelHeadProperty getExcelHeadProperty(); - - /** - * set the excel head property - * @param excelHeadProperty the excel property to set. - */ - void setExcelHeadProperty(ExcelHeadProperty excelHeadProperty); - - /** - * - *if need to short match the content - * @return - */ - boolean trim(); - - /** - * set current result - * @param result - */ - void setCurrentRowAnalysisResult(Object result); - - - /** - * get current result - * @return get current result - */ - Object getCurrentRowAnalysisResult(); - - /** - * Interrupt execution - */ - void interrupt(); - - /** - * date use1904WindowDate - * @return - */ - boolean use1904WindowDate(); - - /** - * date use1904WindowDate - * @param use1904WindowDate - */ - void setUse1904WindowDate(boolean use1904WindowDate); } diff --git a/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java b/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java index ed27e39..0800043 100644 --- a/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java @@ -1,176 +1,47 @@ package com.alibaba.excel.context; -import java.io.InputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -import com.alibaba.excel.converters.ConverterRegistryCenter; -import com.alibaba.excel.event.AnalysisEventListener; -import com.alibaba.excel.exception.ExcelAnalysisException; -import com.alibaba.excel.metadata.property.ExcelHeadProperty; -import com.alibaba.excel.metadata.Sheet; -import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.metadata.holder.SheetHolder; +import com.alibaba.excel.metadata.holder.WorkbookHolder; /** * * @author jipengfei */ public class AnalysisContextImpl implements AnalysisContext { - - private Object custom; - - private Sheet currentSheet; - - private ExcelTypeEnum excelType; - - private InputStream inputStream; - - private AnalysisEventListener eventListener; - - private Integer currentRowNum; - - private Integer totalCount; - - private ExcelHeadProperty excelHeadProperty; - - private boolean trim; - - private boolean use1904WindowDate = false; - - private ConverterRegistryCenter converterRegistryCenter; - - @Override - public void setUse1904WindowDate(boolean use1904WindowDate) { - this.use1904WindowDate = use1904WindowDate; - } - - @Override - public Object getCurrentRowAnalysisResult() { - return currentRowAnalysisResult; - } - - @Override - public void interrupt() { - throw new ExcelAnalysisException("interrupt error"); - } - - @Override - public boolean use1904WindowDate() { - return use1904WindowDate; - } - - @Override - public void setCurrentRowAnalysisResult(Object currentRowAnalysisResult) { - this.currentRowAnalysisResult = currentRowAnalysisResult; - } - - private Object currentRowAnalysisResult; - - public AnalysisContextImpl(InputStream inputStream, ExcelTypeEnum excelTypeEnum, Object custom, - AnalysisEventListener listener, ConverterRegistryCenter converterRegistryCenter, boolean trim) { - this.custom = custom; - this.eventListener = listener; - this.inputStream = inputStream; - this.excelType = excelTypeEnum; - this.trim = trim; - this.converterRegistryCenter = converterRegistryCenter; - } - - @Override - public void setCurrentSheet(Sheet currentSheet) { - cleanCurrentSheet(); - this.currentSheet = currentSheet; - if (currentSheet.getClazz() != null) { - excelHeadProperty = - ExcelHeadProperty.buildExcelHeadProperty(this.excelHeadProperty, currentSheet.getClazz(), null); + private static final Logger LOGGER = LoggerFactory.getLogger(AnalysisContextImpl.class); + /** + * The Workbook currently written + */ + private WorkbookHolder currentWorkbookHolder; + /** + * Current sheet holder + */ + private SheetHolder currentSheetHolder; + + public AnalysisContextImpl(com.alibaba.excel.metadata.Workbook workbook) { + if (workbook == null) { + throw new IllegalArgumentException("Workbook argument cannot be null"); + } + currentWorkbookHolder = WorkbookHolder.buildReadWorkbookHolder(workbook); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Initialization 'AnalysisContextImpl' complete"); } - } - - - private void cleanCurrentSheet() { - this.currentSheet = null; - this.excelHeadProperty = null; - this.totalCount = 0; - this.currentRowAnalysisResult = null; - this.currentRowNum =0; - } - - @Override - public ExcelTypeEnum getExcelType() { - return excelType; - } - - public void setExcelType(ExcelTypeEnum excelType) { - this.excelType = excelType; - } - - public Object getCustom() { - return custom; - } - - public void setCustom(Object custom) { - this.custom = custom; - } - - @Override - public Sheet getCurrentSheet() { - return currentSheet; - } - - @Override - public InputStream getInputStream() { - return inputStream; - } - - public void setInputStream(InputStream inputStream) { - this.inputStream = inputStream; - } - - @Override - public AnalysisEventListener getEventListener() { - return eventListener; - } - - public void setEventListener(AnalysisEventListener eventListener) { - this.eventListener = eventListener; - } - - @Override - public Integer getCurrentRowNum() { - return this.currentRowNum; - } - - @Override - public void setCurrentRowNum(Integer row) { - this.currentRowNum = row; - } - - @Override - public Integer getTotalCount() { - return totalCount; - } - - @Override - public void setTotalCount(Integer totalCount) { - this.totalCount = totalCount; - } - - @Override - public ExcelHeadProperty getExcelHeadProperty() { - return this.excelHeadProperty; - } - - - @Override - public void setExcelHeadProperty(ExcelHeadProperty excelHeadProperty) { - this.excelHeadProperty = excelHeadProperty; - } - - @Override - public boolean trim() { - return this.trim; } @Override - public ConverterRegistryCenter getConverterRegistryCenter() { - return converterRegistryCenter; + public void currentSheet(com.alibaba.excel.metadata.Sheet sheet) { + if (sheet == null) { + throw new IllegalArgumentException("Sheet argument cannot be null"); + } + if (sheet.getSheetNo() == null || sheet.getSheetNo() <= 0) { + sheet.setSheetNo(0); + } + currentSheetHolder = SheetHolder.buildReadWorkSheetHolder(sheet, currentWorkbookHolder); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Began to read:{}", sheet); + } } } diff --git a/src/main/java/com/alibaba/excel/context/WriteContext.java b/src/main/java/com/alibaba/excel/context/WriteContext.java index 639413b..8a27660 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContext.java +++ b/src/main/java/com/alibaba/excel/context/WriteContext.java @@ -1,7 +1,7 @@ package com.alibaba.excel.context; import com.alibaba.excel.metadata.Table; -import com.alibaba.excel.metadata.holder.ConfigurationSelector; +import com.alibaba.excel.metadata.holder.WriteConfiguration; import com.alibaba.excel.metadata.holder.SheetHolder; import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.metadata.holder.WorkbookHolder; @@ -31,7 +31,7 @@ public interface WriteContext { * * @return */ - ConfigurationSelector currentConfigurationSelector(); + WriteConfiguration currentConfiguration(); /** * All information about the workbook you are currently working on diff --git a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java index df28d9f..1c0a4bf 100644 --- a/src/main/java/com/alibaba/excel/context/WriteContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/WriteContextImpl.java @@ -14,10 +14,10 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Table; -import com.alibaba.excel.metadata.holder.ConfigurationSelector; import com.alibaba.excel.metadata.holder.SheetHolder; import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.metadata.holder.WorkbookHolder; +import com.alibaba.excel.metadata.holder.WriteConfiguration; import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.write.handler.CellWriteHandler; @@ -50,7 +50,7 @@ public class WriteContextImpl implements WriteContext { /** * Configuration of currently operated cell */ - private ConfigurationSelector currentConfigurationSelector; + private WriteConfiguration currentWriteConfiguration; public WriteContextImpl(com.alibaba.excel.metadata.Workbook workbook) { if (workbook == null) { @@ -62,8 +62,8 @@ public class WriteContextImpl implements WriteContext { initCurrentWorkbookHolder(workbook); beforeWorkbookCreate(); try { - currentWorkbookHolder.setWorkbook(WorkBookUtil.createWorkBook(workbook)); - } catch (IOException e) { + currentWorkbookHolder.setWorkbook(WorkBookUtil.createWorkBook(currentWorkbookHolder)); + } catch (Exception e) { throw new ExcelGenerateException("Create workbook failure", e); } afterWorkbookCreate(); @@ -73,7 +73,7 @@ public class WriteContextImpl implements WriteContext { } private void beforeWorkbookCreate() { - List handlerList = currentConfigurationSelector.writeHandlerMap().get(WorkbookWriteHandler.class); + List handlerList = currentWriteConfiguration.writeHandlerMap().get(WorkbookWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -85,7 +85,7 @@ public class WriteContextImpl implements WriteContext { } private void afterWorkbookCreate() { - List handlerList = currentConfigurationSelector.writeHandlerMap().get(WorkbookWriteHandler.class); + List handlerList = currentWriteConfiguration.writeHandlerMap().get(WorkbookWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -98,9 +98,9 @@ public class WriteContextImpl implements WriteContext { private void initCurrentWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) { currentWorkbookHolder = new WorkbookHolder(workbook); - currentConfigurationSelector = currentWorkbookHolder; + currentWriteConfiguration = currentWorkbookHolder; if (LOGGER.isDebugEnabled()) { - LOGGER.debug("CurrentConfigurationSelector is currentWorkbookHolder"); + LOGGER.debug("CurrentConfiguration is currentWorkbookHolder"); } } @@ -122,9 +122,9 @@ public class WriteContextImpl implements WriteContext { currentSheetHolder = currentWorkbookHolder.getHasBeenInitializedSheet().get(sheet.getSheetNo()); currentSheetHolder.setNewInitialization(Boolean.FALSE); currentTableHolder = null; - currentConfigurationSelector = currentSheetHolder; + currentWriteConfiguration = currentSheetHolder; if (LOGGER.isDebugEnabled()) { - LOGGER.debug("CurrentConfigurationSelector is currentSheetHolder"); + LOGGER.debug("CurrentConfiguration is currentSheetHolder"); } return; } @@ -136,7 +136,7 @@ public class WriteContextImpl implements WriteContext { } private void beforeSheetCreate() { - List handlerList = currentConfigurationSelector.writeHandlerMap().get(SheetWriteHandler.class); + List handlerList = currentWriteConfiguration.writeHandlerMap().get(SheetWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -148,7 +148,7 @@ public class WriteContextImpl implements WriteContext { } private void afterSheetCreate() { - List handlerList = currentConfigurationSelector.writeHandlerMap().get(SheetWriteHandler.class); + List handlerList = currentWriteConfiguration.writeHandlerMap().get(SheetWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -167,9 +167,9 @@ public class WriteContextImpl implements WriteContext { currentSheetHolder = new SheetHolder(sheet, currentWorkbookHolder); currentWorkbookHolder.getHasBeenInitializedSheet().put(sheet.getSheetNo(), currentSheetHolder); currentTableHolder = null; - currentConfigurationSelector = currentSheetHolder; + currentWriteConfiguration = currentSheetHolder; if (LOGGER.isDebugEnabled()) { - LOGGER.debug("CurrentConfigurationSelector is currentSheetHolder"); + LOGGER.debug("CurrentConfiguration is currentSheetHolder"); } } @@ -179,7 +179,7 @@ public class WriteContextImpl implements WriteContext { currentSheet = currentWorkbookHolder.getWorkbook().getSheetAt(sheet.getSheetNo()); } catch (Exception e) { if (LOGGER.isDebugEnabled()) { - LOGGER.info("Can not find sheet:{} ,now create it", sheet.getSheetNo()); + LOGGER.debug("Can not find sheet:{} ,now create it", sheet.getSheetNo()); } currentSheet = WorkBookUtil.createSheet(currentWorkbookHolder.getWorkbook(), sheet); } @@ -189,11 +189,11 @@ public class WriteContextImpl implements WriteContext { } public void initHead(ExcelHeadProperty excelHeadProperty) { - if (!currentConfigurationSelector.needHead() || !currentSheetHolder.getExcelHeadProperty().hasHead()) { + if (!currentWriteConfiguration.needHead() || !currentSheetHolder.getExcelHeadProperty().hasHead()) { return; } int lastRowNum = currentSheetHolder.getSheet().getLastRowNum(); - int rowIndex = lastRowNum + currentConfigurationSelector.writeRelativeHeadRowIndex(); + int rowIndex = lastRowNum + currentWriteConfiguration.writeRelativeHeadRowIndex(); // Combined head addMergedRegionToCurrentSheet(excelHeadProperty, rowIndex); for (int relativeRowIndex = 0, i = rowIndex; i < excelHeadProperty.getHeadRowNumber() + rowIndex; @@ -206,7 +206,7 @@ public class WriteContextImpl implements WriteContext { } private void beforeRowCreate(int rowIndex, int relativeRowIndex) { - List handlerList = currentConfigurationSelector.writeHandlerMap().get(RowWriteHandler.class); + List handlerList = currentWriteConfiguration.writeHandlerMap().get(RowWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -219,7 +219,7 @@ public class WriteContextImpl implements WriteContext { } private void afterRowCreate(Row row, int relativeRowIndex) { - List handlerList = currentConfigurationSelector.writeHandlerMap().get(RowWriteHandler.class); + List handlerList = currentWriteConfiguration.writeHandlerMap().get(RowWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -251,7 +251,7 @@ public class WriteContextImpl implements WriteContext { } private void beforeCellCreate(Row row, Head head, int relativeRowIndex) { - List handlerList = currentConfigurationSelector.writeHandlerMap().get(CellWriteHandler.class); + List handlerList = currentWriteConfiguration.writeHandlerMap().get(CellWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -264,7 +264,7 @@ public class WriteContextImpl implements WriteContext { } private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) { - List handlerList = currentConfigurationSelector.writeHandlerMap().get(CellWriteHandler.class); + List handlerList = currentWriteConfiguration.writeHandlerMap().get(CellWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -293,9 +293,9 @@ public class WriteContextImpl implements WriteContext { } currentTableHolder = currentSheetHolder.getHasBeenInitializedTable().get(table.getTableNo()); currentTableHolder.setNewInitialization(Boolean.FALSE); - currentConfigurationSelector = currentTableHolder; + currentWriteConfiguration = currentTableHolder; if (LOGGER.isDebugEnabled()) { - LOGGER.debug("CurrentConfigurationSelector is currentTableHolder"); + LOGGER.debug("CurrentConfiguration is currentTableHolder"); } return; } @@ -306,15 +306,15 @@ public class WriteContextImpl implements WriteContext { private void initCurrentTableHolder(com.alibaba.excel.metadata.Table table) { currentTableHolder = new TableHolder(table, currentSheetHolder, currentWorkbookHolder); currentSheetHolder.getHasBeenInitializedTable().put(table.getTableNo(), currentTableHolder); - currentConfigurationSelector = currentTableHolder; + currentWriteConfiguration = currentTableHolder; if (LOGGER.isDebugEnabled()) { - LOGGER.debug("CurrentConfigurationSelector is currentTableHolder"); + LOGGER.debug("CurrentConfiguration is currentTableHolder"); } } @Override - public ConfigurationSelector currentConfigurationSelector() { - return currentConfigurationSelector; + public WriteConfiguration currentConfiguration() { + return currentWriteConfiguration; } @Override diff --git a/src/main/java/com/alibaba/excel/converters/ConverterRegistryCenter.java b/src/main/java/com/alibaba/excel/converters/ConverterRegistryCenter.java deleted file mode 100644 index 4905fb1..0000000 --- a/src/main/java/com/alibaba/excel/converters/ConverterRegistryCenter.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.alibaba.excel.converters; - -import java.util.Collection; -import java.util.Map; - -public interface ConverterRegistryCenter { - void register(Converter converter); - Map getConverters(); -} diff --git a/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java b/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java index 63c96d3..2a63e57 100644 --- a/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java @@ -28,8 +28,12 @@ public class DateNumberConverter implements Converter { @Override public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { - if (contentProperty.getDateTimeFormatProperty() == null) { - return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), false, null); + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + Boolean use1904windowing = Boolean.FALSE; + if (contentProperty != null && contentProperty.getUse1904windowing() != null) { + use1904windowing = contentProperty.getUse1904windowing(); + } + return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), use1904windowing, null); } else { return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null); diff --git a/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java b/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java index ee31a0b..adc7953 100644 --- a/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java +++ b/src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java @@ -27,7 +27,7 @@ public class DateStringConverter implements Converter { @Override public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) throws ParseException { - if (contentProperty.getDateTimeFormatProperty() == null) { + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { return DateUtils.parseDate(cellData.getStringValue(), null); } else { return DateUtils.parseDate(cellData.getStringValue(), @@ -37,7 +37,7 @@ public class DateStringConverter implements Converter { @Override public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty) { - if (contentProperty.getDateTimeFormatProperty() == null) { + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { return new CellData(DateUtils.format(value, null)); } else { return new CellData(DateUtils.format(value, contentProperty.getDateTimeFormatProperty().getFormat())); diff --git a/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java index 0f0fe69..8ad4893 100644 --- a/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java @@ -29,7 +29,7 @@ public class StringNumberConverter implements Converter { @Override public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { // If there are "DateTimeFormat", read as date - if (contentProperty.getDateTimeFormatProperty() != null) { + if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { return DateUtils.format( HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null), diff --git a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java index 305c7cb..4d596db 100644 --- a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java +++ b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java @@ -1,6 +1,7 @@ package com.alibaba.excel.event; import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.read.listener.ReadListener; /** * Receives the return of each piece of data parsed @@ -21,12 +22,7 @@ public abstract class AnalysisEventListener implements ReadListener { throw exception; } - /** - * Verify that there is another piece of data.You can stop the read by returning false - * - * @param context - * @return - */ + @Override public boolean hasNext(AnalysisContext context) { return true; } diff --git a/src/main/java/com/alibaba/excel/event/AnalysisEventRegistryCenter.java b/src/main/java/com/alibaba/excel/event/AnalysisEventRegistryCenter.java deleted file mode 100644 index d3f0095..0000000 --- a/src/main/java/com/alibaba/excel/event/AnalysisEventRegistryCenter.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.alibaba.excel.event; - -/** - * Event center. - * - * @author jipengfei - */ -public interface AnalysisEventRegistryCenter { - - /** - * Append listener - * - * @param name listener name. - * @param listener Callback method after each row is parsed. - */ - void register(String name, AnalysisEventListener listener); - - /** - * Parse one row to notify all event listeners - * - * @param event parse event - */ - void notify(AnalysisFinishEvent event); - - /** - * Clean all listeners. - */ - void cleanAllListeners(); - - /** - * clean listener by name - * @param name the listener name - */ - void cleanListener(String name); -} diff --git a/src/main/java/com/alibaba/excel/event/EachRowAnalysisFinishEvent.java b/src/main/java/com/alibaba/excel/event/EachRowAnalysisFinishEvent.java index 9173caa..1732e59 100644 --- a/src/main/java/com/alibaba/excel/event/EachRowAnalysisFinishEvent.java +++ b/src/main/java/com/alibaba/excel/event/EachRowAnalysisFinishEvent.java @@ -10,6 +10,7 @@ import com.alibaba.excel.metadata.CellData; */ public class EachRowAnalysisFinishEvent implements AnalysisFinishEvent { private Object result; + public EachRowAnalysisFinishEvent(Object content) { this.result = content; } diff --git a/src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java deleted file mode 100644 index ed16713..0000000 --- a/src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.alibaba.excel.event; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.converters.ConverterKey; -import com.alibaba.excel.enums.CellDataTypeEnum; -import com.alibaba.excel.exception.ExcelDataConvertException; -import com.alibaba.excel.exception.ExcelGenerateException; -import com.alibaba.excel.metadata.CellData; -import com.alibaba.excel.metadata.property.ExcelContentProperty; -import com.alibaba.excel.metadata.property.ExcelHeadProperty; - -import net.sf.cglib.beans.BeanMap; - -/** - * @author jipengfei - */ -public class ModelBuildEventListener extends AnalysisEventListener { - private final Map converters; - - public ModelBuildEventListener(Map converters) { - this.converters = converters; - } - - @Override - public void invoke(Object object, AnalysisContext context) { - if (context.getExcelHeadProperty() != null && context.getExcelHeadProperty().getHeadClazz() != null) { - try { - @SuppressWarnings("unchecked") - Object resultModel = buildUserModel(context, (List)object); - context.setCurrentRowAnalysisResult(resultModel); - } catch (Exception e) { - throw new ExcelGenerateException(e); - } - } - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - private Object buildUserModel(AnalysisContext context, List cellDataList) throws Exception { - ExcelHeadProperty excelHeadProperty = context.getExcelHeadProperty(); - Object resultModel = excelHeadProperty.getHeadClazz().newInstance(); - Map map = new HashMap(); - for (int i = 0; i < cellDataList.size(); i++) { - ExcelContentProperty contentProperty = excelHeadProperty.getContentPropertyMap().get(i); - if (contentProperty != null) { - CellData cellData = cellDataList.get(i); - if (cellData.getType() == CellDataTypeEnum.EMPTY) { - continue; - } - Object value = convertValue(cellDataList.get(i), contentProperty.getField().getClass(), contentProperty); - if (value != null) { - map.put(contentProperty.getField().getName(), value); - } - } - } - BeanMap.create(resultModel).putAll(map); - return resultModel; - } - - private Object convertValue(CellData cellData, Class clazz, ExcelContentProperty contentProperty) { - Converter converter = converters.get(ConverterKey.buildConverterKey(clazz, cellData.getType())); - if (converter == null) { - throw new ExcelDataConvertException( - "Converter not found, convert " + cellData.getType() + " to " + clazz.getName()); - } - try { - return converter.convertToJavaData(cellData, contentProperty); - } 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/metadata/BasicParameter.java b/src/main/java/com/alibaba/excel/metadata/BasicParameter.java index dcaf950..a4dd583 100644 --- a/src/main/java/com/alibaba/excel/metadata/BasicParameter.java +++ b/src/main/java/com/alibaba/excel/metadata/BasicParameter.java @@ -1,12 +1,10 @@ package com.alibaba.excel.metadata; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import com.alibaba.excel.converters.Converter; -import com.alibaba.excel.event.ReadListener; +import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.write.handler.WriteHandler; /** @@ -42,7 +40,7 @@ public class BasicParameter { /** * Custom type conversions override the default */ - private Map customConverterMap = new HashMap(); + private List customConverterList = new ArrayList(); /** * Custom type handler override the default */ @@ -51,6 +49,10 @@ public class BasicParameter { * Custom type listener run after default */ private List customReadListenerList = new ArrayList(); + /** + * Automatic trim includes sheet name and content + */ + private Boolean autoTrim; public Integer getReadHeadRowNumber() { return readHeadRowNumber; @@ -92,12 +94,12 @@ public class BasicParameter { this.needHead = needHead; } - public Map getCustomConverterMap() { - return customConverterMap; + public List getCustomConverterList() { + return customConverterList; } - public void setCustomConverterMap(Map customConverterMap) { - this.customConverterMap = customConverterMap; + public void setCustomConverterList(List customConverterList) { + this.customConverterList = customConverterList; } public List getCustomWriteHandlerList() { @@ -115,4 +117,12 @@ public class BasicParameter { public void setCustomReadListenerList(List customReadListenerList) { this.customReadListenerList = customReadListenerList; } + + public Boolean getAutoTrim() { + return autoTrim; + } + + public void setAutoTrim(Boolean autoTrim) { + this.autoTrim = autoTrim; + } } diff --git a/src/main/java/com/alibaba/excel/metadata/Head.java b/src/main/java/com/alibaba/excel/metadata/Head.java index 370bd11..7f50c36 100644 --- a/src/main/java/com/alibaba/excel/metadata/Head.java +++ b/src/main/java/com/alibaba/excel/metadata/Head.java @@ -24,7 +24,10 @@ public class Head { * Head name */ private List headNameList; - + /** + * Whether index is specified + */ + private Boolean forceIndex; /** * Cell style property */ @@ -89,4 +92,12 @@ public class Head { public void setColumnWidthProperty(ColumnWidthProperty columnWidthProperty) { this.columnWidthProperty = columnWidthProperty; } + + public Boolean getForceIndex() { + return forceIndex; + } + + public void setForceIndex(Boolean forceIndex) { + this.forceIndex = forceIndex; + } } diff --git a/src/main/java/com/alibaba/excel/metadata/Workbook.java b/src/main/java/com/alibaba/excel/metadata/Workbook.java index ceb6274..3dd7f33 100644 --- a/src/main/java/com/alibaba/excel/metadata/Workbook.java +++ b/src/main/java/com/alibaba/excel/metadata/Workbook.java @@ -4,6 +4,9 @@ import java.io.File; import java.io.InputStream; import java.io.OutputStream; +import com.alibaba.excel.cache.ReadCache; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.write.handler.WriteHandler; @@ -41,6 +44,22 @@ public class Workbook extends BasicParameter { * Default true */ private Boolean autoCloseStream; + /** + * This object can be read in the Listener {@link AnalysisEventListener#invoke(Object, AnalysisContext)} + * {@link AnalysisContext#getCustom()} + * + */ + private Object readCustomObject; + /** + * A cache that stores temp data to save memory.Default use {@link com.alibaba.excel.cache.Ehcache} + */ + private ReadCache readCache; + /** + * true if date uses 1904 windowing, or false if using 1900 date windowing. + * + * @return + */ + private Boolean use1904windowing; /** * 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. @@ -112,4 +131,28 @@ public class Workbook extends BasicParameter { public void setConvertAllFiled(Boolean convertAllFiled) { this.convertAllFiled = convertAllFiled; } + + public Object getReadCustomObject() { + return readCustomObject; + } + + public void setReadCustomObject(Object readCustomObject) { + this.readCustomObject = readCustomObject; + } + + public ReadCache getReadCache() { + return readCache; + } + + public void setReadCache(ReadCache readCache) { + this.readCache = readCache; + } + + public Boolean getUse1904windowing() { + return use1904windowing; + } + + public void setUse1904windowing(Boolean use1904windowing) { + this.use1904windowing = use1904windowing; + } } diff --git a/src/main/java/com/alibaba/excel/metadata/holder/AbstractConfigurationSelector.java b/src/main/java/com/alibaba/excel/metadata/holder/AbstractWriteConfiguration.java similarity index 60% rename from src/main/java/com/alibaba/excel/metadata/holder/AbstractConfigurationSelector.java rename to src/main/java/com/alibaba/excel/metadata/holder/AbstractWriteConfiguration.java index 48697da..b4586b1 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/AbstractConfigurationSelector.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/AbstractWriteConfiguration.java @@ -11,16 +11,26 @@ import java.util.TreeMap; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Sheet; +import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.converters.ConverterKey; import com.alibaba.excel.enums.HeadKindEnum; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisFinishEvent; import com.alibaba.excel.event.NotRepeatExecutor; import com.alibaba.excel.event.Order; +import com.alibaba.excel.exception.ExcelAnalysisException; +import com.alibaba.excel.exception.ExcelDataConvertException; +import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellStyle; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.property.CellStyleProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.metadata.property.RowHeightProperty; +import com.alibaba.excel.read.listener.ReadListener; +import com.alibaba.excel.read.listener.ReadListenerRegistryCenter; +import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.handler.SheetWriteHandler; @@ -35,7 +45,8 @@ import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy; * * @author zhuangjiaju */ -public abstract class AbstractConfigurationSelector implements ConfigurationSelector { +public abstract class AbstractWriteConfiguration + implements WriteConfiguration, ReadConfiguration, ReadListenerRegistryCenter { /** * Need Head */ @@ -44,10 +55,18 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele * Write handler for workbook */ private Map, List> writeHandlerMap; + /** + * Read listener + */ + private List readListenerList; + /** + * Converter for workbook + */ + private Map readConverterMap; /** * Converter for workbook */ - private Map converterMap; + private Map writeConverterMap; /** * Excel head property */ @@ -60,17 +79,28 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele * Record whether it's new or from cache */ private Boolean newInitialization; - /** - * You can only choose one of the {@link AbstractConfigurationSelector#head} and - * {@link AbstractConfigurationSelector#clazz} + * Count the number of added heads when read sheet. + * + *
  • 0 - This Sheet has no head ,since the first row are the data + *
  • 1 - This Sheet has one row head , this is the default + *
  • 2 - This Sheet has two row head ,since the third row is the data + */ + private Integer readHeadRowNumber; + /** + * You can only choose one of the {@link AbstractWriteConfiguration#head} and + * {@link AbstractWriteConfiguration#clazz} */ private List> head; /** - * You can only choose one of the {@link AbstractConfigurationSelector#head} and - * {@link AbstractConfigurationSelector#clazz} + * You can only choose one of the {@link AbstractWriteConfiguration#head} and + * {@link AbstractWriteConfiguration#clazz} */ private Class clazz; + /** + * Automatic trim includes sheet name and content + */ + private Boolean autoTrim; public Boolean getNeedHead() { return needHead; @@ -88,14 +118,6 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele this.writeHandlerMap = writeHandlerMap; } - public Map getConverterMap() { - return converterMap; - } - - public void setConverterMap(Map converterMap) { - this.converterMap = converterMap; - } - public ExcelHeadProperty getExcelHeadProperty() { return excelHeadProperty; } @@ -136,6 +158,139 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele this.clazz = clazz; } + public Boolean getAutoTrim() { + return autoTrim; + } + + public void setAutoTrim(Boolean autoTrim) { + this.autoTrim = autoTrim; + } + + public List getReadListenerList() { + return readListenerList; + } + + public void setReadListenerList(List readListenerList) { + this.readListenerList = readListenerList; + } + + public Map getReadConverterMap() { + return readConverterMap; + } + + public void setReadConverterMap(Map readConverterMap) { + this.readConverterMap = readConverterMap; + } + + public Map getWriteConverterMap() { + return writeConverterMap; + } + + public void setWriteConverterMap(Map writeConverterMap) { + this.writeConverterMap = writeConverterMap; + } + + public Integer getReadHeadRowNumber() { + return readHeadRowNumber; + } + + public void setReadHeadRowNumber(Integer readHeadRowNumber) { + this.readHeadRowNumber = readHeadRowNumber; + } + + @Override + public void register(AnalysisEventListener listener) { + readListenerList.add(listener); + } + + @Override + public void notifyEndOneRow(AnalysisFinishEvent event, AnalysisContext analysisContext) { + List cellDataList = (List)event.getAnalysisResult(); + if (analysisContext.currentRowNum() > analysisContext.currentSheetHolder().getReadHeadRowNumber()) { + for (ReadListener readListener : readListenerList) { + try { + readListener.invoke(analysisContext.currentRowAnalysisResult(), analysisContext); + } catch (Exception e) { + for (ReadListener readListenerException : readListenerList) { + try { + readListenerException.onException(e, analysisContext); + } catch (Exception exception) { + throw new ExcelAnalysisException("Listen error!", exception); + } + } + } + } + } + // Now is header + if (analysisContext.currentRowNum().equals(analysisContext.currentSheetHolder().getReadHeadRowNumber())) { + buildHead(analysisContext, cellDataList); + } + } + + @Override + public void notifyAfterAllAnalysed(AnalysisContext analysisContext) { + for (ReadListener readListener : readListenerList) { + readListener.doAfterAllAnalysed(analysisContext); + } + } + + private void buildHead(AnalysisContext analysisContext, List cellDataList) { + if (!HeadKindEnum.CLASS.equals(analysisContext.currentConfiguration().excelHeadProperty().getHeadKind())) { + return; + } + List dataList = (List)buildStringList(cellDataList, analysisContext.currentConfiguration()); + ExcelHeadProperty excelHeadPropertyData = analysisContext.currentConfiguration().excelHeadProperty(); + Map headMapData = excelHeadPropertyData.getHeadMap(); + Map contentPropertyMapData = excelHeadPropertyData.getContentPropertyMap(); + Map tmpHeadMap = new HashMap(headMapData.size() * 4 / 3 + 1); + Map tmpContentPropertyMap = + new HashMap(contentPropertyMapData.size() * 4 / 3 + 1); + for (Map.Entry entry : headMapData.entrySet()) { + Head headData = entry.getValue(); + if (headData.getForceIndex()) { + tmpHeadMap.put(entry.getKey(), headData); + tmpContentPropertyMap.put(entry.getKey(), contentPropertyMapData.get(entry.getKey())); + continue; + } + String headName = headData.getHeadNameList().get(0); + for (int i = 0; i < dataList.size(); i++) { + String headString = dataList.get(i); + if (StringUtils.isEmpty(headString)) { + continue; + } + if (analysisContext.currentSheetHolder().getAutoTrim()) { + headString = headString.trim(); + } + if (headName.equals(headString)) { + headData.setColumnIndex(i); + tmpHeadMap.put(i, headData); + tmpContentPropertyMap.put(i, contentPropertyMapData.get(entry.getKey())); + break; + } + } + } + excelHeadPropertyData.setHeadMap(tmpHeadMap); + excelHeadPropertyData.setContentPropertyMap(tmpContentPropertyMap); + } + + private Object buildStringList(List data, ReadConfiguration readConfiguration) { + List list = new ArrayList(); + for (CellData cellData : data) { + Converter converter = readConfiguration.readConverterMap() + .get(ConverterKey.buildConverterKey(String.class, cellData.getType())); + if (converter == null) { + throw new ExcelDataConvertException( + "Converter not found, convert " + cellData.getType() + " to String"); + } + try { + list.add((String)(converter.convertToJavaData(cellData, null))); + } catch (Exception e) { + throw new ExcelDataConvertException("Convert data " + cellData + " to String error ", e); + } + } + return list; + } + protected Map, List> sortAndClearUpHandler( List handlerList, Map, List> parentHandlerMap) { // add @@ -301,11 +456,6 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele return getWriteHandlerMap(); } - @Override - public Map converterMap() { - return getConverterMap(); - } - @Override public boolean needHead() { return getNeedHead(); @@ -326,4 +476,18 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele return getNewInitialization(); } + @Override + public List readListenerList() { + return getReadListenerList(); + } + + @Override + public Map readConverterMap() { + return getReadConverterMap(); + } + + @Override + public Map writeConverterMap() { + return getWriteConverterMap(); + } } diff --git a/src/main/java/com/alibaba/excel/metadata/holder/ReadConfiguration.java b/src/main/java/com/alibaba/excel/metadata/holder/ReadConfiguration.java new file mode 100644 index 0000000..a9358be --- /dev/null +++ b/src/main/java/com/alibaba/excel/metadata/holder/ReadConfiguration.java @@ -0,0 +1,39 @@ +package com.alibaba.excel.metadata.holder; + +import java.util.List; +import java.util.Map; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.converters.ConverterKey; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; +import com.alibaba.excel.read.listener.ReadListener; + +/** + * + * Get the corresponding configuration + * + * @author zhuangjiaju + **/ +public interface ReadConfiguration { + /** + * What handler does the currently operated cell need to execute + * + * @return + */ + List readListenerList(); + + /** + * What converter does the currently operated cell need to execute + * + * @return + */ + Map readConverterMap(); + + /** + * What 'ExcelHeadProperty' does the currently operated cell need to execute + * + * @return + */ + ExcelHeadProperty excelHeadProperty(); + +} diff --git a/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java index 81e7185..a1517a6 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java @@ -10,10 +10,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.converters.ConverterKey; import com.alibaba.excel.metadata.CellStyle; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.TableStyle; import com.alibaba.excel.metadata.property.ExcelHeadProperty; +import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.style.RowCellStyleStrategy; import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy; @@ -23,9 +25,8 @@ import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy * * @author zhuangjiaju */ -public class SheetHolder extends AbstractConfigurationSelector { +public class SheetHolder extends AbstractWriteConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(SheetHolder.class); - /*** * poi sheet */ @@ -51,32 +52,20 @@ public class SheetHolder extends AbstractConfigurationSelector { */ private com.alibaba.excel.metadata.Sheet sheetParam; - public SheetHolder(com.alibaba.excel.metadata.Sheet sheet, WorkbookHolder workbookHolder) { - super(); - this.sheetParam = sheet; - this.parentWorkBook = workbookHolder; - boolean noHead = (sheet.getHead() == null || sheet.getHead().isEmpty()) && sheet.getClazz() == null; - if (noHead) { - // Use parent - setHead(workbookHolder.getHead()); - setClazz(workbookHolder.getClazz()); - } else { - setHead(sheet.getHead()); - setClazz(sheet.getClazz()); - } - // Initialization property - setExcelHeadProperty(new ExcelHeadProperty(getClazz(), getHead(), workbookHolder.getConvertAllFiled())); + public static SheetHolder buildWriteWorkSheetHolder(com.alibaba.excel.metadata.Sheet sheet, + WorkbookHolder workbookHolder) { + SheetHolder sheetHolder = buildBaseSheetHolder(sheet, workbookHolder); - setNewInitialization(Boolean.TRUE); + sheetHolder.setNewInitialization(Boolean.TRUE); if (sheet.getNeedHead() == null) { - setNeedHead(workbookHolder.needHead()); + sheetHolder.setNeedHead(workbookHolder.needHead()); } else { - setNeedHead(sheet.getNeedHead()); + sheetHolder.setNeedHead(sheet.getNeedHead()); } if (sheet.getWriteRelativeHeadRowIndex() == null) { - setWriteRelativeHeadRowIndex(workbookHolder.writeRelativeHeadRowIndex()); + sheetHolder.setWriteRelativeHeadRowIndex(workbookHolder.writeRelativeHeadRowIndex()); } else { - setWriteRelativeHeadRowIndex(sheet.getWriteRelativeHeadRowIndex()); + sheetHolder.setWriteRelativeHeadRowIndex(sheet.getWriteRelativeHeadRowIndex()); } // Compatible with old code compatibleOldCode(sheet); @@ -85,25 +74,86 @@ public class SheetHolder extends AbstractConfigurationSelector { handlerList.addAll(sheet.getCustomWriteHandlerList()); } // Initialization Annotation - initAnnotationConfig(handlerList); - - setWriteHandlerMap(sortAndClearUpHandler(handlerList, workbookHolder.getWriteHandlerMap())); - Map converterMap = new HashMap(workbookHolder.converterMap()); - if (sheet.getCustomConverterMap() != null && !sheet.getCustomConverterMap().isEmpty()) { - converterMap.putAll(sheet.getCustomConverterMap()); + sheetHolder.initAnnotationConfig(handlerList); + + sheetHolder + .setWriteHandlerMap(sheetHolder.sortAndClearUpHandler(handlerList, workbookHolder.getWriteHandlerMap())); + Map converterMap = new HashMap(workbookHolder.getWriteConverterMap()); + if (sheet.getCustomConverterList() != null && !sheet.getCustomConverterList().isEmpty()) { + for (Converter converter : sheet.getCustomConverterList()) { + converterMap.put(converter.getClass(), converter); + } } - setConverterMap(converterMap); - setHasBeenInitializedTable(new HashMap()); + sheetHolder.setWriteConverterMap(converterMap); + sheetHolder.setHasBeenInitializedTable(new HashMap()); if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Sheet writeHandlerMap:{}", getWriteHandlerMap()); + LOGGER.debug("Sheet writeHandlerMap:{}", sheetHolder.getWriteHandlerMap()); + } + return sheetHolder; + } + + public static SheetHolder buildReadWorkSheetHolder(com.alibaba.excel.metadata.Sheet sheet, + WorkbookHolder workbookHolder) { + SheetHolder sheetHolder = buildBaseSheetHolder(sheet, workbookHolder); + if (sheet.getReadHeadRowNumber() == null) { + if (workbookHolder.getReadHeadRowNumber() == null) { + sheetHolder.setReadHeadRowNumber(sheetHolder.getExcelHeadProperty().getHeadRowNumber()); + } else { + sheetHolder.setReadHeadRowNumber(workbookHolder.getReadHeadRowNumber()); + } + } else { + sheetHolder.setReadHeadRowNumber(sheet.getReadHeadRowNumber()); } + + Map converterMap = + new HashMap(workbookHolder.getReadConverterMap()); + if (sheet.getCustomConverterList() != null && !sheet.getCustomConverterList().isEmpty()) { + for (Converter converter : sheet.getCustomConverterList()) { + converterMap.put(ConverterKey.buildConverterKey(converter), converter); + } + } + sheetHolder.setReadConverterMap(converterMap); + + List readListenerList = new ArrayList(); + if (sheet.getCustomReadListenerList() != null && !sheet.getCustomReadListenerList().isEmpty()) { + readListenerList.addAll(sheet.getCustomReadListenerList()); + } + sheetHolder.setReadListenerList(readListenerList); + return sheetHolder; + } + + private static SheetHolder buildBaseSheetHolder(com.alibaba.excel.metadata.Sheet sheet, + WorkbookHolder workbookHolder) { + SheetHolder sheetHolder = new SheetHolder(); + sheetHolder.setSheetParam(sheet); + sheetHolder.setParentWorkBook(workbookHolder); + + boolean noHead = (sheet.getHead() == null || sheet.getHead().isEmpty()) && sheet.getClazz() == null; + if (noHead) { + // Use parent + sheetHolder.setHead(workbookHolder.getHead()); + sheetHolder.setClazz(workbookHolder.getClazz()); + } else { + sheetHolder.setHead(sheet.getHead()); + sheetHolder.setClazz(sheet.getClazz()); + } + + if (sheet.getAutoTrim() == null) { + workbookHolder.setAutoTrim(workbookHolder.getAutoTrim()); + } else { + workbookHolder.setAutoTrim(sheet.getNeedHead()); + } + // Initialization property + sheetHolder + .setExcelHeadProperty(new ExcelHeadProperty(sheetHolder.getClazz(), sheetHolder.getHead(), workbookHolder)); + return sheetHolder; } /** * Compatible with old code */ @Deprecated - private void compatibleOldCode(com.alibaba.excel.metadata.Sheet sheet) { + private static void compatibleOldCode(com.alibaba.excel.metadata.Sheet sheet) { if (sheet.getColumnWidthMap() != null && !sheet.getColumnWidthMap().isEmpty()) { final Map columnWidthMap = sheet.getColumnWidthMap(); if (sheet.getCustomWriteHandlerList() == null) { diff --git a/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java index d30a760..4fa74ad 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java @@ -21,7 +21,7 @@ import com.alibaba.excel.write.style.RowCellStyleStrategy; * * @author zhuangjiaju */ -public class TableHolder extends AbstractConfigurationSelector { +public class TableHolder extends AbstractWriteConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(TableHolder.class); /*** @@ -37,33 +37,35 @@ public class TableHolder extends AbstractConfigurationSelector { */ private com.alibaba.excel.metadata.Table tableParam; - public TableHolder(com.alibaba.excel.metadata.Table table, SheetHolder sheetHolder, WorkbookHolder workbookHolder) { - super(); - this.tableParam = table; - this.parentSheet = sheetHolder; - this.tableNo = table.getTableNo(); + public static TableHolder buildWriteWorkTableHolder(com.alibaba.excel.metadata.Table table, SheetHolder sheetHolder, + WorkbookHolder workbookHolder) { + TableHolder tableHolder = new TableHolder(); + tableHolder.setTableParam(table); + tableHolder.setParentSheet(sheetHolder); + tableHolder.setTableNo(table.getTableNo()); boolean noHead = (table.getHead() == null || table.getHead().isEmpty()) && table.getClazz() == null; if (noHead) { // Use parent - setHead(sheetHolder.getHead()); - setClazz(sheetHolder.getClazz()); + tableHolder.setHead(sheetHolder.getHead()); + tableHolder.setClazz(sheetHolder.getClazz()); } else { - setHead(table.getHead()); - setClazz(table.getClazz()); + tableHolder.setHead(table.getHead()); + tableHolder.setClazz(table.getClazz()); } - setNewInitialization(Boolean.TRUE); + tableHolder.setNewInitialization(Boolean.TRUE); // Initialization property - setExcelHeadProperty(new ExcelHeadProperty(getClazz(), getHead(), workbookHolder.getConvertAllFiled())); + tableHolder.setExcelHeadProperty( + new ExcelHeadProperty(tableHolder.getClazz(), tableHolder.getHead(), workbookHolder.getConvertAllFiled())); if (table.getNeedHead() == null) { - setNeedHead(sheetHolder.needHead()); + tableHolder.setNeedHead(sheetHolder.needHead()); } else { - setNeedHead(table.getNeedHead()); + tableHolder.setNeedHead(table.getNeedHead()); } if (table.getWriteRelativeHeadRowIndex() == null) { - setWriteRelativeHeadRowIndex(sheetHolder.writeRelativeHeadRowIndex()); + tableHolder.setWriteRelativeHeadRowIndex(sheetHolder.writeRelativeHeadRowIndex()); } else { - setWriteRelativeHeadRowIndex(table.getWriteRelativeHeadRowIndex()); + tableHolder.setWriteRelativeHeadRowIndex(table.getWriteRelativeHeadRowIndex()); } // Compatible with old code compatibleOldCode(table); @@ -72,24 +74,28 @@ public class TableHolder extends AbstractConfigurationSelector { handlerList.addAll(table.getCustomWriteHandlerList()); } // Initialization Annotation - initAnnotationConfig(handlerList); + tableHolder.initAnnotationConfig(handlerList); - setWriteHandlerMap(sortAndClearUpHandler(handlerList, sheetHolder.getWriteHandlerMap())); - Map converterMap = new HashMap(sheetHolder.converterMap()); - if (table.getCustomConverterMap() != null && !table.getCustomConverterMap().isEmpty()) { - converterMap.putAll(table.getCustomConverterMap()); + tableHolder + .setWriteHandlerMap(tableHolder.sortAndClearUpHandler(handlerList, sheetHolder.getWriteHandlerMap())); + Map converterMap = new HashMap(sheetHolder.getWriteConverterMap()); + if (table.getCustomConverterList() != null && !table.getCustomConverterList().isEmpty()) { + for (Converter converter : table.getCustomConverterList()) { + converterMap.put(converter.getClass(), converter); + } } - setConverterMap(converterMap); + tableHolder.setWriteConverterMap(converterMap); if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Table writeHandlerMap:{}", getWriteHandlerMap()); + LOGGER.debug("Table writeHandlerMap:{}", tableHolder.getWriteHandlerMap()); } + return tableHolder; } /** * Compatible with old code */ @Deprecated - private void compatibleOldCode(com.alibaba.excel.metadata.Table table) { + private static void compatibleOldCode(com.alibaba.excel.metadata.Table table) { if (table.getTableStyle() != null) { final TableStyle tableStyle = table.getTableStyle(); if (table.getCustomWriteHandlerList() == null) { diff --git a/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java index 1a9f270..b65b8d6 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java @@ -1,5 +1,6 @@ package com.alibaba.excel.metadata.holder; +import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; @@ -11,8 +12,16 @@ import org.apache.poi.ss.usermodel.Workbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.alibaba.excel.cache.ReadCache; +import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.converters.ConverterKey; import com.alibaba.excel.converters.DefaultConverterLoader; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelAnalysisException; +import com.alibaba.excel.read.listener.ModelBuildEventListener; +import com.alibaba.excel.read.listener.ReadListener; +import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.write.handler.DefaultWriteHandlerLoader; import com.alibaba.excel.write.handler.WriteHandler; @@ -21,8 +30,9 @@ import com.alibaba.excel.write.handler.WriteHandler; * * @author zhuangjiaju */ -public class WorkbookHolder extends AbstractConfigurationSelector { +public class WorkbookHolder extends AbstractWriteConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(WorkbookHolder.class); + /*** * poi Workbook */ @@ -40,13 +50,53 @@ public class WorkbookHolder extends AbstractConfigurationSelector { */ private OutputStream outputStream; /** - * Template input stream + *
  • write: Template input stream + *
  • read: Read InputStream + *

    + * If 'inputStream' and 'file' all not empty,file first + */ + private InputStream inputStream; + /** + *

  • write: Template file + *
  • read: Read file + *

    + * If 'inputStream' and 'file' all not empty,file first */ - private InputStream templateInputStream; + private File file; /** * Default true */ private Boolean autoCloseStream; + /** + * Excel type + */ + private ExcelTypeEnum excelType; + /** + * This object can be read in the Listener {@link AnalysisEventListener#invoke(Object, AnalysisContext)} + * {@link AnalysisContext#getCustom()} + * + */ + private Object readCustomObject; + /** + * A cache that stores temp data to save memory.Default use {@link com.alibaba.excel.cache.Ehcache} + */ + private ReadCache readCache; + /** + * true if date uses 1904 windowing, or false if using 1900 date windowing. + * + * @return + */ + private Boolean use1904windowing; + + /** + * Mmandatory use 'inputStream' + */ + private Boolean mandatoryUseInputStream; + + /** + * Temporary files when reading excel + */ + private File readTempFile; /** * The default is all excel objects.if true , you can use {@link com.alibaba.excel.annotation.ExcelIgnore} ignore a @@ -65,50 +115,91 @@ public class WorkbookHolder extends AbstractConfigurationSelector { @Deprecated private com.alibaba.excel.event.WriteHandler writeHandler; - public WorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) { - super(); - this.workbookParam = workbook; - this.templateInputStream = workbook.getTemplateInputStream(); - this.outputStream = workbook.getOutputStream(); - this.templateInputStream = workbook.getTemplateInputStream(); - setHead(workbook.getHead()); - setClazz(workbook.getClazz()); - setNewInitialization(Boolean.TRUE); - if (workbook.getConvertAllFiled() == null) { - this.convertAllFiled = Boolean.TRUE; - } else { - this.convertAllFiled = workbook.getConvertAllFiled(); - } - if (workbook.getAutoCloseStream() == null) { - setAutoCloseStream(Boolean.TRUE); - } else { - setAutoCloseStream(workbook.getAutoCloseStream()); - } + public static WorkbookHolder buildWriteWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) { + WorkbookHolder workbookHolder = buildBaseWorkbookHolder(workbook); + workbookHolder.setNewInitialization(Boolean.TRUE); if (workbook.getNeedHead() == null) { - setNeedHead(Boolean.TRUE); + workbookHolder.setNeedHead(Boolean.TRUE); } else { - setNeedHead(workbook.getNeedHead()); + workbookHolder.setNeedHead(workbook.getNeedHead()); } if (workbook.getWriteRelativeHeadRowIndex() == null) { - setWriteRelativeHeadRowIndex(0); + workbookHolder.setWriteRelativeHeadRowIndex(0); } else { - setWriteRelativeHeadRowIndex(workbook.getWriteRelativeHeadRowIndex()); + workbookHolder.setWriteRelativeHeadRowIndex(workbook.getWriteRelativeHeadRowIndex()); } List handlerList = new ArrayList(); if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) { handlerList.addAll(workbook.getCustomWriteHandlerList()); } handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler()); - setWriteHandlerMap(sortAndClearUpHandler(handlerList, null)); + workbookHolder.setWriteHandlerMap(workbookHolder.sortAndClearUpHandler(handlerList, null)); + Map converterMap = DefaultConverterLoader.loadDefaultWriteConverter(); - if (workbook.getCustomConverterMap() != null && !workbook.getCustomConverterMap().isEmpty()) { - converterMap.putAll(workbook.getCustomConverterMap()); + if (workbook.getCustomConverterList() != null && !workbook.getCustomConverterList().isEmpty()) { + for (Converter converter : workbook.getCustomConverterList()) { + converterMap.put(converter.getClass(), converter); + } } - setConverterMap(converterMap); - setHasBeenInitializedSheet(new HashMap()); + workbookHolder.setWriteConverterMap(converterMap); + workbookHolder.setHasBeenInitializedSheet(new HashMap()); if (LOGGER.isDebugEnabled()) { - LOGGER.debug("Wookbook writeHandlerMap:{}", getWriteHandlerMap()); + LOGGER.debug("Wookbook writeHandlerMap:{}", workbookHolder.getWriteHandlerMap()); + } + return workbookHolder; + } + + public static WorkbookHolder buildReadWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) { + WorkbookHolder workbookHolder = buildBaseWorkbookHolder(workbook); + if (workbook.getFile() == null && workbookHolder.getInputStream() == null) { + throw new ExcelAnalysisException("Read excel 'file' and 'inputStream' cannot be empty at the same time!"); } + workbookHolder.setReadCustomObject(workbook.getReadCustomObject()); + workbookHolder.setReadHeadRowNumber(workbook.getReadHeadRowNumber()); + workbookHolder.setReadCache(workbook.getReadCache()); + + Map converterMap = DefaultConverterLoader.loadDefaultReadConverter(); + if (workbook.getCustomConverterList() != null && !workbook.getCustomConverterList().isEmpty()) { + for (Converter converter : workbook.getCustomConverterList()) { + converterMap.put(ConverterKey.buildConverterKey(converter), converter); + } + } + workbookHolder.setReadConverterMap(converterMap); + + List readListenerList = new ArrayList(); + readListenerList.add(new ModelBuildEventListener()); + if (workbook.getCustomReadListenerList() != null && !workbook.getCustomReadListenerList().isEmpty()) { + readListenerList.addAll(workbook.getCustomReadListenerList()); + } + workbookHolder.setReadListenerList(readListenerList); + return workbookHolder; + } + + private static WorkbookHolder buildBaseWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) { + WorkbookHolder workbookHolder = new WorkbookHolder(); + workbookHolder.setUse1904windowing(workbook.getUse1904windowing()); + workbookHolder.setWorkbookParam(workbook); + workbookHolder.setInputStream(workbook.getInputStream()); + workbookHolder.setFile(workbook.getFile()); + workbookHolder.setExcelType(workbook.getExcelType()); + workbookHolder.setHead(workbook.getHead()); + workbookHolder.setClazz(workbook.getClazz()); + if (workbook.getConvertAllFiled() == null) { + workbookHolder.setConvertAllFiled(Boolean.TRUE); + } else { + workbookHolder.setConvertAllFiled(workbook.getConvertAllFiled()); + } + if (workbook.getAutoCloseStream() == null) { + workbookHolder.setAutoCloseStream(Boolean.TRUE); + } else { + workbookHolder.setAutoCloseStream(workbook.getAutoCloseStream()); + } + if (workbook.getAutoTrim() == null) { + workbookHolder.setAutoTrim(Boolean.TRUE); + } else { + workbookHolder.setAutoTrim(workbook.getNeedHead()); + } + return workbookHolder; } public Workbook getWorkbook() { @@ -143,12 +234,12 @@ public class WorkbookHolder extends AbstractConfigurationSelector { this.outputStream = outputStream; } - public InputStream getTemplateInputStream() { - return templateInputStream; + public InputStream getInputStream() { + return inputStream; } - public void setTemplateInputStream(InputStream templateInputStream) { - this.templateInputStream = templateInputStream; + public void setInputStream(InputStream inputStream) { + this.inputStream = inputStream; } public com.alibaba.excel.event.WriteHandler getWriteHandler() { @@ -174,4 +265,60 @@ public class WorkbookHolder extends AbstractConfigurationSelector { public void setConvertAllFiled(Boolean convertAllFiled) { this.convertAllFiled = convertAllFiled; } + + public File getFile() { + return file; + } + + public void setFile(File file) { + this.file = file; + } + + public ExcelTypeEnum getExcelType() { + return excelType; + } + + public void setExcelType(ExcelTypeEnum excelType) { + this.excelType = excelType; + } + + public Object getReadCustomObject() { + return readCustomObject; + } + + public void setReadCustomObject(Object readCustomObject) { + this.readCustomObject = readCustomObject; + } + + public ReadCache getReadCache() { + return readCache; + } + + public void setReadCache(ReadCache readCache) { + this.readCache = readCache; + } + + public Boolean getUse1904windowing() { + return use1904windowing; + } + + public void setUse1904windowing(Boolean use1904windowing) { + this.use1904windowing = use1904windowing; + } + + public Boolean getMandatoryUseInputStream() { + return mandatoryUseInputStream; + } + + public void setMandatoryUseInputStream(Boolean mandatoryUseInputStream) { + this.mandatoryUseInputStream = mandatoryUseInputStream; + } + + public File getReadTempFile() { + return readTempFile; + } + + public void setReadTempFile(File readTempFile) { + this.readTempFile = readTempFile; + } } diff --git a/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java b/src/main/java/com/alibaba/excel/metadata/holder/WriteConfiguration.java similarity index 93% rename from src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java rename to src/main/java/com/alibaba/excel/metadata/holder/WriteConfiguration.java index fe93026..3a88a05 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/WriteConfiguration.java @@ -13,7 +13,7 @@ import com.alibaba.excel.write.handler.WriteHandler; * * @author zhuangjiaju **/ -public interface ConfigurationSelector { +public interface WriteConfiguration { /** * What handler does the currently operated cell need to execute @@ -27,7 +27,7 @@ public interface ConfigurationSelector { * * @return */ - Map converterMap(); + Map writeConverterMap(); /** * Whether a header is required for the currently operated cell diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java index 22f7b94..70d72c3 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java @@ -19,6 +19,12 @@ public class ExcelContentProperty { private CellStyleProperty cellStyleProperty; private DateTimeFormatProperty dateTimeFormatProperty; private NumberFormatProperty numberFormatProperty; + /** + * true if date uses 1904 windowing, or false if using 1900 date windowing. + * + * @return + */ + private Boolean use1904windowing; public Field getField() { return field; @@ -59,4 +65,12 @@ public class ExcelContentProperty { public void setNumberFormatProperty(NumberFormatProperty numberFormatProperty) { this.numberFormatProperty = numberFormatProperty; } + + public Boolean getUse1904windowing() { + return use1904windowing; + } + + public void setUse1904windowing(Boolean use1904windowing) { + this.use1904windowing = use1904windowing; + } } 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 af478f5..136e033 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java @@ -23,6 +23,8 @@ import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.metadata.CellRange; import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.holder.WorkbookHolder; +import com.alibaba.excel.util.StringUtils; /** * Define the header attribute of excel @@ -49,7 +51,6 @@ public class ExcelHeadProperty { * Configuration header information */ private Map headMap; - /** * Configuration column information */ @@ -57,7 +58,7 @@ public class ExcelHeadProperty { private RowHeightProperty headRowHeightProperty; private RowHeightProperty contentRowHeightProperty; - public ExcelHeadProperty(Class headClazz, List> head, Boolean convertAllFiled) { + public ExcelHeadProperty(Class headClazz, List> head, WorkbookHolder workbookHolder) { this.headClazz = headClazz; headMap = new TreeMap(); contentPropertyMap = new TreeMap(); @@ -71,27 +72,18 @@ public class ExcelHeadProperty { headKind = HeadKindEnum.STRING; } else { // convert headClazz to head - initColumnProperties(convertAllFiled); + initColumnProperties(workbookHolder); } initHeadRowNumber(); - LOGGER.info("The initialization sheet/table 'ExcelHeadProperty' is complete , head kind is {}", headKind); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("The initialization sheet/table 'ExcelHeadProperty' is complete , head kind is {}", headKind); + } if (!hasHead()) { LOGGER.warn( "The table has no header set and all annotations will not be read.If you want to use annotations, please use set head class in ExcelWriterBuilder/ExcelWriterSheetBuilder/ExcelWriterTableBuilder"); } } - public static ExcelHeadProperty buildExcelHeadProperty(ExcelHeadProperty excelHeadProperty, Class clazz, - List headOneRow) { - if (excelHeadProperty == null) { - return new ExcelHeadProperty(clazz, new ArrayList>(), false); - } - if (headOneRow != null) { - excelHeadProperty.appendOneRow(headOneRow); - } - return excelHeadProperty; - } - private void initHeadRowNumber() { headRowNumber = 0; for (Head head : headMap.values()) { @@ -112,7 +104,7 @@ public class ExcelHeadProperty { } } - private void initColumnProperties(Boolean convertAllFiled) { + private void initColumnProperties(WorkbookHolder workbookHolder) { if (headClazz == null) { return; } @@ -135,7 +127,7 @@ public class ExcelHeadProperty { continue; } ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); - if (excelProperty == null && !convertAllFiled) { + if (excelProperty == null && (workbookHolder == null || !workbookHolder.getConvertAllFiled())) { continue; } if (excelProperty == null || excelProperty.index() < 0) { @@ -160,22 +152,23 @@ public class ExcelHeadProperty { int index = 0; for (Field field : defaultFieldList) { while (customFiledMap.containsKey(index)) { - initOneColumnProperty(index, customFiledMap.get(index), headStyle, contentStyle, columnWidth); + initOneColumnProperty(index, customFiledMap.get(index), headStyle, contentStyle, columnWidth, + workbookHolder); customFiledMap.remove(index); index++; } - initOneColumnProperty(index, field, headStyle, contentStyle, columnWidth); + initOneColumnProperty(index, field, headStyle, contentStyle, columnWidth, workbookHolder); index++; } for (Map.Entry entry : customFiledMap.entrySet()) { - initOneColumnProperty(index, entry.getValue(), headStyle, contentStyle, columnWidth); + initOneColumnProperty(index, entry.getValue(), headStyle, contentStyle, columnWidth, workbookHolder); index++; } headKind = HeadKindEnum.CLASS; } private void initOneColumnProperty(int index, Field field, HeadStyle parentHeadStyle, - ContentStyle parentContentStyle, ColumnWidth parentColumnWidth) { + ContentStyle parentContentStyle, ColumnWidth parentColumnWidth, WorkbookHolder workbookHolder) { ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); List tmpHeadList = new ArrayList(); @@ -184,6 +177,9 @@ public class ExcelHeadProperty { } else { tmpHeadList.add(field.getName()); } + if (tmpHeadList.isEmpty() || StringUtils.isEmpty(tmpHeadList.get(0))) { + tmpHeadList.add(field.getName()); + } Head head = new Head(index, field.getName(), tmpHeadList); HeadStyle headStyle = field.getAnnotation(HeadStyle.class); if (headStyle == null) { @@ -211,26 +207,12 @@ public class ExcelHeadProperty { excelContentProperty .setNumberFormatProperty(NumberFormatProperty.build(field.getAnnotation(NumberFormat.class))); - headMap.put(index, head); - contentPropertyMap.put(index, excelContentProperty); - } - /** - * Add one more head under the last head - */ - public void appendOneRow(List row) { - for (int i = 0; i < row.size(); i++) { - String rowData = row.get(i); - // join - if (headMap.containsKey(i)) { - headMap.get(i).getHeadNameList().add(rowData); - } else { - // create and join - int index = ((TreeMap)headMap).lastKey() + 1; - headMap.put(index, new Head(i, null, rowData)); - } + if (workbookHolder != null && workbookHolder.getReadGlobalProperty() != null) { + excelContentProperty.setGlobalProperty(workbookHolder.getReadGlobalProperty()); } - initHeadRowNumber(); + headMap.put(index, head); + contentPropertyMap.put(index, excelContentProperty); } public Class getHeadClazz() { diff --git a/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java new file mode 100644 index 0000000..77519e2 --- /dev/null +++ b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java @@ -0,0 +1,21 @@ +package com.alibaba.excel.read.builder; + +import com.alibaba.excel.metadata.Workbook; + +/** + * Build ExcelWriter + * + * @author zhuangjiaju + */ +public class ExcelReaderBuilder { + /** + * Workbook + */ + private Workbook workbook; + + public ExcelReaderBuilder() { + this.workbook = new Workbook(); + } + + +} diff --git a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java new file mode 100644 index 0000000..68cf517 --- /dev/null +++ b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java @@ -0,0 +1,98 @@ +package com.alibaba.excel.read.listener; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.converters.ConverterKey; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.enums.HeadKindEnum; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelDataConvertException; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.holder.ReadConfiguration; +import com.alibaba.excel.metadata.property.ExcelContentProperty; +import com.alibaba.excel.metadata.property.ExcelHeadProperty; + +import net.sf.cglib.beans.BeanMap; + +/** + * Convert to the object the user needs + * + * @author jipengfei + */ +public class ModelBuildEventListener extends AnalysisEventListener> { + @Override + public void onException(Exception exception, AnalysisContext context) throws Exception {} + + @Override + public void invoke(List data, AnalysisContext context) { + ReadConfiguration readConfiguration = context.currentConfiguration(); + if (HeadKindEnum.CLASS.equals(context.currentSheetHolder().getExcelHeadProperty().getHeadKind())) { + context.setCurrentRowAnalysisResult(buildUserModel(data, readConfiguration)); + return; + } + context.setCurrentRowAnalysisResult(buildStringList(data, readConfiguration)); + } + + private Object buildStringList(List data, ReadConfiguration readConfiguration) { + List list = new ArrayList(); + for (CellData cellData : data) { + list.add((String)convertValue(cellData, String.class, null, readConfiguration.readConverterMap())); + } + return list; + } + + private Object buildUserModel(List data, ReadConfiguration readConfiguration) { + ExcelHeadProperty excelHeadProperty = readConfiguration.excelHeadProperty(); + Object resultModel; + try { + resultModel = excelHeadProperty.getHeadClazz().newInstance(); + } catch (Exception e) { + throw new ExcelDataConvertException("Can not instance class: " + excelHeadProperty.getHeadClazz().getName(), + e); + } + Map map = new HashMap(); + Map headMap = excelHeadProperty.getHeadMap(); + Map contentPropertyMap = excelHeadProperty.getContentPropertyMap(); + for (Map.Entry entry : headMap.entrySet()) { + Integer index = entry.getKey(); + if (index >= data.size()) { + continue; + } + CellData cellData = data.get(index); + if (cellData.getType() == CellDataTypeEnum.EMPTY) { + continue; + } + ExcelContentProperty excelContentProperty = contentPropertyMap.get(index); + Object value = convertValue(cellData, excelContentProperty.getField().getClass(), excelContentProperty, + readConfiguration.readConverterMap()); + if (value != null) { + map.put(excelContentProperty.getField().getName(), value); + } + } + BeanMap.create(resultModel).putAll(map); + return resultModel; + } + + private Object convertValue(CellData cellData, Class clazz, ExcelContentProperty contentProperty, + Map readConverterMap) { + Converter converter = readConverterMap.get(ConverterKey.buildConverterKey(clazz, cellData.getType())); + if (converter == null) { + throw new ExcelDataConvertException( + "Converter not found, convert " + cellData.getType() + " to " + clazz.getName()); + } + try { + return converter.convertToJavaData(cellData, contentProperty); + } 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/event/ReadListener.java b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java similarity index 59% rename from src/main/java/com/alibaba/excel/event/ReadListener.java rename to src/main/java/com/alibaba/excel/read/listener/ReadListener.java index 459f378..c86a0ed 100644 --- a/src/main/java/com/alibaba/excel/event/ReadListener.java +++ b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java @@ -1,6 +1,7 @@ -package com.alibaba.excel.event; +package com.alibaba.excel.read.listener; import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.Listener; /** * Interface to listen for read results @@ -19,14 +20,14 @@ public interface ReadListener extends Listener { void onException(Exception exception, AnalysisContext context) throws Exception; /** - * when analysis one row trigger invoke function + * when analysis one row trigger invoke function. * - * @param object - * one row value + * @param data + * one row value. Is is same as {@link AnalysisContext#currentRowAnalysisResult()} * @param context * analysis context */ - void invoke(T object, AnalysisContext context); + void invoke(T data, AnalysisContext context); /** * if have something to do after all analysis @@ -34,4 +35,12 @@ public interface ReadListener extends Listener { * @param context */ void doAfterAllAnalysed(AnalysisContext context); + + /** + * Verify that there is another piece of data.You can stop the read by returning false + * + * @param context + * @return + */ + boolean hasNext(AnalysisContext context); } diff --git a/src/main/java/com/alibaba/excel/read/listener/ReadListenerRegistryCenter.java b/src/main/java/com/alibaba/excel/read/listener/ReadListenerRegistryCenter.java new file mode 100644 index 0000000..745d5e9 --- /dev/null +++ b/src/main/java/com/alibaba/excel/read/listener/ReadListenerRegistryCenter.java @@ -0,0 +1,35 @@ +package com.alibaba.excel.read.listener; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisFinishEvent; + +/** + * Registry center. + * + * @author jipengfei + */ +public interface ReadListenerRegistryCenter { + + /** + * register + * + * @param listener + */ + void register(AnalysisEventListener listener); + + /** + * Parse one row to notify all event listeners + * + * @param event + * parse event + * @param analysisContext + */ + void notifyEndOneRow(AnalysisFinishEvent event, AnalysisContext analysisContext); + + /** + * + * @param analysisContext + */ + void notifyAfterAllAnalysed(AnalysisContext analysisContext); +} diff --git a/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java b/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java index dc5f5d3..29f110d 100644 --- a/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java +++ b/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java @@ -1,10 +1,10 @@ package com.alibaba.excel.support; -import org.apache.poi.poifs.filesystem.FileMagic; - import java.io.IOException; import java.io.InputStream; +import org.apache.poi.poifs.filesystem.FileMagic; + /** * @author jipengfei */ @@ -18,6 +18,24 @@ public enum ExcelTypeEnum { this.setValue(value); } + public static ExcelTypeEnum valueOf(InputStream inputStream) { + try { + if (!inputStream.markSupported()) { + return null; + } + FileMagic fileMagic = FileMagic.valueOf(inputStream); + if (FileMagic.OLE2.equals(fileMagic)) { + return XLS; + } + if (FileMagic.OOXML.equals(fileMagic)) { + return XLSX; + } + return null; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + public String getValue() { return value; } @@ -25,23 +43,4 @@ public enum ExcelTypeEnum { public void setValue(String value) { this.value = value; } - - public static ExcelTypeEnum valueOf(InputStream inputStream){ - return XLSX; -// try { -// if (!inputStream.markSupported()) { -// return null; -// } -// FileMagic fileMagic = FileMagic.valueOf(inputStream); -// if(FileMagic.OLE2.equals(fileMagic)){ -// return XLS; -// } -// if(FileMagic.OOXML.equals(fileMagic)){ -// return XLSX; -// } -// return null; -// } catch (IOException e) { -// throw new RuntimeException(e); -// } - } } diff --git a/src/main/java/com/alibaba/excel/util/POITempFile.java b/src/main/java/com/alibaba/excel/util/FileUtils.java similarity index 55% rename from src/main/java/com/alibaba/excel/util/POITempFile.java rename to src/main/java/com/alibaba/excel/util/FileUtils.java index 1cf8662..e6a4554 100644 --- a/src/main/java/com/alibaba/excel/util/POITempFile.java +++ b/src/main/java/com/alibaba/excel/util/FileUtils.java @@ -1,13 +1,19 @@ package com.alibaba.excel.util; import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.UUID; +import com.alibaba.excel.exception.ExcelAnalysisException; + /** * * @author jipengfei */ -public class POITempFile { +public class FileUtils { private static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; @@ -15,9 +21,44 @@ public class POITempFile { private static final String CACHE = "excache"; + /** + * Write inputStream to file + * + * @param file + * @param inputStream + */ + public static void writeToFile(File file, InputStream inputStream) { + OutputStream outputStream = null; + try { + outputStream = new FileOutputStream(file); + int bytesRead; + byte[] buffer = new byte[8192]; + while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } catch (Exception e) { + throw new ExcelAnalysisException("Can not create temporary file!", e); + } finally { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + throw new ExcelAnalysisException("Can not close 'outputStream'!", e); + } + } + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + throw new ExcelAnalysisException("Can not close 'inputStream'", e); + } + } + } + } + /** */ - public static void createPOIFilesDirectory() { + public static void createPoiFilesDirectory() { createTmpDirectory(POIFILES); } diff --git a/src/main/java/com/alibaba/excel/util/NumberUtils.java b/src/main/java/com/alibaba/excel/util/NumberUtils.java index 3b5c48c..678da15 100644 --- a/src/main/java/com/alibaba/excel/util/NumberUtils.java +++ b/src/main/java/com/alibaba/excel/util/NumberUtils.java @@ -22,7 +22,7 @@ public class NumberUtils { * @return */ public static String format(Number num, ExcelContentProperty contentProperty) { - if (contentProperty.getNumberFormatProperty() == null + if (contentProperty == null || contentProperty.getNumberFormatProperty() == null || StringUtils.isEmpty(contentProperty.getNumberFormatProperty().getFormat())) { return num.toString(); } diff --git a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java index 13ad6fd..fa68e0b 100644 --- a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java +++ b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java @@ -3,6 +3,7 @@ package com.alibaba.excel.util; import java.io.IOException; import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; @@ -12,6 +13,7 @@ import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import com.alibaba.excel.metadata.holder.WorkbookHolder; import com.alibaba.excel.support.ExcelTypeEnum; /** @@ -20,16 +22,24 @@ import com.alibaba.excel.support.ExcelTypeEnum; */ public class WorkBookUtil { - public static Workbook createWorkBook(com.alibaba.excel.metadata.Workbook workbookParam) throws IOException { - Workbook workbook; - if (ExcelTypeEnum.XLS.equals(workbookParam.getExcelType())) { - workbook = (workbookParam.getTemplateInputStream() == null) ? new HSSFWorkbook() - : new HSSFWorkbook(new POIFSFileSystem(workbookParam.getTemplateInputStream())); - } else { - workbook = (workbookParam.getTemplateInputStream() == null) ? new SXSSFWorkbook(500) - : new SXSSFWorkbook(new XSSFWorkbook(workbookParam.getTemplateInputStream())); + public static Workbook createWorkBook(WorkbookHolder workbookHolder) + throws IOException, InvalidFormatException { + if (ExcelTypeEnum.XLSX.equals(workbookHolder.getExcelType())) { + if (workbookHolder.getFile() != null) { + return new SXSSFWorkbook(new XSSFWorkbook(workbookParam.getFile())); + } + if (workbookParam.getInputStream() != null) { + return new SXSSFWorkbook(new XSSFWorkbook(workbookParam.getInputStream())); + } + return new SXSSFWorkbook(500); } - return workbook; + if (workbookParam.getFile() != null) { + return new HSSFWorkbook(new POIFSFileSystem(workbookParam.getFile())); + } + if (workbookParam.getInputStream() != null) { + return new HSSFWorkbook(new POIFSFileSystem(workbookParam.getInputStream())); + } + return new HSSFWorkbook(); } public static Sheet createSheet(Workbook workbook, com.alibaba.excel.metadata.Sheet sheet) { diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java index 055804c..d3f05eb 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -17,7 +17,7 @@ import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Table; -import com.alibaba.excel.metadata.holder.ConfigurationSelector; +import com.alibaba.excel.metadata.holder.WriteConfiguration; import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.POITempFile; @@ -47,8 +47,8 @@ public class ExcelBuilderImpl implements ExcelBuilder { } org.apache.poi.ss.usermodel.Sheet currentSheet = context.currentSheetHolder().getSheet(); int rowNum = currentSheet.getLastRowNum(); - if (context.currentConfigurationSelector().isNew()) { - rowNum += context.currentConfigurationSelector().writeRelativeHeadRowIndex(); + if (context.currentConfiguration().isNew()) { + rowNum += context.currentConfiguration().writeRelativeHeadRowIndex(); } for (int relativeRowIndex = 0; relativeRowIndex < data.size(); relativeRowIndex++) { int n = relativeRowIndex + rowNum + 1; @@ -92,7 +92,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { private void beforeRowCreate(int rowIndex, int relativeRowIndex) { List handlerList = - context.currentConfigurationSelector().writeHandlerMap().get(RowWriteHandler.class); + context.currentConfiguration().writeHandlerMap().get(RowWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -106,7 +106,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { private void afterRowCreate(Row row, int relativeRowIndex) { List handlerList = - context.currentConfigurationSelector().writeHandlerMap().get(RowWriteHandler.class); + context.currentConfiguration().writeHandlerMap().get(RowWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -125,7 +125,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { if (CollectionUtils.isEmpty(oneRowData)) { return; } - Map headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap(); + Map headMap = context.currentConfiguration().excelHeadProperty().getHeadMap(); int dataIndex = 0; int cellIndex = 0; for (Map.Entry entry : headMap.entrySet()) { @@ -153,17 +153,17 @@ public class ExcelBuilderImpl implements ExcelBuilder { beforeCellCreate(row, head, relativeRowIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex); Object value = oneRowData.get(dataIndex); - converterAndSet(context.currentConfigurationSelector(), value.getClass(), cell, value, null); + converterAndSet(context.currentConfiguration(), value.getClass(), cell, value, null); afterCellCreate(head, cell, relativeRowIndex); } private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex) { - ConfigurationSelector currentConfigurationSelector = context.currentConfigurationSelector(); + WriteConfiguration currentWriteConfiguration = context.currentConfiguration(); BeanMap beanMap = BeanMap.create(oneRowData); Set beanMapHandledSet = new HashSet(); - Map headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap(); + Map headMap = context.currentConfiguration().excelHeadProperty().getHeadMap(); Map contentPropertyMap = - context.currentConfigurationSelector().excelHeadProperty().getContentPropertyMap(); + context.currentConfiguration().excelHeadProperty().getContentPropertyMap(); int cellIndex = 0; for (Map.Entry entry : contentPropertyMap.entrySet()) { cellIndex = entry.getKey(); @@ -176,7 +176,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { beforeCellCreate(row, head, relativeRowIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex); Object value = beanMap.get(name); - converterAndSet(currentConfigurationSelector, excelContentProperty.getField().getType(), cell, value, + converterAndSet(currentWriteConfiguration, excelContentProperty.getField().getType(), cell, value, excelContentProperty); afterCellCreate(head, cell, relativeRowIndex); beanMapHandledSet.add(name); @@ -195,14 +195,14 @@ public class ExcelBuilderImpl implements ExcelBuilder { } beforeCellCreate(row, null, relativeRowIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex++); - converterAndSet(currentConfigurationSelector, entry.getValue().getClass(), cell, entry.getValue(), null); + converterAndSet(currentWriteConfiguration, entry.getValue().getClass(), cell, entry.getValue(), null); afterCellCreate(null, cell, relativeRowIndex); } } private void beforeCellCreate(Row row, Head head, int relativeRowIndex) { List handlerList = - context.currentConfigurationSelector().writeHandlerMap().get(CellWriteHandler.class); + context.currentConfiguration().writeHandlerMap().get(CellWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -217,7 +217,7 @@ public class ExcelBuilderImpl implements ExcelBuilder { private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) { List handlerList = - context.currentConfigurationSelector().writeHandlerMap().get(CellWriteHandler.class); + context.currentConfiguration().writeHandlerMap().get(CellWriteHandler.class); if (handlerList == null || handlerList.isEmpty()) { return; } @@ -232,12 +232,12 @@ public class ExcelBuilderImpl implements ExcelBuilder { } } - private void converterAndSet(ConfigurationSelector currentConfigurationSelector, Class clazz, Cell cell, - Object value, ExcelContentProperty excelContentProperty) { + private void converterAndSet(WriteConfiguration currentWriteConfiguration, Class clazz, Cell cell, + Object value, ExcelContentProperty excelContentProperty) { if (value == null) { return; } - Converter converter = currentConfigurationSelector.converterMap().get(clazz); + Converter converter = currentWriteConfiguration.converterMap().get(clazz); if (converter == null) { throw new ExcelDataConvertException( "Can not find 'Converter' support class " + clazz.getSimpleName() + "."); diff --git a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java index 6bbab00..df8c84b 100644 --- a/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java +++ b/src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java @@ -1,7 +1,6 @@ package com.alibaba.excel.write.builder; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; @@ -170,25 +169,22 @@ public class ExcelWriterBuilder { return outputFile(new File(outputUri)); } - public ExcelWriterBuilder withTemplate(InputStream templateInputStream) { - workbook.setTemplateInputStream(templateInputStream); + public ExcelWriterBuilder withTemplate(InputStream inputStream) { + workbook.setInputStream(inputStream); return this; } - public ExcelWriterBuilder withTemplate(File templateFile) { - try { - return withTemplate(new FileInputStream(templateFile)); - } catch (FileNotFoundException e) { - throw new ExcelGenerateException("Can not create file", e); - } + public ExcelWriterBuilder withTemplate(File file) { + workbook.setFile(file); + return this; } - public ExcelWriterBuilder withTemplate(String templatePathName) { - return withTemplate(new File(templatePathName)); + public ExcelWriterBuilder withTemplate(String pathName) { + return withTemplate(new File(pathName)); } - public ExcelWriterBuilder withTemplate(URI templateUri) { - return withTemplate(new File(templateUri)); + public ExcelWriterBuilder withTemplate(URI uri) { + return withTemplate(new File(uri)); } /**