diff --git a/pom.xml b/pom.xml index f85fb7a7..10175955 100644 --- a/pom.xml +++ b/pom.xml @@ -76,6 +76,11 @@ slf4j-api 1.7.26 + + org.ehcache + ehcache + 3.7.1 + ch.qos.logback logback-classic @@ -88,6 +93,12 @@ 1.2.58 test + + org.projectlombok + lombok + 1.18.8 + test + junit junit diff --git a/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java new file mode 100644 index 00000000..40d413dd --- /dev/null +++ b/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()); + } + } + } +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java index 6d866a54..875b94b4 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java +++ b/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.List; -import org.apache.poi.xssf.model.SharedStringsTable; - import com.alibaba.excel.analysis.v07.handlers.CountRowCellHandler; import com.alibaba.excel.analysis.v07.handlers.DefaultCellHandler; import com.alibaba.excel.analysis.v07.handlers.ProcessResultCellHandler; +import com.alibaba.excel.cache.Cache; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventRegistryCenter; public class XlsxHandlerFactory { public static List buildCellHandlers(AnalysisContext analysisContext, - AnalysisEventRegistryCenter registerCenter, SharedStringsTable sst) { + AnalysisEventRegistryCenter registerCenter, Cache cahe) { List result = new ArrayList(); result.add(new CountRowCellHandler(analysisContext)); - DefaultCellHandler defaultCellHandler = buildXlsxRowResultHandler(analysisContext, registerCenter, sst); + DefaultCellHandler defaultCellHandler = buildXlsxRowResultHandler(analysisContext, registerCenter, cahe); result.add(defaultCellHandler); result.add(new ProcessResultCellHandler(registerCenter, defaultCellHandler)); return result; } private static DefaultCellHandler buildXlsxRowResultHandler(AnalysisContext analysisContext, - AnalysisEventRegistryCenter registerCenter, SharedStringsTable sst) { - return new DefaultCellHandler(analysisContext, registerCenter, sst); + AnalysisEventRegistryCenter registerCenter, Cache cahe) { + return new DefaultCellHandler(analysisContext, registerCenter, cahe); } } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java index 5a02735a..a2dba82c 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java +++ b/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 org.apache.poi.xssf.model.SharedStringsTable; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; +import com.alibaba.excel.cache.Cache; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventRegistryCenter; @@ -19,12 +19,11 @@ public class XlsxRowHandler extends DefaultHandler { private List cellHandlers; private XlsxRowResultHolder rowResultHolder; - public XlsxRowHandler(AnalysisEventRegistryCenter registerCenter, SharedStringsTable sst, - AnalysisContext analysisContext) { - this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext, registerCenter, sst); + public XlsxRowHandler(AnalysisEventRegistryCenter registerCenter, Cache cache, AnalysisContext analysisContext) { + this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext, registerCenter, cache); for (XlsxCellHandler cellHandler : cellHandlers) { if (cellHandler instanceof XlsxRowResultHolder) { - this.rowResultHolder = (XlsxRowResultHolder) cellHandler; + this.rowResultHolder = (XlsxRowResultHolder)cellHandler; break; } } @@ -55,4 +54,3 @@ public class XlsxRowHandler extends DefaultHandler { } } } - diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java index 34f2480b..a0d8e721 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -1,13 +1,18 @@ package com.alibaba.excel.analysis.v07; -import com.alibaba.excel.analysis.BaseSaxAnalyser; -import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.exception.ExcelAnalysisException; -import com.alibaba.excel.metadata.Sheet; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +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.opc.OPCPackage; +import org.apache.poi.openxml4j.opc.PackagePart; 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.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; 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.XMLReader; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; +import com.alibaba.excel.analysis.BaseSaxAnalyser; +import com.alibaba.excel.cache.Cache; +import com.alibaba.excel.cache.Ehcache; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.exception.ExcelAnalysisException; +import com.alibaba.excel.metadata.Sheet; /** * @@ -31,7 +36,7 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser { private XSSFReader xssfReader; - private SharedStringsTable sharedStringsTable; + private Cache cache; private List sheetSourceList = new ArrayList(); @@ -41,8 +46,27 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser { this.analysisContext = analysisContext; analysisContext.setCurrentRowNum(0); - this.xssfReader = new XSSFReader(OPCPackage.open(analysisContext.getInputStream())); - this.sharedStringsTable = this.xssfReader.getSharedStringsTable(); + OPCPackage pkg = OPCPackage.open(analysisContext.getInputStream()); + this.xssfReader = new XSSFReader(pkg); + ArrayList 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(); WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml); @@ -53,7 +77,6 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser { } this.analysisContext.setUse1904WindowDate(use1904WindowDate); - XSSFReader.SheetIterator ite; sheetSourceList = new ArrayList(); ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); @@ -77,7 +100,7 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser { int i = 0; for (SheetSource sheetSource : sheetSourceList) { i++; - analysisContext.setCurrentSheet(new Sheet(i)); + analysisContext.setCurrentSheet(new Sheet(i, sheetParam.getReadHeadRowNumber())); parseXmlSource(sheetSource.getInputStream()); } } @@ -92,7 +115,7 @@ public class XlsxSaxAnalyser extends BaseSaxAnalyser { saxFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); SAXParser saxParser = saxFactory.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); - ContentHandler handler = new XlsxRowHandler(this, sharedStringsTable, analysisContext); + ContentHandler handler = new XlsxRowHandler(this, cache, analysisContext); xmlReader.setContentHandler(handler); xmlReader.parse(sheetSource); inputStream.close(); diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java index 275d9337..23ac8f96 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java @@ -8,13 +8,12 @@ import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TYPE_TAG; 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.xml.sax.Attributes; import com.alibaba.excel.analysis.v07.XlsxCellHandler; import com.alibaba.excel.analysis.v07.XlsxRowResultHolder; +import com.alibaba.excel.cache.Cache; import com.alibaba.excel.constant.ExcelXmlConstants; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.enums.CellDataTypeEnum; @@ -27,7 +26,7 @@ import com.alibaba.excel.util.StringUtils; public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder { private final AnalysisContext analysisContext; private final AnalysisEventRegistryCenter registerCenter; - private final SharedStringsTable sst; + private final Cache cahe; private String currentTag; private String currentCellIndex; private int curRow; @@ -35,11 +34,10 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder private CellData[] curRowContent = new CellData[20]; private CellData currentCellData; - public DefaultCellHandler(AnalysisContext analysisContext, AnalysisEventRegistryCenter registerCenter, - SharedStringsTable sst) { + public DefaultCellHandler(AnalysisContext analysisContext, AnalysisEventRegistryCenter registerCenter, Cache cahe) { this.analysisContext = analysisContext; this.registerCenter = registerCenter; - this.sst = sst; + this.cahe = cahe; } @Override @@ -86,8 +84,7 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder ensureSize(); // Have to go "sharedStrings.xml" and get it if (currentCellData.getType() == CellDataTypeEnum.STRING) { - RichTextString richTextString = sst.getItemAt(Integer.parseInt(currentCellData.getStringValue())); - currentCellData.setStringValue(richTextString.toString()); + currentCellData.setStringValue(cahe.get(Integer.valueOf(currentCellData.getStringValue()))); } curRowContent[curCol] = currentCellData; } @@ -112,6 +109,9 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder if (StringUtils.isEmpty(currentCellValue)) { return; } + if (currentTag == null) { + return; + } if (CELL_FORMULA_TAG.equals(currentTag)) { currentCellData.setReadFormula(currentCellValue); return; diff --git a/src/main/java/com/alibaba/excel/cache/Cache.java b/src/main/java/com/alibaba/excel/cache/Cache.java new file mode 100644 index 00000000..893796a3 --- /dev/null +++ b/src/main/java/com/alibaba/excel/cache/Cache.java @@ -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(); +} diff --git a/src/main/java/com/alibaba/excel/cache/Ehcache.java b/src/main/java/com/alibaba/excel/cache/Ehcache.java new file mode 100644 index 00000000..05ffb0d5 --- /dev/null +++ b/src/main/java/com/alibaba/excel/cache/Ehcache.java @@ -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> 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() { + + } +} diff --git a/src/main/java/com/alibaba/excel/cache/SharedStringsTableCache.java b/src/main/java/com/alibaba/excel/cache/SharedStringsTableCache.java new file mode 100644 index 00000000..8599478d --- /dev/null +++ b/src/main/java/com/alibaba/excel/cache/SharedStringsTableCache.java @@ -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() { + + } +} diff --git a/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java index 51b3381f..81e71856 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/SheetHolder.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Map; 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.metadata.CellStyle; @@ -22,6 +24,7 @@ import com.alibaba.excel.write.style.column.AbstractHeadColumnWidthStyleStrategy * @author zhuangjiaju */ public class SheetHolder extends AbstractConfigurationSelector { + private static final Logger LOGGER = LoggerFactory.getLogger(SheetHolder.class); /*** * poi sheet @@ -91,6 +94,9 @@ public class SheetHolder extends AbstractConfigurationSelector { } setConverterMap(converterMap); setHasBeenInitializedTable(new HashMap()); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Sheet writeHandlerMap:{}", getWriteHandlerMap()); + } } /** diff --git a/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java index dcc1f598..d30a7605 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/TableHolder.java +++ b/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.Map; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.alibaba.excel.converters.Converter; import com.alibaba.excel.metadata.CellStyle; import com.alibaba.excel.metadata.Table; @@ -19,6 +22,8 @@ import com.alibaba.excel.write.style.RowCellStyleStrategy; * @author zhuangjiaju */ public class TableHolder extends AbstractConfigurationSelector { + private static final Logger LOGGER = LoggerFactory.getLogger(TableHolder.class); + /*** * poi sheet */ @@ -75,6 +80,9 @@ public class TableHolder extends AbstractConfigurationSelector { converterMap.putAll(table.getCustomConverterMap()); } setConverterMap(converterMap); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Table writeHandlerMap:{}", getWriteHandlerMap()); + } } /** diff --git a/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java b/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java index 6b8c8ed4..1a9f2702 100644 --- a/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/metadata/holder/WorkbookHolder.java @@ -8,6 +8,8 @@ import java.util.List; import java.util.Map; 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.DefaultConverterLoader; @@ -20,6 +22,7 @@ import com.alibaba.excel.write.handler.WriteHandler; * @author zhuangjiaju */ public class WorkbookHolder extends AbstractConfigurationSelector { + private static final Logger LOGGER = LoggerFactory.getLogger(WorkbookHolder.class); /*** * poi Workbook */ @@ -95,9 +98,6 @@ public class WorkbookHolder extends AbstractConfigurationSelector { if (workbook.getCustomWriteHandlerList() != null && !workbook.getCustomWriteHandlerList().isEmpty()) { handlerList.addAll(workbook.getCustomWriteHandlerList()); } - // Initialization Annotation - initAnnotationConfig(handlerList); - handlerList.addAll(DefaultWriteHandlerLoader.loadDefaultHandler()); setWriteHandlerMap(sortAndClearUpHandler(handlerList, null)); Map converterMap = DefaultConverterLoader.loadDefaultWriteConverter(); @@ -106,6 +106,9 @@ public class WorkbookHolder extends AbstractConfigurationSelector { } setConverterMap(converterMap); setHasBeenInitializedSheet(new HashMap()); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("Wookbook writeHandlerMap:{}", getWriteHandlerMap()); + } } public Workbook getWorkbook() { diff --git a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java index 9b980646..af478f50 100644 --- a/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/property/ExcelHeadProperty.java @@ -75,6 +75,10 @@ public class ExcelHeadProperty { } initHeadRowNumber(); 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, @@ -136,7 +140,7 @@ public class ExcelHeadProperty { } if (excelProperty == null || excelProperty.index() < 0) { defaultFieldList.add(field); - return; + continue; } if (customFiledMap.containsKey(excelProperty.index())) { throw new ExcelGenerateException("The index of " + customFiledMap.get(excelProperty.index()).getName() @@ -195,6 +199,7 @@ public class ExcelHeadProperty { ExcelContentProperty excelContentProperty = new ExcelContentProperty(); excelContentProperty.setHead(head); + excelContentProperty.setField(field); ContentStyle contentStyle = field.getAnnotation(ContentStyle.class); if (contentStyle == null) { contentStyle = parentContentStyle; diff --git a/src/main/java/com/alibaba/excel/util/POITempFile.java b/src/main/java/com/alibaba/excel/util/POITempFile.java index 6382255f..1cf8662e 100644 --- a/src/main/java/com/alibaba/excel/util/POITempFile.java +++ b/src/main/java/com/alibaba/excel/util/POITempFile.java @@ -1,6 +1,7 @@ package com.alibaba.excel.util; 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 CACHE = "excache"; + /** */ 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); if (tmpDir == null) { throw new RuntimeException( "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()) { syncCreatePOIFilesDirectory(directory); } - + return directory; } /** diff --git a/src/main/java/com/alibaba/excel/util/StringUtils.java b/src/main/java/com/alibaba/excel/util/StringUtils.java index cf583883..b4a58986 100644 --- a/src/main/java/com/alibaba/excel/util/StringUtils.java +++ b/src/main/java/com/alibaba/excel/util/StringUtils.java @@ -31,6 +31,7 @@ import java.util.Properties; import java.util.Set; import java.util.StringTokenizer; import java.util.TimeZone; +import java.util.UUID; import org.apache.commons.codec.binary.CharSequenceUtils; @@ -1312,4 +1313,5 @@ public abstract class StringUtils { return true; } + } diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java index fe0f0540..055804c1 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -1,7 +1,9 @@ package com.alibaba.excel.write; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.poi.ss.usermodel.Cell; 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) { ConfigurationSelector currentConfigurationSelector = context.currentConfigurationSelector(); BeanMap beanMap = BeanMap.create(oneRowData); + Set beanMapHandledSet = new HashSet(); Map headMap = context.currentConfigurationSelector().excelHeadProperty().getHeadMap(); Map contentPropertyMap = context.currentConfigurationSelector().excelHeadProperty().getContentPropertyMap(); @@ -176,32 +179,27 @@ public class ExcelBuilderImpl implements ExcelBuilder { converterAndSet(currentConfigurationSelector, excelContentProperty.getField().getType(), cell, value, excelContentProperty); afterCellCreate(head, cell, relativeRowIndex); - beanMap.remove(name); + beanMapHandledSet.add(name); } // Finish - if (beanMap.isEmpty()) { + if (beanMapHandledSet.size() == beanMap.size()) { return; } if (cellIndex != 0) { cellIndex++; } - for (Object value : beanMap.values()) { + Set> entrySet = beanMap.entrySet(); + for (Map.Entry entry : entrySet) { + if (entry.getValue() == null || beanMapHandledSet.contains(entry.getKey())) { + continue; + } beforeCellCreate(row, null, relativeRowIndex); 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); } } - private void doAddJavaObjectToExcel(List 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) { List handlerList = context.currentConfigurationSelector().writeHandlerMap().get(CellWriteHandler.class); diff --git a/src/test/java/com/alibaba/easyexcel/test/ehcache/EncacheTest.java b/src/test/java/com/alibaba/easyexcel/test/ehcache/EncacheTest.java new file mode 100644 index 00000000..09657112 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/ehcache/EncacheTest.java @@ -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 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); + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/read/large/LargeData07Test.java b/src/test/java/com/alibaba/easyexcel/test/read/large/LargeData07Test.java new file mode 100644 index 00000000..8076411e --- /dev/null +++ b/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); + } + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/read/large/LargeDataListener.java b/src/test/java/com/alibaba/easyexcel/test/read/large/LargeDataListener.java new file mode 100644 index 00000000..e54f8757 --- /dev/null +++ b/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 { + 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) {} + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleData.java b/src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleData.java new file mode 100644 index 00000000..30cb2536 --- /dev/null +++ b/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; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleData07Test.java b/src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleData07Test.java new file mode 100644 index 00000000..3b2fc50f --- /dev/null +++ b/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(); + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleDataListener.java b/src/test/java/com/alibaba/easyexcel/test/read/simple/SimpleDataListener.java new file mode 100644 index 00000000..0e9a5be0 --- /dev/null +++ b/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 { + private static final Logger LOGGER = LoggerFactory.getLogger(SimpleDataListener.class); + + List list = new ArrayList(); + + @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; + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/util/FileUtil.java b/src/test/java/com/alibaba/easyexcel/test/util/FileUtil.java index 27d0a9a2..69e6b1ec 100644 --- a/src/test/java/com/alibaba/easyexcel/test/util/FileUtil.java +++ b/src/test/java/com/alibaba/easyexcel/test/util/FileUtil.java @@ -9,6 +9,10 @@ public class FileUtil { return Thread.currentThread().getContextClassLoader().getResourceAsStream("" + fileName); } + public static InputStream readFile(String fileName) { + return Thread.currentThread().getContextClassLoader().getResourceAsStream("read/" + fileName); + } + public static String getPath() { return FileUtil.class.getResource("/").getPath(); } diff --git a/src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData.java b/src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData.java index 43d8d54f..de6e9092 100644 --- a/src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData.java +++ b/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 lombok.Data; + /** * @author zhuangjiaju */ +@Data public class SimpleData { - @ExcelProperty("字符串") - private String string; - - public String getString() { - return string; - } - - public void setString(String string) { - this.string = string; - } + @ExcelProperty("字符串1") + private String string1; + @ExcelProperty("字符串2") + private String string2; } diff --git a/src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData07Test.java b/src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData07Test.java index 80322349..a905728c 100644 --- a/src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData07Test.java +++ b/src/test/java/com/alibaba/easyexcel/test/wirte/simple/SimpleData07Test.java @@ -40,7 +40,8 @@ public class SimpleData07Test { List list = new ArrayList(); for (int i = 0; i < count; i++) { SimpleData simpleData = new SimpleData(); - simpleData.setString("字符体" + i); + simpleData.setString1("一号字" + i); + simpleData.setString2("二号字" + i); list.add(simpleData); } return list; diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index 602049a9..b7641287 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -7,7 +7,7 @@ ${LOG_PATTERN} - + diff --git a/src/test/resources/read/large/large07.xlsx b/src/test/resources/read/large/large07.xlsx new file mode 100644 index 00000000..a317e71f Binary files /dev/null and b/src/test/resources/read/large/large07.xlsx differ diff --git a/src/test/resources/read/simple/simple07.xlsx b/src/test/resources/read/simple/simple07.xlsx new file mode 100644 index 00000000..d439d2ed Binary files /dev/null and b/src/test/resources/read/simple/simple07.xlsx differ