Browse Source

优化读文件逻辑

developing
zhuangjiaju 5 years ago
parent
commit
c8d64352d6
  1. 163
      src/main/java/com/alibaba/excel/ExcelReader.java
  2. 4
      src/main/java/com/alibaba/excel/ExcelWriter.java
  3. 112
      src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java
  4. 18
      src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java
  5. 97
      src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java
  6. 18
      src/main/java/com/alibaba/excel/analysis/ExcelExecutor.java
  7. 61
      src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
  8. 10
      src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java
  9. 19
      src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java
  10. 6
      src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java
  11. 214
      src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java
  12. 11
      src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
  13. 22
      src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java
  14. 27
      src/main/java/com/alibaba/excel/cache/Cache.java
  15. 4
      src/main/java/com/alibaba/excel/cache/Ehcache.java
  16. 15
      src/main/java/com/alibaba/excel/cache/Ehcache2.java
  17. 2
      src/main/java/com/alibaba/excel/cache/EhcacheFile.java
  18. 2
      src/main/java/com/alibaba/excel/cache/EhcacheMix.java
  19. 34
      src/main/java/com/alibaba/excel/cache/ReadCache.java
  20. 4
      src/main/java/com/alibaba/excel/cache/SharedStringsTableReadCache.java
  21. 110
      src/main/java/com/alibaba/excel/context/AnalysisContext.java
  22. 183
      src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java
  23. 4
      src/main/java/com/alibaba/excel/context/WriteContext.java
  24. 54
      src/main/java/com/alibaba/excel/context/WriteContextImpl.java
  25. 9
      src/main/java/com/alibaba/excel/converters/ConverterRegistryCenter.java
  26. 8
      src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java
  27. 4
      src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java
  28. 2
      src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java
  29. 8
      src/main/java/com/alibaba/excel/event/AnalysisEventListener.java
  30. 35
      src/main/java/com/alibaba/excel/event/AnalysisEventRegistryCenter.java
  31. 1
      src/main/java/com/alibaba/excel/event/EachRowAnalysisFinishEvent.java
  32. 81
      src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java
  33. 26
      src/main/java/com/alibaba/excel/metadata/BasicParameter.java
  34. 13
      src/main/java/com/alibaba/excel/metadata/Head.java
  35. 43
      src/main/java/com/alibaba/excel/metadata/Workbook.java
  36. 204
      src/main/java/com/alibaba/excel/metadata/holder/AbstractWriteConfiguration.java
  37. 39
      src/main/java/com/alibaba/excel/metadata/holder/ReadConfiguration.java
  38. 112
      src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java
  39. 54
      src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java
  40. 219
      src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java
  41. 4
      src/main/java/com/alibaba/excel/metadata/holder/WriteConfiguration.java
  42. 14
      src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java
  43. 60
      src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
  44. 21
      src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java
  45. 98
      src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java
  46. 19
      src/main/java/com/alibaba/excel/read/listener/ReadListener.java
  47. 35
      src/main/java/com/alibaba/excel/read/listener/ReadListenerRegistryCenter.java
  48. 41
      src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java
  49. 45
      src/main/java/com/alibaba/excel/util/FileUtils.java
  50. 2
      src/main/java/com/alibaba/excel/util/NumberUtils.java
  51. 28
      src/main/java/com/alibaba/excel/util/WorkBookUtil.java
  52. 32
      src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  53. 22
      src/main/java/com/alibaba/excel/write/builder/ExcelWriterBuilder.java

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

@ -3,11 +3,16 @@ package com.alibaba.excel;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.ExcelAnalyser; import com.alibaba.excel.analysis.ExcelAnalyser;
import com.alibaba.excel.analysis.ExcelAnalyserImpl; import com.alibaba.excel.analysis.ExcelAnalyserImpl;
import com.alibaba.excel.analysis.ExcelExecutor;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.parameter.AnalysisParam; import com.alibaba.excel.parameter.AnalysisParam;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
@ -18,20 +23,26 @@ import com.alibaba.excel.support.ExcelTypeEnum;
* @author jipengfei * @author jipengfei
*/ */
public class ExcelReader { public class ExcelReader {
private static final Logger LOGGER = LoggerFactory.getLogger(ExcelReader.class);
/** /**
* Analyser * Analyser
*/ */
private ExcelAnalyser analyser; private ExcelAnalyser excelAnalyser;
private boolean finished = false;
/** /**
* Create new reader * Create new reader
* *
* @param in the POI filesystem that contains the Workbook stream * @param in
* @param excelTypeEnum 03 or 07 * the POI filesystem that contains the Workbook stream
* @param excelTypeEnum
* 03 or 07
* @param customContent * @param customContent
* {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext
* @param eventListener Callback method after each row is parsed. * @param eventListener
* Callback method after each row is parsed.
*/ */
@Deprecated @Deprecated
public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent, public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent,
@ -42,10 +53,12 @@ public class ExcelReader {
/** /**
* Create new reader * 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 * @param customContent
* {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext
* @param eventListener Callback method after each row is parsed * @param eventListener
* Callback method after each row is parsed
*/ */
public ExcelReader(InputStream in, Object customContent, AnalysisEventListener eventListener) { public ExcelReader(InputStream in, Object customContent, AnalysisEventListener eventListener) {
this(in, customContent, eventListener, null, true); this(in, customContent, eventListener, null, true);
@ -54,10 +67,12 @@ public class ExcelReader {
/** /**
* Create new reader * 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 * @param customContent
* {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext
* @param eventListener Callback method after each row is parsed * @param eventListener
* Callback method after each row is parsed
*/ */
public ExcelReader(InputStream in, Object customContent, AnalysisEventListener eventListener, public ExcelReader(InputStream in, Object customContent, AnalysisEventListener eventListener,
List<Converter> converters) { List<Converter> converters) {
@ -67,8 +82,10 @@ public class ExcelReader {
/** /**
* Create new reader * Create new reader
* *
* @param param old param Deprecated * @param param
* @param eventListener Callback method after each row is parsed. * old param Deprecated
* @param eventListener
* Callback method after each row is parsed.
*/ */
@Deprecated @Deprecated
public ExcelReader(AnalysisParam param, AnalysisEventListener eventListener) { public ExcelReader(AnalysisParam param, AnalysisEventListener eventListener) {
@ -78,15 +95,18 @@ public class ExcelReader {
/** /**
* Create new reader * Create new reader
* *
* @param in the POI filesystem that contains the Workbook stream * @param in
* @param excelTypeEnum 03 or 07 * the POI filesystem that contains the Workbook stream
* @param excelTypeEnum
* 03 or 07
* @param customContent * @param customContent
* {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext
* @param eventListener Callback method after each row is parsed. * @param eventListener
* @param trim The content of the form is empty and needs to be empty. The purpose is to be * Callback method after each row is parsed.
* fault-tolerant, because there are often table contents with spaces that can not be * @param trim
* converted into custom types. For example: '1234 ' contain a space cannot be converted * The content of the form is empty and needs to be empty. The purpose is to be fault-tolerant, because
* to int. * 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 @Deprecated
public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent, public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent,
@ -101,10 +121,10 @@ public class ExcelReader {
* @param customContent * @param customContent
* {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext * {@link AnalysisEventListener#invoke(Object, AnalysisContext) }AnalysisContext
* @param eventListener * @param eventListener
* @param trim The content of the form is empty and needs to be empty. The purpose is to be * @param trim
* fault-tolerant, because there are often table contents with spaces that can not be * The content of the form is empty and needs to be empty. The purpose is to be fault-tolerant, because
* converted into custom types. For example: '1234 ' contain a space cannot be converted * there are often table contents with spaces that can not be converted into custom types. For example:
* to int. * '1234 ' contain a space cannot be converted to int.
*/ */
public ExcelReader(InputStream in, Object customContent, AnalysisEventListener eventListener, public ExcelReader(InputStream in, Object customContent, AnalysisEventListener eventListener,
List<Converter> converters, boolean trim) { List<Converter> converters, boolean trim) {
@ -123,7 +143,6 @@ public class ExcelReader {
initConverters(analyser, converters); initConverters(analyser, converters);
} }
private void initConverters(ExcelAnalyser analyser, List<Converter> converters) { private void initConverters(ExcelAnalyser analyser, List<Converter> converters) {
if (converters != null && converters.size() > 0) { if (converters != null && converters.size() > 0) {
for (Converter c : converters) { for (Converter c : converters) {
@ -136,58 +155,118 @@ public class ExcelReader {
* Parse all sheet content by default * Parse all sheet content by default
*/ */
public void read() { 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 sheetSheetNo start from 1 * Parse the specified sheetSheetNo start from 1
* *
* @param sheet Read sheet * @param sheet
* Read sheet
*/ */
public void read(Sheet sheet) { public void read(Sheet sheet) {
read(sheet, null); checkFinished();
excelAnalyser.analysis(sheet);
} }
/** /**
* Parse the specified sheet * Parse the specified sheet
* *
* @param sheet Read sheet * @param sheet
* @param clazz object parsed into each row of value * 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) { public void read(Sheet sheet, Class clazz) {
analyser.beforeAnalysis();
if (sheet != null) { if (sheet != null) {
sheet.setClazz(clazz); 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 * Parse the workBook get all sheets
* *
* @return workBook all sheets * @return workBook all sheets
*
* @deprecated please use {@link #excelExecutor()}
*/ */
@Deprecated
public List<Sheet> getSheets() { public List<Sheet> getSheets() {
return analyser.getSheets(); return excelExecutor().sheetList();
} }
/**
*
* @return
* @deprecated please use {@link #analysisContext()}
*/
@Deprecated
public AnalysisContext getAnalysisContext() { public AnalysisContext getAnalysisContext() {
return analyser.getAnalysisContext(); return analysisContext();
}
/**
* Complete the entire read file.Release the cache and close stream.
*/
public void finish() {
if (finished) {
return;
}
finished = true;
excelAnalyser.finish();
} }
/** /**
* validate param * Prevents calls to {@link #finish} from freeing the cache
* *
* @param in * @throws Throwable
* @param eventListener
*/ */
private void validateParam(InputStream in, AnalysisEventListener eventListener) { @Override
// if (eventListener == null) { protected void finalize() {
// throw new IllegalArgumentException("AnalysisEventListener can not null"); if (finished) {
// } else if (in == null) { return;
// throw new IllegalArgumentException("InputStream can not null"); }
// } 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.");
}
} }
} }

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

@ -48,7 +48,7 @@ public class ExcelWriter {
public ExcelWriter(InputStream templateInputStream, OutputStream outputStream, ExcelTypeEnum excelType, public ExcelWriter(InputStream templateInputStream, OutputStream outputStream, ExcelTypeEnum excelType,
boolean needHead, Map<Class, Converter> customConverterMap, List<WriteHandler> customWriteHandlerList) { boolean needHead, Map<Class, Converter> customConverterMap, List<WriteHandler> customWriteHandlerList) {
Workbook workbook = new Workbook(); Workbook workbook = new Workbook();
workbook.setTemplateInputStream(templateInputStream); workbook.setInputStream(templateInputStream);
workbook.setOutputStream(outputStream); workbook.setOutputStream(outputStream);
workbook.setExcelType(excelType); workbook.setExcelType(excelType);
workbook.setNeedHead(needHead); workbook.setNeedHead(needHead);
@ -135,7 +135,7 @@ public class ExcelWriter {
List<WriteHandler> customWriteHandlerList = new ArrayList<WriteHandler>(); List<WriteHandler> customWriteHandlerList = new ArrayList<WriteHandler>();
customWriteHandlerList.add(writeHandler); customWriteHandlerList.add(writeHandler);
Workbook workbook = new Workbook(); Workbook workbook = new Workbook();
workbook.setTemplateInputStream(templateInputStream); workbook.setInputStream(templateInputStream);
workbook.setOutputStream(outputStream); workbook.setOutputStream(outputStream);
workbook.setExcelType(typeEnum); workbook.setExcelType(typeEnum);
workbook.setNeedHead(needHead); workbook.setNeedHead(needHead);

112
src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java

@ -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<String, AnalysisEventListener<Object>> listeners =
new LinkedHashMap<String, AnalysisEventListener<Object>>();
private Map<ConverterKey, Converter> converters = new HashMap<ConverterKey, Converter>();
/**
* execute method
*/
protected abstract void execute();
@Override
public void register(String name, AnalysisEventListener<Object> 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<ConverterKey, Converter> 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<String>)analysisContext.getCurrentRowAnalysisResult());
}
} else {
for (Entry<String, AnalysisEventListener<Object>> entry : listeners.entrySet()) {
entry.getValue().invoke(analysisContext.getCurrentRowAnalysisResult(), analysisContext);
}
}
}
private void buildExcelHeadProperty(Class clazz, List<String> headOneRow) {
ExcelHeadProperty excelHeadProperty =
ExcelHeadProperty.buildExcelHeadProperty(this.analysisContext.getExcelHeadProperty(), clazz, headOneRow);
this.analysisContext.setExcelHeadProperty(excelHeadProperty);
}
}

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

@ -1,7 +1,5 @@
package com.alibaba.excel.analysis; package com.alibaba.excel.analysis;
import java.util.List;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Sheet;
@ -11,9 +9,6 @@ import com.alibaba.excel.metadata.Sheet;
* @author jipengfei * @author jipengfei
*/ */
public interface ExcelAnalyser { public interface ExcelAnalyser {
void beforeAnalysis();
/** /**
* parse one sheet * parse one sheet
* *
@ -22,21 +17,22 @@ public interface ExcelAnalyser {
void analysis(Sheet sheetParam); 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 * Acquisition excel executor
* *
* @return all sheets * @return
*/ */
List<Sheet> getSheets(); ExcelExecutor excelExecutor();
/** /**
* get the analysis context. * get the analysis context.
*
* @return analysis context * @return analysis context
*/ */
AnalysisContext getAnalysisContext(); AnalysisContext analysisContext();
} }

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

@ -1,21 +1,12 @@
package com.alibaba.excel.analysis; 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.v03.XlsSaxAnalyser;
import com.alibaba.excel.analysis.v07.XlsxSaxAnalyser; import com.alibaba.excel.analysis.v07.XlsxSaxAnalyser;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.context.AnalysisContextImpl; 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.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.event.ModelBuildEventListener; import com.alibaba.excel.metadata.Workbook;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
/** /**
@ -25,93 +16,49 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
private AnalysisContext analysisContext; private AnalysisContext analysisContext;
private BaseSaxAnalyser saxAnalyser; private ExcelExecutor excelExecutor;
public ExcelAnalyserImpl(InputStream inputStream, ExcelTypeEnum excelTypeEnum, Object custom,
AnalysisEventListener<Object> eventListener, boolean trim) {
ConverterRegistryCenter center = new ConverterRegistryCenter() {
@Override
public void register(Converter converter) {
saxAnalyser.register(converter);
}
@Override public ExcelAnalyserImpl(Workbook workbook) {
public Map<ConverterKey, Converter> getConverters() { analysisContext = new AnalysisContextImpl(workbook);
return saxAnalyser.getConverters(); choiceExcelExecutor();
}
};
analysisContext = new AnalysisContextImpl(inputStream, excelTypeEnum, custom,
eventListener, center, trim);
this.saxAnalyser = getSaxAnalyser();
} }
private BaseSaxAnalyser getSaxAnalyser() { private void choiceExcelExecutor() {
if (saxAnalyser != null) {
return this.saxAnalyser;
}
try { try {
if (analysisContext.getExcelType() != null) { ExcelTypeEnum excelType = analysisContext.currentWorkbookHolder().getExcelType();
switch (analysisContext.getExcelType()) { if (excelType == null) {
excelExecutor = new XlsxSaxAnalyser(analysisContext);
return;
}
switch (excelType) {
case XLS: case XLS:
this.saxAnalyser = new XlsSaxAnalyser(analysisContext); excelExecutor = new XlsSaxAnalyser(analysisContext);
break; break;
case XLSX: case XLSX:
this.saxAnalyser = new XlsxSaxAnalyser(analysisContext); excelExecutor = new XlsxSaxAnalyser(analysisContext);
break; break;
} default:
} 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 <code> new "
+ "BufferedInputStream(new FileInputStream(\"/xxxx\"))</code> ");
}
this.saxAnalyser = new XlsSaxAnalyser(analysisContext);
}
} }
} catch (Exception e) { } catch (Exception e) {
throw new ExcelAnalysisException("File type error,io must be available markSupported,you can do like " throw new ExcelAnalysisException("File type error,io must be available markSupported,you can do like "
+ "this <code> new BufferedInputStream(new FileInputStream(\\\"/xxxx\\\"))</code> \"", e); + "this <code> new BufferedInputStream(new FileInputStream(\\\"/xxxx\\\"))</code> \"", e);
} }
return this.saxAnalyser;
} }
@Override @Override
public void analysis(Sheet sheetParam) { public void analysis(Sheet sheet) {
analysisContext.setCurrentSheet(sheetParam); analysisContext.currentSheet(sheet);
analysis(); excelExecutor.execute();
}
@Override
public AnalysisContext getAnalysisContext() {
return analysisContext;
}
@Override
public void analysis() {
saxAnalyser.execute();
analysisContext.getEventListener().doAfterAllAnalysed(analysisContext); analysisContext.getEventListener().doAfterAllAnalysed(analysisContext);
} }
@Override @Override
public List<Sheet> getSheets() { public com.alibaba.excel.analysis.ExcelExecutor excelExecutor() {
return this.saxAnalyser.getSheets(); return excelExecutor;
}
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());
}
} }
@Override @Override
public void beforeAnalysis() { public AnalysisContext analysisContext() {
BaseSaxAnalyser saxAnalyser = getSaxAnalyser(); return analysisContext;
registerListeners(saxAnalyser);
} }
} }

18
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<Sheet> sheetList();
void execute();
}

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

@ -1,32 +1,53 @@
package com.alibaba.excel.analysis.v03; package com.alibaba.excel.analysis.v03;
import com.alibaba.excel.analysis.BaseSaxAnalyser; import java.io.IOException;
import com.alibaba.excel.analysis.v03.handlers.*; 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.context.AnalysisContext;
import com.alibaba.excel.event.EachRowAnalysisFinishEvent; import com.alibaba.excel.event.EachRowAnalysisFinishEvent;
import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.util.CollectionUtils; 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. * <p> * Returns the textual content of the file, suitable for * indexing by * /** * A text extractor for Excel files. *
* something like Lucene, but not really * intended for display to the user. * </p> * <p> * To turn an excel file into * <p>
* a CSV or similar, then see * the XLS2CSVmra example * </p> * * @see * * Returns the textual content of the file, suitable for * indexing by something like Lucene, but not really *
* <a href="http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java">XLS2CSVmra</a> * intended for display to the user. *
* </p>
* *
* <p>
* * To turn an excel file into a CSV or similar, then see * the XLS2CSVmra example *
* </p>
* * * @see <a href=
* "http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java">XLS2CSVmra</a>
* *
* @author jipengfei * @author jipengfei
*/ */
public class XlsSaxAnalyser extends BaseSaxAnalyser implements HSSFListener { public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
private boolean outputFormulaValues = true; private boolean outputFormulaValues = true;
private POIFSFileSystem fs; private POIFSFileSystem fs;
private int lastRowNumber; private int lastRowNumber;
@ -41,6 +62,7 @@ public class XlsSaxAnalyser extends BaseSaxAnalyser implements HSSFListener {
private List<Sheet> sheets = new ArrayList<Sheet>(); private List<Sheet> sheets = new ArrayList<Sheet>();
private HSSFWorkbook stubWorkbook; private HSSFWorkbook stubWorkbook;
private List<XlsRecordHandler> recordHandlers = new ArrayList<XlsRecordHandler>(); private List<XlsRecordHandler> recordHandlers = new ArrayList<XlsRecordHandler>();
public XlsSaxAnalyser(AnalysisContext context) throws IOException { public XlsSaxAnalyser(AnalysisContext context) throws IOException {
this.analysisContext = context; this.analysisContext = context;
this.records = new ArrayList<String>(); this.records = new ArrayList<String>();
@ -54,6 +76,11 @@ public class XlsSaxAnalyser extends BaseSaxAnalyser implements HSSFListener {
return sheets; return sheets;
} }
@Override
public List<Sheet> sheetList() {
return null;
}
@Override @Override
public void execute() { public void execute() {
MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this); MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);

10
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.SAXException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import com.alibaba.excel.cache.Cache; import com.alibaba.excel.cache.ReadCache;
/** /**
* Sax read sharedStringsTable.xml * Sax read sharedStringsTable.xml
@ -19,10 +19,10 @@ public class SharedStringsTableHandler extends DefaultHandler {
private String currentData; private String currentData;
private boolean isT; private boolean isT;
private int index = 0; private int index = 0;
private Cache cache; private ReadCache readCache;
public SharedStringsTableHandler(Cache cache) { public SharedStringsTableHandler(ReadCache readCache) {
this.cache = cache; this.readCache = readCache;
} }
@Override @Override
@ -44,7 +44,7 @@ public class SharedStringsTableHandler extends DefaultHandler {
@Override @Override
public void characters(char[] ch, int start, int length) throws SAXException { public void characters(char[] ch, int start, int length) throws SAXException {
if (isT) { if (isT) {
cache.put(index++, new String(ch, start, length)); readCache.put(index++, new String(ch, start, length));
if (index % 100000 == 0) { if (index % 100000 == 0) {
LOGGER.info("row:{} ,mem:{},data:{}", index, Runtime.getRuntime().totalMemory()); LOGGER.info("row:{} ,mem:{},data:{}", index, Runtime.getRuntime().totalMemory());
} }

19
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.CountRowCellHandler;
import com.alibaba.excel.analysis.v07.handlers.DefaultCellHandler; import com.alibaba.excel.analysis.v07.handlers.DefaultCellHandler;
import com.alibaba.excel.analysis.v07.handlers.ProcessResultCellHandler; import com.alibaba.excel.analysis.v07.handlers.ProcessResultCellHandler;
import com.alibaba.excel.cache.Cache;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventRegistryCenter;
/**
* Build handler
*
* @author Dan Zheng
*/
public class XlsxHandlerFactory { public class XlsxHandlerFactory {
public static List<XlsxCellHandler> buildCellHandlers(AnalysisContext analysisContext, public static List<XlsxCellHandler> buildCellHandlers(AnalysisContext analysisContext) {
AnalysisEventRegistryCenter registerCenter, Cache cahe) {
List<XlsxCellHandler> result = new ArrayList<XlsxCellHandler>(); List<XlsxCellHandler> result = new ArrayList<XlsxCellHandler>();
result.add(new CountRowCellHandler(analysisContext)); result.add(new CountRowCellHandler(analysisContext));
DefaultCellHandler defaultCellHandler = buildXlsxRowResultHandler(analysisContext, registerCenter, cahe); DefaultCellHandler defaultCellHandler = new DefaultCellHandler(analysisContext);
result.add(defaultCellHandler); result.add(defaultCellHandler);
result.add(new ProcessResultCellHandler(registerCenter, defaultCellHandler)); result.add(new ProcessResultCellHandler(analysisContext, defaultCellHandler));
return result; return result;
} }
private static DefaultCellHandler buildXlsxRowResultHandler(AnalysisContext analysisContext,
AnalysisEventRegistryCenter registerCenter, Cache cahe) {
return new DefaultCellHandler(analysisContext, registerCenter, cahe);
}
} }

6
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.SAXException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import com.alibaba.excel.cache.Cache;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventRegistryCenter;
/** /**
* *
@ -19,8 +17,8 @@ public class XlsxRowHandler extends DefaultHandler {
private List<XlsxCellHandler> cellHandlers; private List<XlsxCellHandler> cellHandlers;
private XlsxRowResultHolder rowResultHolder; private XlsxRowResultHolder rowResultHolder;
public XlsxRowHandler(AnalysisEventRegistryCenter registerCenter, Cache cache, AnalysisContext analysisContext) { public XlsxRowHandler(AnalysisContext analysisContext) {
this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext, registerCenter, cache); this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext);
for (XlsxCellHandler cellHandler : cellHandlers) { for (XlsxCellHandler cellHandler : cellHandlers) {
if (cellHandler instanceof XlsxRowResultHolder) { if (cellHandler instanceof XlsxRowResultHolder) {
this.rowResultHolder = (XlsxRowResultHolder)cellHandler; this.rowResultHolder = (XlsxRowResultHolder)cellHandler;

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

@ -1,133 +1,120 @@
package com.alibaba.excel.analysis.v07; package com.alibaba.excel.analysis.v07;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; 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.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.usermodel.XSSFRelation; 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.ContentHandler;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import com.alibaba.excel.analysis.BaseSaxAnalyser; import com.alibaba.excel.analysis.ExcelExecutor;
import com.alibaba.excel.cache.Cache; import com.alibaba.excel.cache.Ehcache;
import com.alibaba.excel.cache.EhcacheFile;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.holder.WorkbookHolder;
import com.alibaba.excel.util.FileUtils;
/** /**
* *
* @author jipengfei * @author jipengfei
*/ */
public class XlsxSaxAnalyser extends BaseSaxAnalyser { public class XlsxSaxAnalyser implements ExcelExecutor {
private AnalysisContext analysisContext;
private List<Sheet> sheetList;
private Map<Integer, InputStream> sheetMap;
private XSSFReader xssfReader; public XlsxSaxAnalyser(AnalysisContext analysisContext) throws Exception {
this.analysisContext = analysisContext;
private Cache cache; analysisContext.setCurrentRowNum(0);
WorkbookHolder workbookHolder = analysisContext.currentWorkbookHolder();
if (workbookHolder.getReadCache() == null) {
workbookHolder.setReadCache(new Ehcache());
}
OPCPackage pkg = readOpcPackage(workbookHolder);
private List<SheetSource> sheetSourceList = new ArrayList<SheetSource>(); // Analysis sharedStringsTable.xml
analysisSharedStringsTable(pkg, workbookHolder);
private boolean use1904WindowDate = false; XSSFReader xssfReader = new XSSFReader(pkg);
public XlsxSaxAnalyser(AnalysisContext analysisContext) throws IOException, OpenXML4JException, XmlException { analysisUse1904WindowDate(xssfReader, workbookHolder);
this.analysisContext = analysisContext;
analysisContext.setCurrentRowNum(0); sheetList = new ArrayList<Sheet>();
// OPCPackage pkg = sheetMap = new HashMap<Integer, InputStream>();
// OPCPackage.open(new File("D:\\git\\easyexcel\\src\\test\\resources\\read\\large\\large07.xlsx")); XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData();
// InputStream input = int index = 0;
// 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<PackagePart> 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<SheetSource>();
ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData();
while (ite.hasNext()) { while (ite.hasNext()) {
InputStream inputStream = ite.next(); InputStream inputStream = ite.next();
String sheetName = ite.getSheetName(); Sheet sheet = new Sheet();
SheetSource sheetSource = new SheetSource(sheetName, inputStream); sheet.setSheetNo(index);
sheetSourceList.add(sheetSource); sheet.setSheetName(ite.getSheetName());
sheetList.add(sheet);
sheetMap.put(index, inputStream);
index++;
} }
} }
@Override private void analysisUse1904WindowDate(XSSFReader xssfReader, WorkbookHolder workbookHolder) throws Exception {
protected void execute() { InputStream workbookXml = xssfReader.getWorkbookData();
Sheet sheetParam = analysisContext.getCurrentSheet(); WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml);
if (sheetParam != null && sheetParam.getSheetNo() > 0 && sheetSourceList.size() >= sheetParam.getSheetNo()) { CTWorkbook wb = ctWorkbook.getWorkbook();
InputStream sheetInputStream = sheetSourceList.get(sheetParam.getSheetNo() - 1).getInputStream(); CTWorkbookPr prefix = wb.getWorkbookPr();
parseXmlSource(sheetInputStream); if (prefix != null && prefix.getDate1904()) {
workbookHolder.setUse1904windowing(Boolean.TRUE);
}
}
} else { private void analysisSharedStringsTable(OPCPackage pkg, WorkbookHolder workbookHolder) throws Exception {
int i = 0; ContentHandler handler = new SharedStringsTableHandler(workbookHolder.getReadCache());
for (SheetSource sheetSource : sheetSourceList) { parseXmlSource(pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType()).get(0).getInputStream(),
i++; handler);
analysisContext.setCurrentSheet(new Sheet(i, sheetParam.getReadHeadRowNumber())); workbookHolder.getReadCache().putFinished();
parseXmlSource(sheetSource.getInputStream()); }
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);
} }
@Override
public List<Sheet> sheetList() {
return sheetList;
}
@Override
public void execute() {
parseXmlSource(sheetMap.get(analysisContext.currentSheetHolder().getSheetNo()),
new XlsxRowHandler(analysisContext));
} }
private void parseXmlSource(InputStream inputStream) { private void parseXmlSource(InputStream inputStream, ContentHandler handler) {
InputSource sheetSource = new InputSource(inputStream); InputSource inputSource = new InputSource(inputStream);
try { try {
SAXParserFactory saxFactory = SAXParserFactory.newInstance(); SAXParserFactory saxFactory = SAXParserFactory.newInstance();
saxFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); 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); saxFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
SAXParser saxParser = saxFactory.newSAXParser(); SAXParser saxParser = saxFactory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader(); XMLReader xmlReader = saxParser.getXMLReader();
ContentHandler handler = new XlsxRowHandler(this, cache, analysisContext);
xmlReader.setContentHandler(handler); xmlReader.setContentHandler(handler);
xmlReader.parse(sheetSource); xmlReader.parse(inputSource);
inputStream.close(); inputStream.close();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
throw new ExcelAnalysisException(e); throw new ExcelAnalysisException(e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
throw new ExcelAnalysisException("Can not close 'inputStream'!");
} }
} }
@Override
public List<Sheet> getSheets() {
List<Sheet> sheets = new ArrayList<Sheet>();
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;
}
}
} }

11
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.XlsxCellHandler;
import com.alibaba.excel.analysis.v07.XlsxRowResultHolder; import com.alibaba.excel.analysis.v07.XlsxRowResultHolder;
import com.alibaba.excel.cache.Cache;
import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.event.AnalysisEventRegistryCenter;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.util.PositionUtils; import com.alibaba.excel.util.PositionUtils;
@ -25,8 +23,6 @@ import com.alibaba.excel.util.StringUtils;
public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder { public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder {
private final AnalysisContext analysisContext; private final AnalysisContext analysisContext;
private final AnalysisEventRegistryCenter registerCenter;
private final Cache cahe;
private String currentTag; private String currentTag;
private String currentCellIndex; private String currentCellIndex;
private int curRow; private int curRow;
@ -34,10 +30,8 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
private CellData[] curRowContent = new CellData[20]; private CellData[] curRowContent = new CellData[20];
private CellData currentCellData; private CellData currentCellData;
public DefaultCellHandler(AnalysisContext analysisContext, AnalysisEventRegistryCenter registerCenter, Cache cahe) { public DefaultCellHandler(AnalysisContext analysisContext) {
this.analysisContext = analysisContext; this.analysisContext = analysisContext;
this.registerCenter = registerCenter;
this.cahe = cahe;
} }
@Override @Override
@ -84,7 +78,8 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
ensureSize(); ensureSize();
// Have to go "sharedStrings.xml" and get it // Have to go "sharedStrings.xml" and get it
if (currentCellData.getType() == CellDataTypeEnum.STRING) { 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; curRowContent[curCol] = currentCellData;
} }

22
src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java

@ -1,19 +1,20 @@
package com.alibaba.excel.analysis.v07.handlers; package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import static com.alibaba.excel.constant.ExcelXmlConstants.ROW_TAG; 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.XlsxCellHandler;
import com.alibaba.excel.analysis.v07.XlsxRowResultHolder; 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; import com.alibaba.excel.event.EachRowAnalysisFinishEvent;
public class ProcessResultCellHandler implements XlsxCellHandler { public class ProcessResultCellHandler implements XlsxCellHandler {
private AnalysisEventRegistryCenter registerCenter; private AnalysisContext analysisContext;
private XlsxRowResultHolder rowResultHandler; private XlsxRowResultHolder rowResultHandler;
public ProcessResultCellHandler(AnalysisEventRegistryCenter registerCenter, public ProcessResultCellHandler(AnalysisContext analysisContext, XlsxRowResultHolder rowResultHandler) {
XlsxRowResultHolder rowResultHandler) { this.analysisContext = analysisContext;
this.registerCenter = registerCenter;
this.rowResultHandler = rowResultHandler; this.rowResultHandler = rowResultHandler;
} }
@ -23,14 +24,13 @@ public class ProcessResultCellHandler implements XlsxCellHandler {
} }
@Override @Override
public void startHandle(String name, Attributes attributes) { public void startHandle(String name, Attributes attributes) {}
}
@Override @Override
public void endHandle(String name) { public void endHandle(String name) {
registerCenter.notify(new EachRowAnalysisFinishEvent(rowResultHandler.getCurRowContent(), analysisContext.currentSheetHolder().notifyAll(
rowResultHandler.getColumnSize())); new EachRowAnalysisFinishEvent(rowResultHandler.getCurRowContent(), rowResultHandler.getColumnSize()),
analysisContext);
rowResultHandler.clearResult(); rowResultHandler.clearResult();
} }

27
src/main/java/com/alibaba/excel/cache/Cache.java vendored

@ -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();
}

4
src/main/java/com/alibaba/excel/cache/Ehcache.java vendored

@ -24,10 +24,10 @@ import com.alibaba.excel.util.StringUtils;
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class Ehcache implements Cache { public class Ehcache implements ReadCache {
private static final Logger LOGGER = LoggerFactory.getLogger(Ehcache.class); private static final Logger LOGGER = LoggerFactory.getLogger(Ehcache.class);
private static final int BATCH = 500; private static final int BATCH = 500;
// private org.ehcache.Cache<Integer, String> cache; // private org.ehcache.ReadCache<Integer, String> cache;
int index = 0; int index = 0;
int expirekey = 0; int expirekey = 0;
private Map<Integer, String> cache = new HashMap<Integer, String>(); private Map<Integer, String> cache = new HashMap<Integer, String>();

15
src/main/java/com/alibaba/excel/cache/Ehcache2.java vendored

@ -3,23 +3,16 @@ package com.alibaba.excel.cache;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; 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 * @author zhuangjiaju
*/ */
public class Ehcache2 implements Cache { public class MapCache implements ReadCache {
private static final Logger LOGGER = LoggerFactory.getLogger(Ehcache2.class);
int index = 0;
// private org.ehcache.Cache<Integer, String> cache;
private Map<Integer, String> cache = new HashMap<Integer, String>(); private Map<Integer, String> cache = new HashMap<Integer, String>();
public Ehcache2() {} public MapCache() {}
@Override @Override
public void put(Integer key, String value) { public void put(Integer key, String value) {

2
src/main/java/com/alibaba/excel/cache/EhcacheFile.java vendored

@ -24,7 +24,7 @@ import com.alibaba.excel.util.StringUtils;
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class EhcacheFile implements Cache { public class EhcacheFile implements ReadCache {
private static final Logger LOGGER = LoggerFactory.getLogger(EhcacheFile.class); private static final Logger LOGGER = LoggerFactory.getLogger(EhcacheFile.class);
private static final int BATCH = 500; private static final int BATCH = 500;
int index = 0; int index = 0;

2
src/main/java/com/alibaba/excel/cache/EhcacheMix.java vendored

@ -24,7 +24,7 @@ import com.alibaba.excel.util.StringUtils;
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class EhcacheMix implements Cache { public class EhcacheMix implements ReadCache {
private static final Logger LOGGER = LoggerFactory.getLogger(EhcacheMix.class); private static final Logger LOGGER = LoggerFactory.getLogger(EhcacheMix.class);
private static final int BATCH = 500; private static final int BATCH = 500;
int index = 0; int index = 0;

34
src/main/java/com/alibaba/excel/cache/ReadCache.java vendored

@ -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();
}

4
src/main/java/com/alibaba/excel/cache/SharedStringsTableCache.java → src/main/java/com/alibaba/excel/cache/SharedStringsTableReadCache.java vendored

@ -7,10 +7,10 @@ import org.apache.poi.xssf.model.SharedStringsTable;
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class SharedStringsTableCache implements Cache { public class SharedStringsTableReadCache implements ReadCache {
private SharedStringsTable sharedStringsTable; private SharedStringsTable sharedStringsTable;
public SharedStringsTableCache(SharedStringsTable sharedStringsTable) { public SharedStringsTableReadCache(SharedStringsTable sharedStringsTable) {
this.sharedStringsTable = sharedStringsTable; this.sharedStringsTable = sharedStringsTable;
} }

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

@ -1,77 +1,76 @@
package com.alibaba.excel.context; package com.alibaba.excel.context;
import java.io.InputStream; import com.alibaba.excel.event.EachRowAnalysisFinishEvent;
import com.alibaba.excel.metadata.holder.ReadConfiguration;
import com.alibaba.excel.converters.ConverterRegistryCenter; import com.alibaba.excel.metadata.holder.SheetHolder;
import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.holder.WorkbookHolder;
import com.alibaba.excel.metadata.property.ExcelHeadProperty;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
/** /**
* *
* A context is the main anchorage point of a excel reader. * A context is the main anchorage point of a excel reader.
*
* @author jipengfei * @author jipengfei
*/ */
public interface AnalysisContext { 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 * All information about the sheet you are currently working on
* @param sheet *
* @return
*/ */
void setCurrentSheet(Sheet sheet); SheetHolder currentSheetHolder();
/** /**
* Configuration of currently operated cell
* *
* get excel type * @return
* @return excel type
*/ */
ExcelTypeEnum getExcelType(); ReadConfiguration currentConfiguration();
/** /**
* get in io * set current result
* @return file io *
* @param result
*/ */
InputStream getInputStream(); void setCurrentRowAnalysisResult(Object result);
/** /**
* get current result
* *
* custom listener * @return get current result
* @return listener
*/ */
AnalysisEventListener<Object> getEventListener(); Object currentRowAnalysisResult();
/**
* get the converter registry center.
* @return converter registry center.
*/
ConverterRegistryCenter getConverterRegistryCenter();
/** /**
* get current row * get current row
*
* @return * @return
*/ */
Integer getCurrentRowNum(); Integer currentRowNum();
/** /**
* set current row num * set current row num
*
* @param row * @param row
*/ */
void setCurrentRowNum(Integer row); void setCurrentRowNum(Integer row);
/** /**
* get total row , Data may be inaccurate * get total row , Data may be inaccurate
*
* @return * @return
*/ */
@Deprecated @Deprecated
@ -83,53 +82,4 @@ public interface AnalysisContext {
* @param totalCount * @param totalCount
*/ */
void setTotalCount(Integer 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);
} }

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

@ -1,176 +1,47 @@
package com.alibaba.excel.context; 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.metadata.holder.SheetHolder;
import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.holder.WorkbookHolder;
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;
/** /**
* *
* @author jipengfei * @author jipengfei
*/ */
public class AnalysisContextImpl implements AnalysisContext { public class AnalysisContextImpl implements AnalysisContext {
private static final Logger LOGGER = LoggerFactory.getLogger(AnalysisContextImpl.class);
/**
* The Workbook currently written
*/
private WorkbookHolder currentWorkbookHolder;
/**
* Current sheet holder
*/
private SheetHolder currentSheetHolder;
private Object custom; public AnalysisContextImpl(com.alibaba.excel.metadata.Workbook workbook) {
if (workbook == null) {
private Sheet currentSheet; throw new IllegalArgumentException("Workbook argument cannot be null");
private ExcelTypeEnum excelType;
private InputStream inputStream;
private AnalysisEventListener<Object> 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<Object> 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 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<Object> getEventListener() {
return eventListener;
}
public void setEventListener(AnalysisEventListener<Object> eventListener) {
this.eventListener = eventListener;
}
@Override
public Integer getCurrentRowNum() {
return this.currentRowNum;
} }
currentWorkbookHolder = WorkbookHolder.buildReadWorkbookHolder(workbook);
@Override if (LOGGER.isDebugEnabled()) {
public void setCurrentRowNum(Integer row) { LOGGER.debug("Initialization 'AnalysisContextImpl' complete");
this.currentRowNum = row;
} }
@Override
public Integer getTotalCount() {
return totalCount;
} }
@Override @Override
public void setTotalCount(Integer totalCount) { public void currentSheet(com.alibaba.excel.metadata.Sheet sheet) {
this.totalCount = totalCount; if (sheet == null) {
throw new IllegalArgumentException("Sheet argument cannot be null");
} }
if (sheet.getSheetNo() == null || sheet.getSheetNo() <= 0) {
@Override sheet.setSheetNo(0);
public ExcelHeadProperty getExcelHeadProperty() {
return this.excelHeadProperty;
} }
currentSheetHolder = SheetHolder.buildReadWorkSheetHolder(sheet, currentWorkbookHolder);
if (LOGGER.isDebugEnabled()) {
@Override LOGGER.debug("Began to read:{}", sheet);
public void setExcelHeadProperty(ExcelHeadProperty excelHeadProperty) {
this.excelHeadProperty = excelHeadProperty;
} }
@Override
public boolean trim() {
return this.trim;
}
@Override
public ConverterRegistryCenter getConverterRegistryCenter() {
return converterRegistryCenter;
} }
} }

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

@ -1,7 +1,7 @@
package com.alibaba.excel.context; package com.alibaba.excel.context;
import com.alibaba.excel.metadata.Table; 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.SheetHolder;
import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.metadata.holder.TableHolder;
import com.alibaba.excel.metadata.holder.WorkbookHolder; import com.alibaba.excel.metadata.holder.WorkbookHolder;
@ -31,7 +31,7 @@ public interface WriteContext {
* *
* @return * @return
*/ */
ConfigurationSelector currentConfigurationSelector(); WriteConfiguration currentConfiguration();
/** /**
* All information about the workbook you are currently working on * All information about the workbook you are currently working on

54
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.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.Table; 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.SheetHolder;
import com.alibaba.excel.metadata.holder.TableHolder; import com.alibaba.excel.metadata.holder.TableHolder;
import com.alibaba.excel.metadata.holder.WorkbookHolder; 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.metadata.property.ExcelHeadProperty;
import com.alibaba.excel.util.WorkBookUtil; import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.write.handler.CellWriteHandler; import com.alibaba.excel.write.handler.CellWriteHandler;
@ -50,7 +50,7 @@ public class WriteContextImpl implements WriteContext {
/** /**
* Configuration of currently operated cell * Configuration of currently operated cell
*/ */
private ConfigurationSelector currentConfigurationSelector; private WriteConfiguration currentWriteConfiguration;
public WriteContextImpl(com.alibaba.excel.metadata.Workbook workbook) { public WriteContextImpl(com.alibaba.excel.metadata.Workbook workbook) {
if (workbook == null) { if (workbook == null) {
@ -62,8 +62,8 @@ public class WriteContextImpl implements WriteContext {
initCurrentWorkbookHolder(workbook); initCurrentWorkbookHolder(workbook);
beforeWorkbookCreate(); beforeWorkbookCreate();
try { try {
currentWorkbookHolder.setWorkbook(WorkBookUtil.createWorkBook(workbook)); currentWorkbookHolder.setWorkbook(WorkBookUtil.createWorkBook(currentWorkbookHolder));
} catch (IOException e) { } catch (Exception e) {
throw new ExcelGenerateException("Create workbook failure", e); throw new ExcelGenerateException("Create workbook failure", e);
} }
afterWorkbookCreate(); afterWorkbookCreate();
@ -73,7 +73,7 @@ public class WriteContextImpl implements WriteContext {
} }
private void beforeWorkbookCreate() { private void beforeWorkbookCreate() {
List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(WorkbookWriteHandler.class); List<WriteHandler> handlerList = currentWriteConfiguration.writeHandlerMap().get(WorkbookWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -85,7 +85,7 @@ public class WriteContextImpl implements WriteContext {
} }
private void afterWorkbookCreate() { private void afterWorkbookCreate() {
List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(WorkbookWriteHandler.class); List<WriteHandler> handlerList = currentWriteConfiguration.writeHandlerMap().get(WorkbookWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -98,9 +98,9 @@ public class WriteContextImpl implements WriteContext {
private void initCurrentWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) { private void initCurrentWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) {
currentWorkbookHolder = new WorkbookHolder(workbook); currentWorkbookHolder = new WorkbookHolder(workbook);
currentConfigurationSelector = currentWorkbookHolder; currentWriteConfiguration = currentWorkbookHolder;
if (LOGGER.isDebugEnabled()) { 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 = currentWorkbookHolder.getHasBeenInitializedSheet().get(sheet.getSheetNo());
currentSheetHolder.setNewInitialization(Boolean.FALSE); currentSheetHolder.setNewInitialization(Boolean.FALSE);
currentTableHolder = null; currentTableHolder = null;
currentConfigurationSelector = currentSheetHolder; currentWriteConfiguration = currentSheetHolder;
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfigurationSelector is currentSheetHolder"); LOGGER.debug("CurrentConfiguration is currentSheetHolder");
} }
return; return;
} }
@ -136,7 +136,7 @@ public class WriteContextImpl implements WriteContext {
} }
private void beforeSheetCreate() { private void beforeSheetCreate() {
List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(SheetWriteHandler.class); List<WriteHandler> handlerList = currentWriteConfiguration.writeHandlerMap().get(SheetWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -148,7 +148,7 @@ public class WriteContextImpl implements WriteContext {
} }
private void afterSheetCreate() { private void afterSheetCreate() {
List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(SheetWriteHandler.class); List<WriteHandler> handlerList = currentWriteConfiguration.writeHandlerMap().get(SheetWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -167,9 +167,9 @@ public class WriteContextImpl implements WriteContext {
currentSheetHolder = new SheetHolder(sheet, currentWorkbookHolder); currentSheetHolder = new SheetHolder(sheet, currentWorkbookHolder);
currentWorkbookHolder.getHasBeenInitializedSheet().put(sheet.getSheetNo(), currentSheetHolder); currentWorkbookHolder.getHasBeenInitializedSheet().put(sheet.getSheetNo(), currentSheetHolder);
currentTableHolder = null; currentTableHolder = null;
currentConfigurationSelector = currentSheetHolder; currentWriteConfiguration = currentSheetHolder;
if (LOGGER.isDebugEnabled()) { 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()); currentSheet = currentWorkbookHolder.getWorkbook().getSheetAt(sheet.getSheetNo());
} catch (Exception e) { } catch (Exception e) {
if (LOGGER.isDebugEnabled()) { 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); currentSheet = WorkBookUtil.createSheet(currentWorkbookHolder.getWorkbook(), sheet);
} }
@ -189,11 +189,11 @@ public class WriteContextImpl implements WriteContext {
} }
public void initHead(ExcelHeadProperty excelHeadProperty) { public void initHead(ExcelHeadProperty excelHeadProperty) {
if (!currentConfigurationSelector.needHead() || !currentSheetHolder.getExcelHeadProperty().hasHead()) { if (!currentWriteConfiguration.needHead() || !currentSheetHolder.getExcelHeadProperty().hasHead()) {
return; return;
} }
int lastRowNum = currentSheetHolder.getSheet().getLastRowNum(); int lastRowNum = currentSheetHolder.getSheet().getLastRowNum();
int rowIndex = lastRowNum + currentConfigurationSelector.writeRelativeHeadRowIndex(); int rowIndex = lastRowNum + currentWriteConfiguration.writeRelativeHeadRowIndex();
// Combined head // Combined head
addMergedRegionToCurrentSheet(excelHeadProperty, rowIndex); addMergedRegionToCurrentSheet(excelHeadProperty, rowIndex);
for (int relativeRowIndex = 0, i = rowIndex; i < excelHeadProperty.getHeadRowNumber() + 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) { private void beforeRowCreate(int rowIndex, int relativeRowIndex) {
List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(RowWriteHandler.class); List<WriteHandler> handlerList = currentWriteConfiguration.writeHandlerMap().get(RowWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -219,7 +219,7 @@ public class WriteContextImpl implements WriteContext {
} }
private void afterRowCreate(Row row, int relativeRowIndex) { private void afterRowCreate(Row row, int relativeRowIndex) {
List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(RowWriteHandler.class); List<WriteHandler> handlerList = currentWriteConfiguration.writeHandlerMap().get(RowWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -251,7 +251,7 @@ public class WriteContextImpl implements WriteContext {
} }
private void beforeCellCreate(Row row, Head head, int relativeRowIndex) { private void beforeCellCreate(Row row, Head head, int relativeRowIndex) {
List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(CellWriteHandler.class); List<WriteHandler> handlerList = currentWriteConfiguration.writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -264,7 +264,7 @@ public class WriteContextImpl implements WriteContext {
} }
private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) { private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) {
List<WriteHandler> handlerList = currentConfigurationSelector.writeHandlerMap().get(CellWriteHandler.class); List<WriteHandler> handlerList = currentWriteConfiguration.writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -293,9 +293,9 @@ public class WriteContextImpl implements WriteContext {
} }
currentTableHolder = currentSheetHolder.getHasBeenInitializedTable().get(table.getTableNo()); currentTableHolder = currentSheetHolder.getHasBeenInitializedTable().get(table.getTableNo());
currentTableHolder.setNewInitialization(Boolean.FALSE); currentTableHolder.setNewInitialization(Boolean.FALSE);
currentConfigurationSelector = currentTableHolder; currentWriteConfiguration = currentTableHolder;
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfigurationSelector is currentTableHolder"); LOGGER.debug("CurrentConfiguration is currentTableHolder");
} }
return; return;
} }
@ -306,15 +306,15 @@ public class WriteContextImpl implements WriteContext {
private void initCurrentTableHolder(com.alibaba.excel.metadata.Table table) { private void initCurrentTableHolder(com.alibaba.excel.metadata.Table table) {
currentTableHolder = new TableHolder(table, currentSheetHolder, currentWorkbookHolder); currentTableHolder = new TableHolder(table, currentSheetHolder, currentWorkbookHolder);
currentSheetHolder.getHasBeenInitializedTable().put(table.getTableNo(), currentTableHolder); currentSheetHolder.getHasBeenInitializedTable().put(table.getTableNo(), currentTableHolder);
currentConfigurationSelector = currentTableHolder; currentWriteConfiguration = currentTableHolder;
if (LOGGER.isDebugEnabled()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfigurationSelector is currentTableHolder"); LOGGER.debug("CurrentConfiguration is currentTableHolder");
} }
} }
@Override @Override
public ConfigurationSelector currentConfigurationSelector() { public WriteConfiguration currentConfiguration() {
return currentConfigurationSelector; return currentWriteConfiguration;
} }
@Override @Override

9
src/main/java/com/alibaba/excel/converters/ConverterRegistryCenter.java

@ -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<ConverterKey, Converter> getConverters();
}

8
src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java

@ -28,8 +28,12 @@ public class DateNumberConverter implements Converter<Date> {
@Override @Override
public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
if (contentProperty.getDateTimeFormatProperty() == null) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), false, null); Boolean use1904windowing = Boolean.FALSE;
if (contentProperty != null && contentProperty.getUse1904windowing() != null) {
use1904windowing = contentProperty.getUse1904windowing();
}
return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), use1904windowing, null);
} else { } else {
return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(),
contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null); contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null);

4
src/main/java/com/alibaba/excel/converters/date/DateStringConverter.java

@ -27,7 +27,7 @@ public class DateStringConverter implements Converter<Date> {
@Override @Override
public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) throws ParseException { 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); return DateUtils.parseDate(cellData.getStringValue(), null);
} else { } else {
return DateUtils.parseDate(cellData.getStringValue(), return DateUtils.parseDate(cellData.getStringValue(),
@ -37,7 +37,7 @@ public class DateStringConverter implements Converter<Date> {
@Override @Override
public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty) { public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty) {
if (contentProperty.getDateTimeFormatProperty() == null) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
return new CellData(DateUtils.format(value, null)); return new CellData(DateUtils.format(value, null));
} else { } else {
return new CellData(DateUtils.format(value, contentProperty.getDateTimeFormatProperty().getFormat())); return new CellData(DateUtils.format(value, contentProperty.getDateTimeFormatProperty().getFormat()));

2
src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java

@ -29,7 +29,7 @@ public class StringNumberConverter implements Converter<String> {
@Override @Override
public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) { public String convertToJavaData(CellData cellData, ExcelContentProperty contentProperty) {
// If there are "DateTimeFormat", read as date // If there are "DateTimeFormat", read as date
if (contentProperty.getDateTimeFormatProperty() != null) { if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) {
return DateUtils.format( return DateUtils.format(
HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), HSSFDateUtil.getJavaDate(cellData.getDoubleValue(),
contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null), contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null),

8
src/main/java/com/alibaba/excel/event/AnalysisEventListener.java

@ -1,6 +1,7 @@
package com.alibaba.excel.event; package com.alibaba.excel.event;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
/** /**
* Receives the return of each piece of data parsed * Receives the return of each piece of data parsed
@ -21,12 +22,7 @@ public abstract class AnalysisEventListener<T> implements ReadListener<T> {
throw exception; throw exception;
} }
/** @Override
* Verify that there is another piece of data.You can stop the read by returning false
*
* @param context
* @return
*/
public boolean hasNext(AnalysisContext context) { public boolean hasNext(AnalysisContext context) {
return true; return true;
} }

35
src/main/java/com/alibaba/excel/event/AnalysisEventRegistryCenter.java

@ -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<Object> 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);
}

1
src/main/java/com/alibaba/excel/event/EachRowAnalysisFinishEvent.java

@ -10,6 +10,7 @@ import com.alibaba.excel.metadata.CellData;
*/ */
public class EachRowAnalysisFinishEvent implements AnalysisFinishEvent { public class EachRowAnalysisFinishEvent implements AnalysisFinishEvent {
private Object result; private Object result;
public EachRowAnalysisFinishEvent(Object content) { public EachRowAnalysisFinishEvent(Object content) {
this.result = content; this.result = content;
} }

81
src/main/java/com/alibaba/excel/event/ModelBuildEventListener.java

@ -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<Object> {
private final Map<ConverterKey, Converter> converters;
public ModelBuildEventListener(Map<ConverterKey, Converter> 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<CellData>)object);
context.setCurrentRowAnalysisResult(resultModel);
} catch (Exception e) {
throw new ExcelGenerateException(e);
}
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
private Object buildUserModel(AnalysisContext context, List<CellData> cellDataList) throws Exception {
ExcelHeadProperty excelHeadProperty = context.getExcelHeadProperty();
Object resultModel = excelHeadProperty.getHeadClazz().newInstance();
Map<String,Object> map = new HashMap<String,Object>();
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) {
}
}

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

@ -1,12 +1,10 @@
package com.alibaba.excel.metadata; package com.alibaba.excel.metadata;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import com.alibaba.excel.converters.Converter; 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; import com.alibaba.excel.write.handler.WriteHandler;
/** /**
@ -42,7 +40,7 @@ public class BasicParameter {
/** /**
* Custom type conversions override the default * Custom type conversions override the default
*/ */
private Map<Class, Converter> customConverterMap = new HashMap<Class, Converter>(); private List<Converter> customConverterList = new ArrayList<Converter>();
/** /**
* Custom type handler override the default * Custom type handler override the default
*/ */
@ -51,6 +49,10 @@ public class BasicParameter {
* Custom type listener run after default * Custom type listener run after default
*/ */
private List<ReadListener> customReadListenerList = new ArrayList<ReadListener>(); private List<ReadListener> customReadListenerList = new ArrayList<ReadListener>();
/**
* Automatic trim includes sheet name and content
*/
private Boolean autoTrim;
public Integer getReadHeadRowNumber() { public Integer getReadHeadRowNumber() {
return readHeadRowNumber; return readHeadRowNumber;
@ -92,12 +94,12 @@ public class BasicParameter {
this.needHead = needHead; this.needHead = needHead;
} }
public Map<Class, Converter> getCustomConverterMap() { public List<Converter> getCustomConverterList() {
return customConverterMap; return customConverterList;
} }
public void setCustomConverterMap(Map<Class, Converter> customConverterMap) { public void setCustomConverterList(List<Converter> customConverterList) {
this.customConverterMap = customConverterMap; this.customConverterList = customConverterList;
} }
public List<WriteHandler> getCustomWriteHandlerList() { public List<WriteHandler> getCustomWriteHandlerList() {
@ -115,4 +117,12 @@ public class BasicParameter {
public void setCustomReadListenerList(List<ReadListener> customReadListenerList) { public void setCustomReadListenerList(List<ReadListener> customReadListenerList) {
this.customReadListenerList = customReadListenerList; this.customReadListenerList = customReadListenerList;
} }
public Boolean getAutoTrim() {
return autoTrim;
}
public void setAutoTrim(Boolean autoTrim) {
this.autoTrim = autoTrim;
}
} }

13
src/main/java/com/alibaba/excel/metadata/Head.java

@ -24,7 +24,10 @@ public class Head {
* Head name * Head name
*/ */
private List<String> headNameList; private List<String> headNameList;
/**
* Whether index is specified
*/
private Boolean forceIndex;
/** /**
* Cell style property * Cell style property
*/ */
@ -89,4 +92,12 @@ public class Head {
public void setColumnWidthProperty(ColumnWidthProperty columnWidthProperty) { public void setColumnWidthProperty(ColumnWidthProperty columnWidthProperty) {
this.columnWidthProperty = columnWidthProperty; this.columnWidthProperty = columnWidthProperty;
} }
public Boolean getForceIndex() {
return forceIndex;
}
public void setForceIndex(Boolean forceIndex) {
this.forceIndex = forceIndex;
}
} }

43
src/main/java/com/alibaba/excel/metadata/Workbook.java

@ -4,6 +4,9 @@ import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; 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.support.ExcelTypeEnum;
import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.handler.WriteHandler;
@ -41,6 +44,22 @@ public class Workbook extends BasicParameter {
* Default true * Default true
*/ */
private Boolean autoCloseStream; 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 * 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. * 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) { public void setConvertAllFiled(Boolean convertAllFiled) {
this.convertAllFiled = 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;
}
} }

204
src/main/java/com/alibaba/excel/metadata/holder/AbstractConfigurationSelector.java → 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.Cell;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKey;
import com.alibaba.excel.enums.HeadKindEnum; 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.NotRepeatExecutor;
import com.alibaba.excel.event.Order; 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.CellStyle;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.property.CellStyleProperty; import com.alibaba.excel.metadata.property.CellStyleProperty;
import com.alibaba.excel.metadata.property.ExcelContentProperty; import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.metadata.property.ExcelHeadProperty; import com.alibaba.excel.metadata.property.ExcelHeadProperty;
import com.alibaba.excel.metadata.property.RowHeightProperty; 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.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler; import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.handler.SheetWriteHandler;
@ -35,7 +45,8 @@ import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public abstract class AbstractConfigurationSelector implements ConfigurationSelector { public abstract class AbstractWriteConfiguration
implements WriteConfiguration, ReadConfiguration, ReadListenerRegistryCenter {
/** /**
* Need Head * Need Head
*/ */
@ -44,10 +55,18 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele
* Write handler for workbook * Write handler for workbook
*/ */
private Map<Class<? extends WriteHandler>, List<WriteHandler>> writeHandlerMap; private Map<Class<? extends WriteHandler>, List<WriteHandler>> writeHandlerMap;
/**
* Read listener
*/
private List<ReadListener> readListenerList;
/**
* Converter for workbook
*/
private Map<ConverterKey, Converter> readConverterMap;
/** /**
* Converter for workbook * Converter for workbook
*/ */
private Map<Class, Converter> converterMap; private Map<Class, Converter> writeConverterMap;
/** /**
* Excel head property * Excel head property
*/ */
@ -60,17 +79,28 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele
* Record whether it's new or from cache * Record whether it's new or from cache
*/ */
private Boolean newInitialization; private Boolean newInitialization;
/** /**
* You can only choose one of the {@link AbstractConfigurationSelector#head} and * Count the number of added heads when read sheet.
* {@link AbstractConfigurationSelector#clazz} *
* <li>0 - This Sheet has no head ,since the first row are the data
* <li>1 - This Sheet has one row head , this is the default
* <li>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<List<String>> head; private List<List<String>> head;
/** /**
* You can only choose one of the {@link AbstractConfigurationSelector#head} and * You can only choose one of the {@link AbstractWriteConfiguration#head} and
* {@link AbstractConfigurationSelector#clazz} * {@link AbstractWriteConfiguration#clazz}
*/ */
private Class clazz; private Class clazz;
/**
* Automatic trim includes sheet name and content
*/
private Boolean autoTrim;
public Boolean getNeedHead() { public Boolean getNeedHead() {
return needHead; return needHead;
@ -88,14 +118,6 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele
this.writeHandlerMap = writeHandlerMap; this.writeHandlerMap = writeHandlerMap;
} }
public Map<Class, Converter> getConverterMap() {
return converterMap;
}
public void setConverterMap(Map<Class, Converter> converterMap) {
this.converterMap = converterMap;
}
public ExcelHeadProperty getExcelHeadProperty() { public ExcelHeadProperty getExcelHeadProperty() {
return excelHeadProperty; return excelHeadProperty;
} }
@ -136,6 +158,139 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele
this.clazz = clazz; this.clazz = clazz;
} }
public Boolean getAutoTrim() {
return autoTrim;
}
public void setAutoTrim(Boolean autoTrim) {
this.autoTrim = autoTrim;
}
public List<ReadListener> getReadListenerList() {
return readListenerList;
}
public void setReadListenerList(List<ReadListener> readListenerList) {
this.readListenerList = readListenerList;
}
public Map<ConverterKey, Converter> getReadConverterMap() {
return readConverterMap;
}
public void setReadConverterMap(Map<ConverterKey, Converter> readConverterMap) {
this.readConverterMap = readConverterMap;
}
public Map<Class, Converter> getWriteConverterMap() {
return writeConverterMap;
}
public void setWriteConverterMap(Map<Class, Converter> 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<CellData> cellDataList = (List<CellData>)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<CellData> cellDataList) {
if (!HeadKindEnum.CLASS.equals(analysisContext.currentConfiguration().excelHeadProperty().getHeadKind())) {
return;
}
List<String> dataList = (List<String>)buildStringList(cellDataList, analysisContext.currentConfiguration());
ExcelHeadProperty excelHeadPropertyData = analysisContext.currentConfiguration().excelHeadProperty();
Map<Integer, Head> headMapData = excelHeadPropertyData.getHeadMap();
Map<Integer, ExcelContentProperty> contentPropertyMapData = excelHeadPropertyData.getContentPropertyMap();
Map<Integer, Head> tmpHeadMap = new HashMap<Integer, Head>(headMapData.size() * 4 / 3 + 1);
Map<Integer, ExcelContentProperty> tmpContentPropertyMap =
new HashMap<Integer, ExcelContentProperty>(contentPropertyMapData.size() * 4 / 3 + 1);
for (Map.Entry<Integer, Head> 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<CellData> data, ReadConfiguration readConfiguration) {
List<String> list = new ArrayList<String>();
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<Class<? extends WriteHandler>, List<WriteHandler>> sortAndClearUpHandler( protected Map<Class<? extends WriteHandler>, List<WriteHandler>> sortAndClearUpHandler(
List<WriteHandler> handlerList, Map<Class<? extends WriteHandler>, List<WriteHandler>> parentHandlerMap) { List<WriteHandler> handlerList, Map<Class<? extends WriteHandler>, List<WriteHandler>> parentHandlerMap) {
// add // add
@ -301,11 +456,6 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele
return getWriteHandlerMap(); return getWriteHandlerMap();
} }
@Override
public Map<Class, Converter> converterMap() {
return getConverterMap();
}
@Override @Override
public boolean needHead() { public boolean needHead() {
return getNeedHead(); return getNeedHead();
@ -326,4 +476,18 @@ public abstract class AbstractConfigurationSelector implements ConfigurationSele
return getNewInitialization(); return getNewInitialization();
} }
@Override
public List<ReadListener> readListenerList() {
return getReadListenerList();
}
@Override
public Map<ConverterKey, Converter> readConverterMap() {
return getReadConverterMap();
}
@Override
public Map<Class, Converter> writeConverterMap() {
return getWriteConverterMap();
}
} }

39
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<ReadListener> readListenerList();
/**
* What converter does the currently operated cell need to execute
*
* @return
*/
Map<ConverterKey, Converter> readConverterMap();
/**
* What 'ExcelHeadProperty' does the currently operated cell need to execute
*
* @return
*/
ExcelHeadProperty excelHeadProperty();
}

112
src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java

@ -10,10 +10,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ConverterKey;
import com.alibaba.excel.metadata.CellStyle; import com.alibaba.excel.metadata.CellStyle;
import com.alibaba.excel.metadata.Head; import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.TableStyle; import com.alibaba.excel.metadata.TableStyle;
import com.alibaba.excel.metadata.property.ExcelHeadProperty; 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.handler.WriteHandler;
import com.alibaba.excel.write.style.RowCellStyleStrategy; import com.alibaba.excel.write.style.RowCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy; import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy;
@ -23,9 +25,8 @@ import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class SheetHolder extends AbstractConfigurationSelector { public class SheetHolder extends AbstractWriteConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(SheetHolder.class); private static final Logger LOGGER = LoggerFactory.getLogger(SheetHolder.class);
/*** /***
* poi sheet * poi sheet
*/ */
@ -51,32 +52,20 @@ public class SheetHolder extends AbstractConfigurationSelector {
*/ */
private com.alibaba.excel.metadata.Sheet sheetParam; private com.alibaba.excel.metadata.Sheet sheetParam;
public SheetHolder(com.alibaba.excel.metadata.Sheet sheet, WorkbookHolder workbookHolder) { public static SheetHolder buildWriteWorkSheetHolder(com.alibaba.excel.metadata.Sheet sheet,
super(); WorkbookHolder workbookHolder) {
this.sheetParam = sheet; SheetHolder sheetHolder = buildBaseSheetHolder(sheet, workbookHolder);
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()));
setNewInitialization(Boolean.TRUE); sheetHolder.setNewInitialization(Boolean.TRUE);
if (sheet.getNeedHead() == null) { if (sheet.getNeedHead() == null) {
setNeedHead(workbookHolder.needHead()); sheetHolder.setNeedHead(workbookHolder.needHead());
} else { } else {
setNeedHead(sheet.getNeedHead()); sheetHolder.setNeedHead(sheet.getNeedHead());
} }
if (sheet.getWriteRelativeHeadRowIndex() == null) { if (sheet.getWriteRelativeHeadRowIndex() == null) {
setWriteRelativeHeadRowIndex(workbookHolder.writeRelativeHeadRowIndex()); sheetHolder.setWriteRelativeHeadRowIndex(workbookHolder.writeRelativeHeadRowIndex());
} else { } else {
setWriteRelativeHeadRowIndex(sheet.getWriteRelativeHeadRowIndex()); sheetHolder.setWriteRelativeHeadRowIndex(sheet.getWriteRelativeHeadRowIndex());
} }
// Compatible with old code // Compatible with old code
compatibleOldCode(sheet); compatibleOldCode(sheet);
@ -85,25 +74,86 @@ public class SheetHolder extends AbstractConfigurationSelector {
handlerList.addAll(sheet.getCustomWriteHandlerList()); handlerList.addAll(sheet.getCustomWriteHandlerList());
} }
// Initialization Annotation // Initialization Annotation
initAnnotationConfig(handlerList); sheetHolder.initAnnotationConfig(handlerList);
setWriteHandlerMap(sortAndClearUpHandler(handlerList, workbookHolder.getWriteHandlerMap())); sheetHolder
Map<Class, Converter> converterMap = new HashMap<Class, Converter>(workbookHolder.converterMap()); .setWriteHandlerMap(sheetHolder.sortAndClearUpHandler(handlerList, workbookHolder.getWriteHandlerMap()));
if (sheet.getCustomConverterMap() != null && !sheet.getCustomConverterMap().isEmpty()) { Map<Class, Converter> converterMap = new HashMap<Class, Converter>(workbookHolder.getWriteConverterMap());
converterMap.putAll(sheet.getCustomConverterMap()); if (sheet.getCustomConverterList() != null && !sheet.getCustomConverterList().isEmpty()) {
for (Converter converter : sheet.getCustomConverterList()) {
converterMap.put(converter.getClass(), converter);
}
} }
setConverterMap(converterMap); sheetHolder.setWriteConverterMap(converterMap);
setHasBeenInitializedTable(new HashMap<Integer, TableHolder>()); sheetHolder.setHasBeenInitializedTable(new HashMap<Integer, TableHolder>());
if (LOGGER.isDebugEnabled()) { 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<ConverterKey, Converter> converterMap =
new HashMap<ConverterKey, Converter>(workbookHolder.getReadConverterMap());
if (sheet.getCustomConverterList() != null && !sheet.getCustomConverterList().isEmpty()) {
for (Converter converter : sheet.getCustomConverterList()) {
converterMap.put(ConverterKey.buildConverterKey(converter), converter);
} }
} }
sheetHolder.setReadConverterMap(converterMap);
List<ReadListener> readListenerList = new ArrayList<ReadListener>();
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 * Compatible with old code
*/ */
@Deprecated @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()) { if (sheet.getColumnWidthMap() != null && !sheet.getColumnWidthMap().isEmpty()) {
final Map<Integer, Integer> columnWidthMap = sheet.getColumnWidthMap(); final Map<Integer, Integer> columnWidthMap = sheet.getColumnWidthMap();
if (sheet.getCustomWriteHandlerList() == null) { if (sheet.getCustomWriteHandlerList() == null) {

54
src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java

@ -21,7 +21,7 @@ import com.alibaba.excel.write.style.RowCellStyleStrategy;
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class TableHolder extends AbstractConfigurationSelector { public class TableHolder extends AbstractWriteConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(TableHolder.class); 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; private com.alibaba.excel.metadata.Table tableParam;
public TableHolder(com.alibaba.excel.metadata.Table table, SheetHolder sheetHolder, WorkbookHolder workbookHolder) { public static TableHolder buildWriteWorkTableHolder(com.alibaba.excel.metadata.Table table, SheetHolder sheetHolder,
super(); WorkbookHolder workbookHolder) {
this.tableParam = table; TableHolder tableHolder = new TableHolder();
this.parentSheet = sheetHolder; tableHolder.setTableParam(table);
this.tableNo = table.getTableNo(); tableHolder.setParentSheet(sheetHolder);
tableHolder.setTableNo(table.getTableNo());
boolean noHead = (table.getHead() == null || table.getHead().isEmpty()) && table.getClazz() == null; boolean noHead = (table.getHead() == null || table.getHead().isEmpty()) && table.getClazz() == null;
if (noHead) { if (noHead) {
// Use parent // Use parent
setHead(sheetHolder.getHead()); tableHolder.setHead(sheetHolder.getHead());
setClazz(sheetHolder.getClazz()); tableHolder.setClazz(sheetHolder.getClazz());
} else { } else {
setHead(table.getHead()); tableHolder.setHead(table.getHead());
setClazz(table.getClazz()); tableHolder.setClazz(table.getClazz());
} }
setNewInitialization(Boolean.TRUE); tableHolder.setNewInitialization(Boolean.TRUE);
// Initialization property // Initialization property
setExcelHeadProperty(new ExcelHeadProperty(getClazz(), getHead(), workbookHolder.getConvertAllFiled())); tableHolder.setExcelHeadProperty(
new ExcelHeadProperty(tableHolder.getClazz(), tableHolder.getHead(), workbookHolder.getConvertAllFiled()));
if (table.getNeedHead() == null) { if (table.getNeedHead() == null) {
setNeedHead(sheetHolder.needHead()); tableHolder.setNeedHead(sheetHolder.needHead());
} else { } else {
setNeedHead(table.getNeedHead()); tableHolder.setNeedHead(table.getNeedHead());
} }
if (table.getWriteRelativeHeadRowIndex() == null) { if (table.getWriteRelativeHeadRowIndex() == null) {
setWriteRelativeHeadRowIndex(sheetHolder.writeRelativeHeadRowIndex()); tableHolder.setWriteRelativeHeadRowIndex(sheetHolder.writeRelativeHeadRowIndex());
} else { } else {
setWriteRelativeHeadRowIndex(table.getWriteRelativeHeadRowIndex()); tableHolder.setWriteRelativeHeadRowIndex(table.getWriteRelativeHeadRowIndex());
} }
// Compatible with old code // Compatible with old code
compatibleOldCode(table); compatibleOldCode(table);
@ -72,24 +74,28 @@ public class TableHolder extends AbstractConfigurationSelector {
handlerList.addAll(table.getCustomWriteHandlerList()); handlerList.addAll(table.getCustomWriteHandlerList());
} }
// Initialization Annotation // Initialization Annotation
initAnnotationConfig(handlerList); tableHolder.initAnnotationConfig(handlerList);
setWriteHandlerMap(sortAndClearUpHandler(handlerList, sheetHolder.getWriteHandlerMap())); tableHolder
Map<Class, Converter> converterMap = new HashMap<Class, Converter>(sheetHolder.converterMap()); .setWriteHandlerMap(tableHolder.sortAndClearUpHandler(handlerList, sheetHolder.getWriteHandlerMap()));
if (table.getCustomConverterMap() != null && !table.getCustomConverterMap().isEmpty()) { Map<Class, Converter> converterMap = new HashMap<Class, Converter>(sheetHolder.getWriteConverterMap());
converterMap.putAll(table.getCustomConverterMap()); 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()) { if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Table writeHandlerMap:{}", getWriteHandlerMap()); LOGGER.debug("Table writeHandlerMap:{}", tableHolder.getWriteHandlerMap());
} }
return tableHolder;
} }
/** /**
* Compatible with old code * Compatible with old code
*/ */
@Deprecated @Deprecated
private void compatibleOldCode(com.alibaba.excel.metadata.Table table) { private static void compatibleOldCode(com.alibaba.excel.metadata.Table table) {
if (table.getTableStyle() != null) { if (table.getTableStyle() != null) {
final TableStyle tableStyle = table.getTableStyle(); final TableStyle tableStyle = table.getTableStyle();
if (table.getCustomWriteHandlerList() == null) { if (table.getCustomWriteHandlerList() == null) {

219
src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java

@ -1,5 +1,6 @@
package com.alibaba.excel.metadata.holder; package com.alibaba.excel.metadata.holder;
import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
@ -11,8 +12,16 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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.Converter;
import com.alibaba.excel.converters.ConverterKey;
import com.alibaba.excel.converters.DefaultConverterLoader; 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.DefaultWriteHandlerLoader;
import com.alibaba.excel.write.handler.WriteHandler; import com.alibaba.excel.write.handler.WriteHandler;
@ -21,8 +30,9 @@ import com.alibaba.excel.write.handler.WriteHandler;
* *
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class WorkbookHolder extends AbstractConfigurationSelector { public class WorkbookHolder extends AbstractWriteConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(WorkbookHolder.class); private static final Logger LOGGER = LoggerFactory.getLogger(WorkbookHolder.class);
/*** /***
* poi Workbook * poi Workbook
*/ */
@ -40,13 +50,53 @@ public class WorkbookHolder extends AbstractConfigurationSelector {
*/ */
private OutputStream outputStream; private OutputStream outputStream;
/** /**
* Template input stream * <li>write: Template input stream
* <li>read: Read InputStream
* <p>
* If 'inputStream' and 'file' all not empty,file first
*/
private InputStream inputStream;
/**
* <li>write: Template file
* <li>read: Read file
* <p>
* If 'inputStream' and 'file' all not empty,file first
*/ */
private InputStream templateInputStream; private File file;
/** /**
* Default true * Default true
*/ */
private Boolean autoCloseStream; 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 * 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 @Deprecated
private com.alibaba.excel.event.WriteHandler writeHandler; private com.alibaba.excel.event.WriteHandler writeHandler;
public WorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) { public static WorkbookHolder buildWriteWorkbookHolder(com.alibaba.excel.metadata.Workbook workbook) {
super(); WorkbookHolder workbookHolder = buildBaseWorkbookHolder(workbook);
this.workbookParam = workbook; workbookHolder.setNewInitialization(Boolean.TRUE);
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());
}
if (workbook.getNeedHead() == null) { if (workbook.getNeedHead() == null) {
setNeedHead(Boolean.TRUE); workbookHolder.setNeedHead(Boolean.TRUE);
} else { } else {
setNeedHead(workbook.getNeedHead()); workbookHolder.setNeedHead(workbook.getNeedHead());
} }
if (workbook.getWriteRelativeHeadRowIndex() == null) { if (workbook.getWriteRelativeHeadRowIndex() == null) {
setWriteRelativeHeadRowIndex(0); workbookHolder.setWriteRelativeHeadRowIndex(0);
} else { } else {
setWriteRelativeHeadRowIndex(workbook.getWriteRelativeHeadRowIndex()); workbookHolder.setWriteRelativeHeadRowIndex(workbook.getWriteRelativeHeadRowIndex());
} }
List<WriteHandler> handlerList = new ArrayList<WriteHandler>(); List<WriteHandler> handlerList = new ArrayList<WriteHandler>();
if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) { if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) {
handlerList.addAll(workbook.getCustomWriteHandlerList()); handlerList.addAll(workbook.getCustomWriteHandlerList());
} }
handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler()); handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler());
setWriteHandlerMap(sortAndClearUpHandler(handlerList, null)); workbookHolder.setWriteHandlerMap(workbookHolder.sortAndClearUpHandler(handlerList, null));
Map<Class, Converter> converterMap = DefaultConverterLoader.loadDefaultWriteConverter(); Map<Class, Converter> converterMap = DefaultConverterLoader.loadDefaultWriteConverter();
if (workbook.getCustomConverterMap() != null && !workbook.getCustomConverterMap().isEmpty()) { if (workbook.getCustomConverterList() != null && !workbook.getCustomConverterList().isEmpty()) {
converterMap.putAll(workbook.getCustomConverterMap()); for (Converter converter : workbook.getCustomConverterList()) {
converterMap.put(converter.getClass(), converter);
} }
setConverterMap(converterMap); }
setHasBeenInitializedSheet(new HashMap<Integer, SheetHolder>()); workbookHolder.setWriteConverterMap(converterMap);
workbookHolder.setHasBeenInitializedSheet(new HashMap<Integer, SheetHolder>());
if (LOGGER.isDebugEnabled()) { 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<ConverterKey, Converter> 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<ReadListener> readListenerList = new ArrayList<ReadListener>();
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() { public Workbook getWorkbook() {
@ -143,12 +234,12 @@ public class WorkbookHolder extends AbstractConfigurationSelector {
this.outputStream = outputStream; this.outputStream = outputStream;
} }
public InputStream getTemplateInputStream() { public InputStream getInputStream() {
return templateInputStream; return inputStream;
} }
public void setTemplateInputStream(InputStream templateInputStream) { public void setInputStream(InputStream inputStream) {
this.templateInputStream = templateInputStream; this.inputStream = inputStream;
} }
public com.alibaba.excel.event.WriteHandler getWriteHandler() { public com.alibaba.excel.event.WriteHandler getWriteHandler() {
@ -174,4 +265,60 @@ public class WorkbookHolder extends AbstractConfigurationSelector {
public void setConvertAllFiled(Boolean convertAllFiled) { public void setConvertAllFiled(Boolean convertAllFiled) {
this.convertAllFiled = 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;
}
} }

4
src/main/java/com/alibaba/excel/metadata/holder/ConfigurationSelector.java → src/main/java/com/alibaba/excel/metadata/holder/WriteConfiguration.java

@ -13,7 +13,7 @@ import com.alibaba.excel.write.handler.WriteHandler;
* *
* @author zhuangjiaju * @author zhuangjiaju
**/ **/
public interface ConfigurationSelector { public interface WriteConfiguration {
/** /**
* What handler does the currently operated cell need to execute * What handler does the currently operated cell need to execute
@ -27,7 +27,7 @@ public interface ConfigurationSelector {
* *
* @return * @return
*/ */
Map<Class, Converter> converterMap(); Map<Class, Converter> writeConverterMap();
/** /**
* Whether a header is required for the currently operated cell * Whether a header is required for the currently operated cell

14
src/main/java/com/alibaba/excel/metadata/property/ExcelContentProperty.java

@ -19,6 +19,12 @@ public class ExcelContentProperty {
private CellStyleProperty cellStyleProperty; private CellStyleProperty cellStyleProperty;
private DateTimeFormatProperty dateTimeFormatProperty; private DateTimeFormatProperty dateTimeFormatProperty;
private NumberFormatProperty numberFormatProperty; private NumberFormatProperty numberFormatProperty;
/**
* true if date uses 1904 windowing, or false if using 1900 date windowing.
*
* @return
*/
private Boolean use1904windowing;
public Field getField() { public Field getField() {
return field; return field;
@ -59,4 +65,12 @@ public class ExcelContentProperty {
public void setNumberFormatProperty(NumberFormatProperty numberFormatProperty) { public void setNumberFormatProperty(NumberFormatProperty numberFormatProperty) {
this.numberFormatProperty = numberFormatProperty; this.numberFormatProperty = numberFormatProperty;
} }
public Boolean getUse1904windowing() {
return use1904windowing;
}
public void setUse1904windowing(Boolean use1904windowing) {
this.use1904windowing = use1904windowing;
}
} }

60
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.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.CellRange; import com.alibaba.excel.metadata.CellRange;
import com.alibaba.excel.metadata.Head; 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 * Define the header attribute of excel
@ -49,7 +51,6 @@ public class ExcelHeadProperty {
* Configuration header information * Configuration header information
*/ */
private Map<Integer, Head> headMap; private Map<Integer, Head> headMap;
/** /**
* Configuration column information * Configuration column information
*/ */
@ -57,7 +58,7 @@ public class ExcelHeadProperty {
private RowHeightProperty headRowHeightProperty; private RowHeightProperty headRowHeightProperty;
private RowHeightProperty contentRowHeightProperty; private RowHeightProperty contentRowHeightProperty;
public ExcelHeadProperty(Class headClazz, List<List<String>> head, Boolean convertAllFiled) { public ExcelHeadProperty(Class headClazz, List<List<String>> head, WorkbookHolder workbookHolder) {
this.headClazz = headClazz; this.headClazz = headClazz;
headMap = new TreeMap<Integer, Head>(); headMap = new TreeMap<Integer, Head>();
contentPropertyMap = new TreeMap<Integer, ExcelContentProperty>(); contentPropertyMap = new TreeMap<Integer, ExcelContentProperty>();
@ -71,27 +72,18 @@ public class ExcelHeadProperty {
headKind = HeadKindEnum.STRING; headKind = HeadKindEnum.STRING;
} else { } else {
// convert headClazz to head // convert headClazz to head
initColumnProperties(convertAllFiled); initColumnProperties(workbookHolder);
} }
initHeadRowNumber(); 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()) { if (!hasHead()) {
LOGGER.warn( 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"); "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<String> headOneRow) {
if (excelHeadProperty == null) {
return new ExcelHeadProperty(clazz, new ArrayList<List<String>>(), false);
}
if (headOneRow != null) {
excelHeadProperty.appendOneRow(headOneRow);
}
return excelHeadProperty;
}
private void initHeadRowNumber() { private void initHeadRowNumber() {
headRowNumber = 0; headRowNumber = 0;
for (Head head : headMap.values()) { 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) { if (headClazz == null) {
return; return;
} }
@ -135,7 +127,7 @@ public class ExcelHeadProperty {
continue; continue;
} }
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
if (excelProperty == null && !convertAllFiled) { if (excelProperty == null && (workbookHolder == null || !workbookHolder.getConvertAllFiled())) {
continue; continue;
} }
if (excelProperty == null || excelProperty.index() < 0) { if (excelProperty == null || excelProperty.index() < 0) {
@ -160,22 +152,23 @@ public class ExcelHeadProperty {
int index = 0; int index = 0;
for (Field field : defaultFieldList) { for (Field field : defaultFieldList) {
while (customFiledMap.containsKey(index)) { while (customFiledMap.containsKey(index)) {
initOneColumnProperty(index, customFiledMap.get(index), headStyle, contentStyle, columnWidth); initOneColumnProperty(index, customFiledMap.get(index), headStyle, contentStyle, columnWidth,
workbookHolder);
customFiledMap.remove(index); customFiledMap.remove(index);
index++; index++;
} }
initOneColumnProperty(index, field, headStyle, contentStyle, columnWidth); initOneColumnProperty(index, field, headStyle, contentStyle, columnWidth, workbookHolder);
index++; index++;
} }
for (Map.Entry<Integer, Field> entry : customFiledMap.entrySet()) { for (Map.Entry<Integer, Field> entry : customFiledMap.entrySet()) {
initOneColumnProperty(index, entry.getValue(), headStyle, contentStyle, columnWidth); initOneColumnProperty(index, entry.getValue(), headStyle, contentStyle, columnWidth, workbookHolder);
index++; index++;
} }
headKind = HeadKindEnum.CLASS; headKind = HeadKindEnum.CLASS;
} }
private void initOneColumnProperty(int index, Field field, HeadStyle parentHeadStyle, 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); ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
List<String> tmpHeadList = new ArrayList<String>(); List<String> tmpHeadList = new ArrayList<String>();
@ -184,6 +177,9 @@ public class ExcelHeadProperty {
} else { } else {
tmpHeadList.add(field.getName()); tmpHeadList.add(field.getName());
} }
if (tmpHeadList.isEmpty() || StringUtils.isEmpty(tmpHeadList.get(0))) {
tmpHeadList.add(field.getName());
}
Head head = new Head(index, field.getName(), tmpHeadList); Head head = new Head(index, field.getName(), tmpHeadList);
HeadStyle headStyle = field.getAnnotation(HeadStyle.class); HeadStyle headStyle = field.getAnnotation(HeadStyle.class);
if (headStyle == null) { if (headStyle == null) {
@ -211,26 +207,12 @@ public class ExcelHeadProperty {
excelContentProperty excelContentProperty
.setNumberFormatProperty(NumberFormatProperty.build(field.getAnnotation(NumberFormat.class))); .setNumberFormatProperty(NumberFormatProperty.build(field.getAnnotation(NumberFormat.class)));
headMap.put(index, head);
contentPropertyMap.put(index, excelContentProperty);
}
/** if (workbookHolder != null && workbookHolder.getReadGlobalProperty() != null) {
* Add one more head under the last head excelContentProperty.setGlobalProperty(workbookHolder.getReadGlobalProperty());
*/
public void appendOneRow(List<String> 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<Integer, Head>)headMap).lastKey() + 1;
headMap.put(index, new Head(i, null, rowData));
} }
} headMap.put(index, head);
initHeadRowNumber(); contentPropertyMap.put(index, excelContentProperty);
} }
public Class getHeadClazz() { public Class getHeadClazz() {

21
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();
}
}

98
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<List<CellData>> {
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {}
@Override
public void invoke(List<CellData> 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<CellData> data, ReadConfiguration readConfiguration) {
List<String> list = new ArrayList<String>();
for (CellData cellData : data) {
list.add((String)convertValue(cellData, String.class, null, readConfiguration.readConverterMap()));
}
return list;
}
private Object buildUserModel(List<CellData> 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<String, Object> map = new HashMap<String, Object>();
Map<Integer, Head> headMap = excelHeadProperty.getHeadMap();
Map<Integer, ExcelContentProperty> contentPropertyMap = excelHeadProperty.getContentPropertyMap();
for (Map.Entry<Integer, Head> 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<ConverterKey, Converter> 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) {}
}

19
src/main/java/com/alibaba/excel/event/ReadListener.java → 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.context.AnalysisContext;
import com.alibaba.excel.event.Listener;
/** /**
* Interface to listen for read results * Interface to listen for read results
@ -19,14 +20,14 @@ public interface ReadListener<T> extends Listener {
void onException(Exception exception, AnalysisContext context) throws Exception; void onException(Exception exception, AnalysisContext context) throws Exception;
/** /**
* when analysis one row trigger invoke function * when analysis one row trigger invoke function.
* *
* @param object * @param data
* one row value * one row value. Is is same as {@link AnalysisContext#currentRowAnalysisResult()}
* @param context * @param context
* analysis context * analysis context
*/ */
void invoke(T object, AnalysisContext context); void invoke(T data, AnalysisContext context);
/** /**
* if have something to do after all analysis * if have something to do after all analysis
@ -34,4 +35,12 @@ public interface ReadListener<T> extends Listener {
* @param context * @param context
*/ */
void doAfterAllAnalysed(AnalysisContext 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);
} }

35
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);
}

41
src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java

@ -1,10 +1,10 @@
package com.alibaba.excel.support; package com.alibaba.excel.support;
import org.apache.poi.poifs.filesystem.FileMagic;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import org.apache.poi.poifs.filesystem.FileMagic;
/** /**
* @author jipengfei * @author jipengfei
*/ */
@ -18,6 +18,24 @@ public enum ExcelTypeEnum {
this.setValue(value); 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() { public String getValue() {
return value; return value;
} }
@ -25,23 +43,4 @@ public enum ExcelTypeEnum {
public void setValue(String value) { public void setValue(String value) {
this.value = 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);
// }
}
} }

45
src/main/java/com/alibaba/excel/util/POITempFile.java → src/main/java/com/alibaba/excel/util/FileUtils.java

@ -1,13 +1,19 @@
package com.alibaba.excel.util; package com.alibaba.excel.util;
import java.io.File; 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 java.util.UUID;
import com.alibaba.excel.exception.ExcelAnalysisException;
/** /**
* *
* @author jipengfei * @author jipengfei
*/ */
public class POITempFile { public class FileUtils {
private static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; private static final String JAVA_IO_TMPDIR = "java.io.tmpdir";
@ -15,9 +21,44 @@ public class POITempFile {
private static final String CACHE = "excache"; 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); createTmpDirectory(POIFILES);
} }

2
src/main/java/com/alibaba/excel/util/NumberUtils.java

@ -22,7 +22,7 @@ public class NumberUtils {
* @return * @return
*/ */
public static String format(Number num, ExcelContentProperty contentProperty) { public static String format(Number num, ExcelContentProperty contentProperty) {
if (contentProperty.getNumberFormatProperty() == null if (contentProperty == null || contentProperty.getNumberFormatProperty() == null
|| StringUtils.isEmpty(contentProperty.getNumberFormatProperty().getFormat())) { || StringUtils.isEmpty(contentProperty.getNumberFormatProperty().getFormat())) {
return num.toString(); return num.toString();
} }

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

@ -3,6 +3,7 @@ package com.alibaba.excel.util;
import java.io.IOException; import java.io.IOException;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; 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.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle; 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.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.alibaba.excel.metadata.holder.WorkbookHolder;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
/** /**
@ -20,16 +22,24 @@ import com.alibaba.excel.support.ExcelTypeEnum;
*/ */
public class WorkBookUtil { public class WorkBookUtil {
public static Workbook createWorkBook(com.alibaba.excel.metadata.Workbook workbookParam) throws IOException { public static Workbook createWorkBook(WorkbookHolder workbookHolder)
Workbook workbook; throws IOException, InvalidFormatException {
if (ExcelTypeEnum.XLS.equals(workbookParam.getExcelType())) { if (ExcelTypeEnum.XLSX.equals(workbookHolder.getExcelType())) {
workbook = (workbookParam.getTemplateInputStream() == null) ? new HSSFWorkbook() if (workbookHolder.getFile() != null) {
: new HSSFWorkbook(new POIFSFileSystem(workbookParam.getTemplateInputStream())); return new SXSSFWorkbook(new XSSFWorkbook(workbookParam.getFile()));
} else {
workbook = (workbookParam.getTemplateInputStream() == null) ? new SXSSFWorkbook(500)
: new SXSSFWorkbook(new XSSFWorkbook(workbookParam.getTemplateInputStream()));
} }
return workbook; if (workbookParam.getInputStream() != null) {
return new SXSSFWorkbook(new XSSFWorkbook(workbookParam.getInputStream()));
}
return new SXSSFWorkbook(500);
}
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) { public static Sheet createSheet(Workbook workbook, com.alibaba.excel.metadata.Sheet sheet) {

32
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.Head;
import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.metadata.Table; 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.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.POITempFile; 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(); org.apache.poi.ss.usermodel.Sheet currentSheet = context.currentSheetHolder().getSheet();
int rowNum = currentSheet.getLastRowNum(); int rowNum = currentSheet.getLastRowNum();
if (context.currentConfigurationSelector().isNew()) { if (context.currentConfiguration().isNew()) {
rowNum += context.currentConfigurationSelector().writeRelativeHeadRowIndex(); rowNum += context.currentConfiguration().writeRelativeHeadRowIndex();
} }
for (int relativeRowIndex = 0; relativeRowIndex < data.size(); relativeRowIndex++) { for (int relativeRowIndex = 0; relativeRowIndex < data.size(); relativeRowIndex++) {
int n = relativeRowIndex + rowNum + 1; int n = relativeRowIndex + rowNum + 1;
@ -92,7 +92,7 @@ public class ExcelBuilderImpl implements ExcelBuilder {
private void beforeRowCreate(int rowIndex, int relativeRowIndex) { private void beforeRowCreate(int rowIndex, int relativeRowIndex) {
List<WriteHandler> handlerList = List<WriteHandler> handlerList =
context.currentConfigurationSelector().writeHandlerMap().get(RowWriteHandler.class); context.currentConfiguration().writeHandlerMap().get(RowWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -106,7 +106,7 @@ public class ExcelBuilderImpl implements ExcelBuilder {
private void afterRowCreate(Row row, int relativeRowIndex) { private void afterRowCreate(Row row, int relativeRowIndex) {
List<WriteHandler> handlerList = List<WriteHandler> handlerList =
context.currentConfigurationSelector().writeHandlerMap().get(RowWriteHandler.class); context.currentConfiguration().writeHandlerMap().get(RowWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -125,7 +125,7 @@ public class ExcelBuilderImpl implements ExcelBuilder {
if (CollectionUtils.isEmpty(oneRowData)) { if (CollectionUtils.isEmpty(oneRowData)) {
return; return;
} }
Map<Integer, Head> headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap(); Map<Integer, Head> headMap = context.currentConfiguration().excelHeadProperty().getHeadMap();
int dataIndex = 0; int dataIndex = 0;
int cellIndex = 0; int cellIndex = 0;
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) { for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
@ -153,17 +153,17 @@ public class ExcelBuilderImpl implements ExcelBuilder {
beforeCellCreate(row, head, relativeRowIndex); beforeCellCreate(row, head, relativeRowIndex);
Cell cell = WorkBookUtil.createCell(row, cellIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex);
Object value = oneRowData.get(dataIndex); Object value = oneRowData.get(dataIndex);
converterAndSet(context.currentConfigurationSelector(), value.getClass(), cell, value, null); converterAndSet(context.currentConfiguration(), value.getClass(), cell, value, null);
afterCellCreate(head, cell, relativeRowIndex); afterCellCreate(head, cell, relativeRowIndex);
} }
private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex) { private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex) {
ConfigurationSelector currentConfigurationSelector = context.currentConfigurationSelector(); WriteConfiguration currentWriteConfiguration = context.currentConfiguration();
BeanMap beanMap = BeanMap.create(oneRowData); BeanMap beanMap = BeanMap.create(oneRowData);
Set<String> beanMapHandledSet = new HashSet<String>(); Set<String> beanMapHandledSet = new HashSet<String>();
Map<Integer, Head> headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap(); Map<Integer, Head> headMap = context.currentConfiguration().excelHeadProperty().getHeadMap();
Map<Integer, ExcelContentProperty> contentPropertyMap = Map<Integer, ExcelContentProperty> contentPropertyMap =
context.currentConfigurationSelector().excelHeadProperty().getContentPropertyMap(); context.currentConfiguration().excelHeadProperty().getContentPropertyMap();
int cellIndex = 0; int cellIndex = 0;
for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) { for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) {
cellIndex = entry.getKey(); cellIndex = entry.getKey();
@ -176,7 +176,7 @@ public class ExcelBuilderImpl implements ExcelBuilder {
beforeCellCreate(row, head, relativeRowIndex); beforeCellCreate(row, head, relativeRowIndex);
Cell cell = WorkBookUtil.createCell(row, cellIndex); Cell cell = WorkBookUtil.createCell(row, cellIndex);
Object value = beanMap.get(name); Object value = beanMap.get(name);
converterAndSet(currentConfigurationSelector, excelContentProperty.getField().getType(), cell, value, converterAndSet(currentWriteConfiguration, excelContentProperty.getField().getType(), cell, value,
excelContentProperty); excelContentProperty);
afterCellCreate(head, cell, relativeRowIndex); afterCellCreate(head, cell, relativeRowIndex);
beanMapHandledSet.add(name); beanMapHandledSet.add(name);
@ -195,14 +195,14 @@ public class ExcelBuilderImpl implements ExcelBuilder {
} }
beforeCellCreate(row, null, relativeRowIndex); beforeCellCreate(row, null, relativeRowIndex);
Cell cell = WorkBookUtil.createCell(row, cellIndex++); 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); afterCellCreate(null, cell, relativeRowIndex);
} }
} }
private void beforeCellCreate(Row row, Head head, int relativeRowIndex) { private void beforeCellCreate(Row row, Head head, int relativeRowIndex) {
List<WriteHandler> handlerList = List<WriteHandler> handlerList =
context.currentConfigurationSelector().writeHandlerMap().get(CellWriteHandler.class); context.currentConfiguration().writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -217,7 +217,7 @@ public class ExcelBuilderImpl implements ExcelBuilder {
private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) { private void afterCellCreate(Head head, Cell cell, int relativeRowIndex) {
List<WriteHandler> handlerList = List<WriteHandler> handlerList =
context.currentConfigurationSelector().writeHandlerMap().get(CellWriteHandler.class); context.currentConfiguration().writeHandlerMap().get(CellWriteHandler.class);
if (handlerList == null || handlerList.isEmpty()) { if (handlerList == null || handlerList.isEmpty()) {
return; return;
} }
@ -232,12 +232,12 @@ public class ExcelBuilderImpl implements ExcelBuilder {
} }
} }
private void converterAndSet(ConfigurationSelector currentConfigurationSelector, Class clazz, Cell cell, private void converterAndSet(WriteConfiguration currentWriteConfiguration, Class clazz, Cell cell,
Object value, ExcelContentProperty excelContentProperty) { Object value, ExcelContentProperty excelContentProperty) {
if (value == null) { if (value == null) {
return; return;
} }
Converter converter = currentConfigurationSelector.converterMap().get(clazz); Converter converter = currentWriteConfiguration.converterMap().get(clazz);
if (converter == null) { if (converter == null) {
throw new ExcelDataConvertException( throw new ExcelDataConvertException(
"Can not find 'Converter' support class " + clazz.getSimpleName() + "."); "Can not find 'Converter' support class " + clazz.getSimpleName() + ".");

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

@ -1,7 +1,6 @@
package com.alibaba.excel.write.builder; package com.alibaba.excel.write.builder;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
@ -170,25 +169,22 @@ public class ExcelWriterBuilder {
return outputFile(new File(outputUri)); return outputFile(new File(outputUri));
} }
public ExcelWriterBuilder withTemplate(InputStream templateInputStream) { public ExcelWriterBuilder withTemplate(InputStream inputStream) {
workbook.setTemplateInputStream(templateInputStream); workbook.setInputStream(inputStream);
return this; return this;
} }
public ExcelWriterBuilder withTemplate(File templateFile) { public ExcelWriterBuilder withTemplate(File file) {
try { workbook.setFile(file);
return withTemplate(new FileInputStream(templateFile)); return this;
} catch (FileNotFoundException e) {
throw new ExcelGenerateException("Can not create file", e);
}
} }
public ExcelWriterBuilder withTemplate(String templatePathName) { public ExcelWriterBuilder withTemplate(String pathName) {
return withTemplate(new File(templatePathName)); return withTemplate(new File(pathName));
} }
public ExcelWriterBuilder withTemplate(URI templateUri) { public ExcelWriterBuilder withTemplate(URI uri) {
return withTemplate(new File(templateUri)); return withTemplate(new File(uri));
} }
/** /**

Loading…
Cancel
Save