Browse Source

将缓存改为ehcache

pull/507/head
zhuangjiaju 6 years ago
parent
commit
bca0fd83e3
  1. 11
      pom.xml
  2. 53
      src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java
  3. 11
      src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java
  4. 10
      src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java
  5. 57
      src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java
  6. 16
      src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
  7. 27
      src/main/java/com/alibaba/excel/cache/Cache.java
  8. 46
      src/main/java/com/alibaba/excel/cache/Ehcache.java
  9. 31
      src/main/java/com/alibaba/excel/cache/SharedStringsTableCache.java
  10. 6
      src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java
  11. 8
      src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java
  12. 9
      src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java
  13. 7
      src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java
  14. 38
      src/main/java/com/alibaba/excel/util/POITempFile.java
  15. 2
      src/main/java/com/alibaba/excel/util/StringUtils.java
  16. 24
      src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java
  17. 40
      src/test/java/com/alibaba/easyexcel/test/ehcache/EncacheTest.java
  18. 33
      src/test/java/com/alibaba/easyexcel/test/read/large/LargeData07Test.java
  19. 29
      src/test/java/com/alibaba/easyexcel/test/read/large/LargeDataListener.java
  20. 16
      src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleData.java
  21. 26
      src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleData07Test.java
  22. 31
      src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleDataListener.java
  23. 4
      src/test/java/com/alibaba/easyexcel/test/util/FileUtil.java
  24. 17
      src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData.java
  25. 3
      src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData07Test.java
  26. 2
      src/test/resources/logback.xml
  27. BIN
      src/test/resources/read/large/large07.xlsx
  28. BIN
      src/test/resources/read/simple/simple07.xlsx

11
pom.xml

@ -76,6 +76,11 @@
<artifactId>slf4j-api</artifactId> <artifactId>slf4j-api</artifactId>
<version>1.7.26</version> <version>1.7.26</version>
</dependency> </dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.7.1</version>
</dependency>
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
@ -88,6 +93,12 @@
<version>1.2.58</version> <version>1.2.58</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>

53
src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java

@ -0,0 +1,53 @@
package com.alibaba.excel.analysis.v07;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.alibaba.excel.cache.Cache;
/**
* Sax read sharedStringsTable.xml
*
* @author zhuangjiaju
*/
public class SharedStringsTableHandler extends DefaultHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(SharedStringsTableHandler.class);
private String currentData;
private boolean isT;
private int index = 0;
private Cache cache;
public SharedStringsTableHandler(Cache cache) {
this.cache = cache;
}
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
if ("t".equals(name)) {
currentData = null;
isT = true;
}
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if ("t".equals(name)) {
currentData = null;
isT = false;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (isT) {
cache.put(index++, new String(ch, start, length));
if (index % 100000 == 0) {
LOGGER.info("row:{} ,mem:{},data:{}", index, Runtime.getRuntime().totalMemory());
}
}
}
}

11
src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java

@ -3,27 +3,26 @@ package com.alibaba.excel.analysis.v07;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.poi.xssf.model.SharedStringsTable;
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; import com.alibaba.excel.event.AnalysisEventRegistryCenter;
public class XlsxHandlerFactory { public class XlsxHandlerFactory {
public static List<XlsxCellHandler> buildCellHandlers(AnalysisContext analysisContext, public static List<XlsxCellHandler> buildCellHandlers(AnalysisContext analysisContext,
AnalysisEventRegistryCenter registerCenter, SharedStringsTable sst) { 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, sst); DefaultCellHandler defaultCellHandler = buildXlsxRowResultHandler(analysisContext, registerCenter, cahe);
result.add(defaultCellHandler); result.add(defaultCellHandler);
result.add(new ProcessResultCellHandler(registerCenter, defaultCellHandler)); result.add(new ProcessResultCellHandler(registerCenter, defaultCellHandler));
return result; return result;
} }
private static DefaultCellHandler buildXlsxRowResultHandler(AnalysisContext analysisContext, private static DefaultCellHandler buildXlsxRowResultHandler(AnalysisContext analysisContext,
AnalysisEventRegistryCenter registerCenter, SharedStringsTable sst) { AnalysisEventRegistryCenter registerCenter, Cache cahe) {
return new DefaultCellHandler(analysisContext, registerCenter, sst); return new DefaultCellHandler(analysisContext, registerCenter, cahe);
} }
} }

10
src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java

@ -2,11 +2,11 @@ package com.alibaba.excel.analysis.v07;
import java.util.List; import java.util.List;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.Attributes; 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; import com.alibaba.excel.event.AnalysisEventRegistryCenter;
@ -19,12 +19,11 @@ public class XlsxRowHandler extends DefaultHandler {
private List<XlsxCellHandler> cellHandlers; private List<XlsxCellHandler> cellHandlers;
private XlsxRowResultHolder rowResultHolder; private XlsxRowResultHolder rowResultHolder;
public XlsxRowHandler(AnalysisEventRegistryCenter registerCenter, SharedStringsTable sst, public XlsxRowHandler(AnalysisEventRegistryCenter registerCenter, Cache cache, AnalysisContext analysisContext) {
AnalysisContext analysisContext) { this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext, registerCenter, cache);
this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext, registerCenter, sst);
for (XlsxCellHandler cellHandler : cellHandlers) { for (XlsxCellHandler cellHandler : cellHandlers) {
if (cellHandler instanceof XlsxRowResultHolder) { if (cellHandler instanceof XlsxRowResultHolder) {
this.rowResultHolder = (XlsxRowResultHolder) cellHandler; this.rowResultHolder = (XlsxRowResultHolder)cellHandler;
break; break;
} }
} }
@ -55,4 +54,3 @@ public class XlsxRowHandler extends DefaultHandler {
} }
} }
} }

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

@ -1,13 +1,18 @@
package com.alibaba.excel.analysis.v07; package com.alibaba.excel.analysis.v07;
import com.alibaba.excel.analysis.BaseSaxAnalyser; import java.io.IOException;
import com.alibaba.excel.context.AnalysisContext; import java.io.InputStream;
import com.alibaba.excel.exception.ExcelAnalysisException; import java.util.ArrayList;
import com.alibaba.excel.metadata.Sheet; import java.util.List;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException; 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.model.SharedStringsTable; import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
@ -16,12 +21,12 @@ 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 javax.xml.parsers.SAXParser; import com.alibaba.excel.analysis.BaseSaxAnalyser;
import javax.xml.parsers.SAXParserFactory; import com.alibaba.excel.cache.Cache;
import java.io.IOException; import com.alibaba.excel.cache.Ehcache;
import java.io.InputStream; import com.alibaba.excel.context.AnalysisContext;
import java.util.ArrayList; import com.alibaba.excel.exception.ExcelAnalysisException;
import java.util.List; import com.alibaba.excel.metadata.Sheet;
/** /**
* *
@ -31,7 +36,7 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser {
private XSSFReader xssfReader; private XSSFReader xssfReader;
private SharedStringsTable sharedStringsTable; private Cache cache;
private List<SheetSource> sheetSourceList = new ArrayList<SheetSource>(); private List<SheetSource> sheetSourceList = new ArrayList<SheetSource>();
@ -41,8 +46,27 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser {
this.analysisContext = analysisContext; this.analysisContext = analysisContext;
analysisContext.setCurrentRowNum(0); analysisContext.setCurrentRowNum(0);
this.xssfReader = new XSSFReader(OPCPackage.open(analysisContext.getInputStream())); OPCPackage pkg = OPCPackage.open(analysisContext.getInputStream());
this.sharedStringsTable = this.xssfReader.getSharedStringsTable(); this.xssfReader = new XSSFReader(pkg);
ArrayList<PackagePart> parts = pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType());
PackagePart packagePart = parts.get(0);
InputSource sheetSource1 = new InputSource(packagePart.getInputStream());
this.cache = new Ehcache();
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);
packagePart.getInputStream().close();
} catch (Exception e) {
e.printStackTrace();
throw new ExcelAnalysisException(e);
}
InputStream workbookXml = xssfReader.getWorkbookData(); InputStream workbookXml = xssfReader.getWorkbookData();
WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml); WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml);
@ -53,7 +77,6 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser {
} }
this.analysisContext.setUse1904WindowDate(use1904WindowDate); this.analysisContext.setUse1904WindowDate(use1904WindowDate);
XSSFReader.SheetIterator ite; XSSFReader.SheetIterator ite;
sheetSourceList = new ArrayList<SheetSource>(); sheetSourceList = new ArrayList<SheetSource>();
ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData();
@ -77,7 +100,7 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser {
int i = 0; int i = 0;
for (SheetSource sheetSource : sheetSourceList) { for (SheetSource sheetSource : sheetSourceList) {
i++; i++;
analysisContext.setCurrentSheet(new Sheet(i)); analysisContext.setCurrentSheet(new Sheet(i, sheetParam.getReadHeadRowNumber()));
parseXmlSource(sheetSource.getInputStream()); parseXmlSource(sheetSource.getInputStream());
} }
} }
@ -92,7 +115,7 @@ 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, sharedStringsTable, analysisContext); ContentHandler handler = new XlsxRowHandler(this, cache, analysisContext);
xmlReader.setContentHandler(handler); xmlReader.setContentHandler(handler);
xmlReader.parse(sheetSource); xmlReader.parse(sheetSource);
inputStream.close(); inputStream.close();

16
src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java

@ -8,13 +8,12 @@ import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TYPE_TAG;
import java.util.Arrays; import java.util.Arrays;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes; 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;
@ -27,7 +26,7 @@ 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 AnalysisEventRegistryCenter registerCenter;
private final SharedStringsTable sst; private final Cache cahe;
private String currentTag; private String currentTag;
private String currentCellIndex; private String currentCellIndex;
private int curRow; private int curRow;
@ -35,11 +34,10 @@ 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, public DefaultCellHandler(AnalysisContext analysisContext, AnalysisEventRegistryCenter registerCenter, Cache cahe) {
SharedStringsTable sst) {
this.analysisContext = analysisContext; this.analysisContext = analysisContext;
this.registerCenter = registerCenter; this.registerCenter = registerCenter;
this.sst = sst; this.cahe = cahe;
} }
@Override @Override
@ -86,8 +84,7 @@ 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) {
RichTextString richTextString = sst.getItemAt(Integer.parseInt(currentCellData.getStringValue())); currentCellData.setStringValue(cahe.get(Integer.valueOf(currentCellData.getStringValue())));
currentCellData.setStringValue(richTextString.toString());
} }
curRowContent[curCol] = currentCellData; curRowContent[curCol] = currentCellData;
} }
@ -112,6 +109,9 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder
if (StringUtils.isEmpty(currentCellValue)) { if (StringUtils.isEmpty(currentCellValue)) {
return; return;
} }
if (currentTag == null) {
return;
}
if (CELL_FORMULA_TAG.equals(currentTag)) { if (CELL_FORMULA_TAG.equals(currentTag)) {
currentCellData.setReadFormula(currentCellValue); currentCellData.setReadFormula(currentCellValue);
return; return;

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

@ -0,0 +1,27 @@
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();
}

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

@ -0,0 +1,46 @@
package com.alibaba.excel.cache;
import java.io.File;
import java.util.Map;
import org.ehcache.PersistentCacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.MemoryUnit;
import com.alibaba.excel.util.POITempFile;
/**
* Default cache
*
* @author zhuangjiaju
*/
public class Ehcache implements Cache {
private org.ehcache.Cache<Integer, Map<Integer, String>> cache;
public Ehcache() {
File file = POITempFile.createCacheTmpFile();
PersistentCacheManager persistentCacheManager =
CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(file))
.withCache("cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10, MemoryUnit.GB)))
.build(true);
this.cache = persistentCacheManager.getCache("cache", Integer.class, String.class);
}
@Override
public void put(Integer key, String value) {
cache.put(key, value);
}
@Override
public String get(Integer key) {
return cache.get(key);
}
@Override
public void finish() {
}
}

31
src/main/java/com/alibaba/excel/cache/SharedStringsTableCache.java vendored

@ -0,0 +1,31 @@
package com.alibaba.excel.cache;
import org.apache.poi.xssf.model.SharedStringsTable;
/**
* Default cache
*
* @author zhuangjiaju
*/
public class SharedStringsTableCache implements Cache {
private SharedStringsTable sharedStringsTable;
public SharedStringsTableCache(SharedStringsTable sharedStringsTable) {
this.sharedStringsTable = sharedStringsTable;
}
@Override
public void put(Integer key, String value) {
throw new UnsupportedOperationException("Can not put value");
}
@Override
public String get(Integer key) {
return sharedStringsTable.getItemAt(key).toString();
}
@Override
public void finish() {
}
}

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

@ -6,6 +6,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.CellStyle; import com.alibaba.excel.metadata.CellStyle;
@ -22,6 +24,7 @@ import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class SheetHolder extends AbstractConfigurationSelector { public class SheetHolder extends AbstractConfigurationSelector {
private static final Logger LOGGER = LoggerFactory.getLogger(SheetHolder.class);
/*** /***
* poi sheet * poi sheet
@ -91,6 +94,9 @@ public class SheetHolder extends AbstractConfigurationSelector {
} }
setConverterMap(converterMap); setConverterMap(converterMap);
setHasBeenInitializedTable(new HashMap<Integer, TableHolder>()); setHasBeenInitializedTable(new HashMap<Integer, TableHolder>());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Sheet writeHandlerMap:{}", getWriteHandlerMap());
}
} }
/** /**

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

@ -5,6 +5,9 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.CellStyle; import com.alibaba.excel.metadata.CellStyle;
import com.alibaba.excel.metadata.Table; import com.alibaba.excel.metadata.Table;
@ -19,6 +22,8 @@ import com.alibaba.excel.write.style.RowCellStyleStrategy;
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class TableHolder extends AbstractConfigurationSelector { public class TableHolder extends AbstractConfigurationSelector {
private static final Logger LOGGER = LoggerFactory.getLogger(TableHolder.class);
/*** /***
* poi sheet * poi sheet
*/ */
@ -75,6 +80,9 @@ public class TableHolder extends AbstractConfigurationSelector {
converterMap.putAll(table.getCustomConverterMap()); converterMap.putAll(table.getCustomConverterMap());
} }
setConverterMap(converterMap); setConverterMap(converterMap);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Table writeHandlerMap:{}", getWriteHandlerMap());
}
} }
/** /**

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

@ -8,6 +8,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.DefaultConverterLoader; import com.alibaba.excel.converters.DefaultConverterLoader;
@ -20,6 +22,7 @@ import com.alibaba.excel.write.handler.WriteHandler;
* @author zhuangjiaju * @author zhuangjiaju
*/ */
public class WorkbookHolder extends AbstractConfigurationSelector { public class WorkbookHolder extends AbstractConfigurationSelector {
private static final Logger LOGGER = LoggerFactory.getLogger(WorkbookHolder.class);
/*** /***
* poi Workbook * poi Workbook
*/ */
@ -95,9 +98,6 @@ public class WorkbookHolder extends AbstractConfigurationSelector {
if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) { if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) {
handlerList.addAll(workbook.getCustomWriteHandlerList()); handlerList.addAll(workbook.getCustomWriteHandlerList());
} }
// Initialization Annotation
initAnnotationConfig(handlerList);
handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler()); handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler());
setWriteHandlerMap(sortAndClearUpHandler(handlerList, null)); setWriteHandlerMap(sortAndClearUpHandler(handlerList, null));
Map<Class, Converter> converterMap = DefaultConverterLoader.loadDefaultWriteConverter(); Map<Class, Converter> converterMap = DefaultConverterLoader.loadDefaultWriteConverter();
@ -106,6 +106,9 @@ public class WorkbookHolder extends AbstractConfigurationSelector {
} }
setConverterMap(converterMap); setConverterMap(converterMap);
setHasBeenInitializedSheet(new HashMap<Integer, SheetHolder>()); setHasBeenInitializedSheet(new HashMap<Integer, SheetHolder>());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Wookbook writeHandlerMap:{}", getWriteHandlerMap());
}
} }
public Workbook getWorkbook() { public Workbook getWorkbook() {

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

@ -75,6 +75,10 @@ public class ExcelHeadProperty {
} }
initHeadRowNumber(); initHeadRowNumber();
LOGGER.info("The initialization sheet/table 'ExcelHeadProperty' is complete , head kind is {}", headKind); LOGGER.info("The initialization sheet/table 'ExcelHeadProperty' is complete , head kind is {}", headKind);
if (!hasHead()) {
LOGGER.warn(
"The table has no header set and all annotations will not be read.If you want to use annotations, please use set head class in ExcelWriterBuilder/ExcelWriterSheetBuilder/ExcelWriterTableBuilder");
}
} }
public static ExcelHeadProperty buildExcelHeadProperty(ExcelHeadProperty excelHeadProperty, Class clazz, public static ExcelHeadProperty buildExcelHeadProperty(ExcelHeadProperty excelHeadProperty, Class clazz,
@ -136,7 +140,7 @@ public class ExcelHeadProperty {
} }
if (excelProperty == null || excelProperty.index() < 0) { if (excelProperty == null || excelProperty.index() < 0) {
defaultFieldList.add(field); defaultFieldList.add(field);
return; continue;
} }
if (customFiledMap.containsKey(excelProperty.index())) { if (customFiledMap.containsKey(excelProperty.index())) {
throw new ExcelGenerateException("The index of " + customFiledMap.get(excelProperty.index()).getName() throw new ExcelGenerateException("The index of " + customFiledMap.get(excelProperty.index()).getName()
@ -195,6 +199,7 @@ public class ExcelHeadProperty {
ExcelContentProperty excelContentProperty = new ExcelContentProperty(); ExcelContentProperty excelContentProperty = new ExcelContentProperty();
excelContentProperty.setHead(head); excelContentProperty.setHead(head);
excelContentProperty.setField(field);
ContentStyle contentStyle = field.getAnnotation(ContentStyle.class); ContentStyle contentStyle = field.getAnnotation(ContentStyle.class);
if (contentStyle == null) { if (contentStyle == null) {
contentStyle = parentContentStyle; contentStyle = parentContentStyle;

38
src/main/java/com/alibaba/excel/util/POITempFile.java

@ -1,6 +1,7 @@
package com.alibaba.excel.util; package com.alibaba.excel.util;
import java.io.File; import java.io.File;
import java.util.UUID;
/** /**
* *
@ -12,20 +13,53 @@ public class POITempFile {
private static final String POIFILES = "poifiles"; private static final String POIFILES = "poifiles";
private static final String CACHE = "excache";
/** /**
*/ */
public static void createPOIFilesDirectory() { public static void createPOIFilesDirectory() {
createTmpDirectory(POIFILES);
}
public static File createCacheTmpFile() {
File directory = createTmpDirectory(CACHE);
return new File(directory.getPath(), UUID.randomUUID().toString());
}
/**
* delete file
*
* @param file
*/
public static void delete(File file) {
if (file.isFile()) {
file.delete();
return;
}
if (file.isDirectory()) {
File[] childFiles = file.listFiles();
if (childFiles == null || childFiles.length == 0) {
file.delete();
return;
}
for (int i = 0; i < childFiles.length; i++) {
delete(childFiles[i]);
}
file.delete();
}
}
public static File createTmpDirectory(String path) {
String tmpDir = System.getProperty(JAVA_IO_TMPDIR); String tmpDir = System.getProperty(JAVA_IO_TMPDIR);
if (tmpDir == null) { if (tmpDir == null) {
throw new RuntimeException( throw new RuntimeException(
"Systems temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + " jvm property!"); "Systems temporary directory not defined - set the -D" + JAVA_IO_TMPDIR + " jvm property!");
} }
File directory = new File(tmpDir, POIFILES); File directory = new File(tmpDir, path);
if (!directory.exists()) { if (!directory.exists()) {
syncCreatePOIFilesDirectory(directory); syncCreatePOIFilesDirectory(directory);
} }
return directory;
} }
/** /**

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

@ -31,6 +31,7 @@ import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.UUID;
import org.apache.commons.codec.binary.CharSequenceUtils; import org.apache.commons.codec.binary.CharSequenceUtils;
@ -1312,4 +1313,5 @@ public abstract class StringUtils {
return true; return true;
} }
} }

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

@ -1,7 +1,9 @@
package com.alibaba.excel.write; package com.alibaba.excel.write;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
@ -158,6 +160,7 @@ public class ExcelBuilderImpl implements ExcelBuilder {
private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex) { private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex) {
ConfigurationSelector currentConfigurationSelector = context.currentConfigurationSelector(); ConfigurationSelector currentConfigurationSelector = context.currentConfigurationSelector();
BeanMap beanMap = BeanMap.create(oneRowData); BeanMap beanMap = BeanMap.create(oneRowData);
Set<String> beanMapHandledSet = new HashSet<String>();
Map<Integer, Head> headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap(); Map<Integer, Head> headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap();
Map<Integer, ExcelContentProperty> contentPropertyMap = Map<Integer, ExcelContentProperty> contentPropertyMap =
context.currentConfigurationSelector().excelHeadProperty().getContentPropertyMap(); context.currentConfigurationSelector().excelHeadProperty().getContentPropertyMap();
@ -176,32 +179,27 @@ public class ExcelBuilderImpl implements ExcelBuilder {
converterAndSet(currentConfigurationSelector, excelContentProperty.getField().getType(), cell, value, converterAndSet(currentConfigurationSelector, excelContentProperty.getField().getType(), cell, value,
excelContentProperty); excelContentProperty);
afterCellCreate(head, cell, relativeRowIndex); afterCellCreate(head, cell, relativeRowIndex);
beanMap.remove(name); beanMapHandledSet.add(name);
} }
// Finish // Finish
if (beanMap.isEmpty()) { if (beanMapHandledSet.size() == beanMap.size()) {
return; return;
} }
if (cellIndex != 0) { if (cellIndex != 0) {
cellIndex++; cellIndex++;
} }
for (Object value : beanMap.values()) { Set<Map.Entry<String, Object>> entrySet = beanMap.entrySet();
for (Map.Entry<String, Object> entry : entrySet) {
if (entry.getValue() == null || beanMapHandledSet.contains(entry.getKey())) {
continue;
}
beforeCellCreate(row, null, relativeRowIndex); beforeCellCreate(row, null, relativeRowIndex);
Cell cell = WorkBookUtil.createCell(row, cellIndex++); Cell cell = WorkBookUtil.createCell(row, cellIndex++);
converterAndSet(currentConfigurationSelector, value.getClass(), cell, value, null); converterAndSet(currentConfigurationSelector, entry.getValue().getClass(), cell, entry.getValue(), null);
afterCellCreate(null, cell, relativeRowIndex); afterCellCreate(null, cell, relativeRowIndex);
} }
} }
private void doAddJavaObjectToExcel(List<Object> oneRowData, Head head, Row row, int relativeRowIndex,
int dataIndex, int cellIndex) {
beforeCellCreate(row, head, relativeRowIndex);
Cell cell = WorkBookUtil.createCell(row, cellIndex);
Object value = oneRowData.get(dataIndex);
converterAndSet(context.currentConfigurationSelector(), value.getClass(), cell, value, null);
afterCellCreate(head, 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.currentConfigurationSelector().writeHandlerMap().get(CellWriteHandler.class);

40
src/test/java/com/alibaba/easyexcel/test/ehcache/EncacheTest.java vendored

@ -0,0 +1,40 @@
package com.alibaba.easyexcel.test.ehcache;
import java.io.File;
import org.ehcache.Cache;
import org.ehcache.PersistentCacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.MemoryUnit;
import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.util.POITempFile;
/**
* @author zhuangjiaju
*/
@Ignore
public class EncacheTest {
private static final Logger LOGGER = LoggerFactory.getLogger(EncacheTest.class);
@Test
public void cache() {
File file = POITempFile.createCacheTmpFile();
PersistentCacheManager persistentCacheManager =
CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(file))
.withCache("cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10, MemoryUnit.GB)))
.build(true);
Cache<Integer, String> cache = persistentCacheManager.getCache("cache", Integer.class, String.class);
cache.put(1, "测试1");
LOGGER.info("cache:{}", cache.get(1));
persistentCacheManager.close();
LOGGER.info("close");
POITempFile.delete(file);
}
}

33
src/test/java/com/alibaba/easyexcel/test/read/large/LargeData07Test.java

@ -0,0 +1,33 @@
package com.alibaba.easyexcel.test.read.large;
import java.io.InputStream;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.util.FileUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.metadata.Sheet;
/**
* Simple data test
*
* @author zhuangjiaju
*/
public class LargeData07Test {
private static final Logger LOGGER = LoggerFactory.getLogger(LargeData07Test.class);
@Test
public void large() throws Exception {
LOGGER.info("start");
long start = System.currentTimeMillis();
InputStream inputStream = FileUtil.readFile("large/large07.xlsx");
ExcelReader excelReader = EasyExcelFactory.getReader(inputStream, new LargeDataListener());
excelReader.read(new Sheet(1, 1));
inputStream.close();
LOGGER.info("time:{}", System.currentTimeMillis() - start);
}
}

29
src/test/java/com/alibaba/easyexcel/test/read/large/LargeDataListener.java

@ -0,0 +1,29 @@
package com.alibaba.easyexcel.test.read.large;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.easyexcel.test.read.simple.SimpleDataListener;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
/**
* @author zhuangjiaju
*/
public class LargeDataListener extends AnalysisEventListener<Object> {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleDataListener.class);
private int count = 0;
@Override
public void invoke(Object object, AnalysisContext context) {
count++;
if (count % 100000 == 0) {
LOGGER.info("row:{} ,mem:{},data:{}", count, Runtime.getRuntime().totalMemory(), JSON.toJSONString(object));
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {}
}

16
src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleData.java

@ -0,0 +1,16 @@
package com.alibaba.easyexcel.test.read.simple;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* @author zhuangjiaju
*/
@Data
public class SimpleData {
@ExcelProperty("字符串1")
private String string1;
@ExcelProperty("字符串2")
private String string2;
}

26
src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleData07Test.java

@ -0,0 +1,26 @@
package com.alibaba.easyexcel.test.read.simple;
import java.io.InputStream;
import org.junit.Test;
import com.alibaba.easyexcel.test.util.FileUtil;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.metadata.Sheet;
/**
* Simple data test
*
* @author zhuangjiaju
*/
public class SimpleData07Test {
@Test
public void simple() throws Exception {
InputStream inputStream = FileUtil.readFile("simple/simple07.xlsx");
ExcelReader excelReader = EasyExcelFactory.getReader(inputStream, new SimpleDataListener());
excelReader.read(new Sheet(1, 1), SimpleData.class);
inputStream.close();
}
}

31
src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleDataListener.java

@ -0,0 +1,31 @@
package com.alibaba.easyexcel.test.read.simple;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
/**
* @author zhuangjiaju
*/
public class SimpleDataListener extends AnalysisEventListener<Object> {
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleDataListener.class);
List<Object> list = new ArrayList<Object>();
@Override
public void invoke(Object object, AnalysisContext context) {
list.add(object);
LOGGER.info("data:{}", JSON.toJSONString(object));
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
assert list.size() == 10;
}
}

4
src/test/java/com/alibaba/easyexcel/test/util/FileUtil.java

@ -9,6 +9,10 @@ public class FileUtil {
return Thread.currentThread().getContextClassLoader().getResourceAsStream("" + fileName); return Thread.currentThread().getContextClassLoader().getResourceAsStream("" + fileName);
} }
public static InputStream readFile(String fileName) {
return Thread.currentThread().getContextClassLoader().getResourceAsStream("read/" + fileName);
}
public static String getPath() { public static String getPath() {
return FileUtil.class.getResource("/").getPath(); return FileUtil.class.getResource("/").getPath();
} }

17
src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData.java

@ -2,18 +2,15 @@ package com.alibaba.easyexcel.test.wirte.simple;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/** /**
* @author zhuangjiaju * @author zhuangjiaju
*/ */
@Data
public class SimpleData { public class SimpleData {
@ExcelProperty("字符串") @ExcelProperty("字符串1")
private String string; private String string1;
@ExcelProperty("字符串2")
public String getString() { private String string2;
return string;
}
public void setString(String string) {
this.string = string;
}
} }

3
src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData07Test.java

@ -40,7 +40,8 @@ public class SimpleData07Test {
List<SimpleData> list = new ArrayList<SimpleData>(); List<SimpleData> list = new ArrayList<SimpleData>();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
SimpleData simpleData = new SimpleData(); SimpleData simpleData = new SimpleData();
simpleData.setString("字符体" + i); simpleData.setString1("一号字" + i);
simpleData.setString2("二号字" + i);
list.add(simpleData); list.add(simpleData);
} }
return list; return list;

2
src/test/resources/logback.xml

@ -7,7 +7,7 @@
<pattern>${LOG_PATTERN}</pattern> <pattern>${LOG_PATTERN}</pattern>
</encoder> </encoder>
</appender> </appender>
<root level="DEBUG"> <root level="INFO">
<appender-ref ref="STDOUT"/> <appender-ref ref="STDOUT"/>
</root> </root>
</configuration> </configuration>

BIN
src/test/resources/read/large/large07.xlsx

Binary file not shown.

BIN
src/test/resources/read/simple/simple07.xlsx

Binary file not shown.
Loading…
Cancel
Save