diff --git a/pom.xml b/pom.xml index e004b36..462d5f9 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.alibaba easyexcel - 1.0.4-SNAPSHOT + 1.0.4 jar easyexcel easyexcel is a excel handle tools written in Java @@ -118,18 +118,7 @@ - - - - - - - - - - - - + org.apache.maven.plugins maven-gpg-plugin diff --git a/src/main/java/com/alibaba/excel/ExcelReader.java b/src/main/java/com/alibaba/excel/ExcelReader.java index e5dfe6f..a15c74d 100644 --- a/src/main/java/com/alibaba/excel/ExcelReader.java +++ b/src/main/java/com/alibaba/excel/ExcelReader.java @@ -1,33 +1,35 @@ package com.alibaba.excel; -import java.io.InputStream; -import java.util.List; - -import com.alibaba.excel.read.ExcelAnalyser; -import com.alibaba.excel.read.ExcelAnalyserImpl; -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.analysis.ExcelAnalyser; +import com.alibaba.excel.analysis.ExcelAnalyserImpl; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.metadata.BaseRowModel; import com.alibaba.excel.metadata.Sheet; +import com.alibaba.excel.parameter.AnalysisParam; import com.alibaba.excel.support.ExcelTypeEnum; +import java.io.InputStream; +import java.util.List; + /** - * Excel解析,thread unsafe + * Excel thread unsafe * * @author jipengfei */ public class ExcelReader { /** - * 解析器 + * analyser */ private ExcelAnalyser analyser = new ExcelAnalyserImpl(); /** - * @param in 文件输入流 - * @param excelTypeEnum excel类型03、07 - * @param customContent 自定义模型可以在{@link AnalysisEventListener#invoke(Object, AnalysisContext) - * }AnalysisContext中获取用于监听者回调使用 - * @param eventListener 用户监听 + * @param in + * @param excelTypeEnum 0307 + * @param customContent {@link AnalysisEventListener#invoke(Object, AnalysisContext) + * }AnalysisContext + * @param eventListener */ public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent, AnalysisEventListener eventListener) { @@ -35,12 +37,22 @@ public class ExcelReader { } /** - * @param in 文件输入流 - * @param excelTypeEnum excel类型03、07 - * @param customContent 自定义模型可以在{@link AnalysisEventListener#invoke(Object, AnalysisContext) - * }AnalysisContext中获取用于监听者回调使用 - * @param eventListener 用户监听 - * @param trim 是否对解析的String做trim()默认true,用于防止 excel中空格引起的装换报错。 + * old 1.1.0 + * @param param + * @param eventListener + */ + @Deprecated + public ExcelReader(AnalysisParam param, AnalysisEventListener eventListener) { + this(param.getIn(), param.getExcelTypeEnum(), param.getCustomContent(), eventListener, true); + } + + /** + * @param in + * @param excelTypeEnum 03 07 + * @param customContent {@link AnalysisEventListener#invoke(Object, AnalysisContext) + * }AnalysisContext + * @param eventListener + * @param trim */ public ExcelReader(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent, AnalysisEventListener eventListener, boolean trim) { @@ -49,39 +61,34 @@ public class ExcelReader { } /** - * 读一个sheet,且没有模型映射 */ public void read() { analyser.analysis(); } /** - * 读指定个sheet,没有模型映射 * - * @param sheet 需要解析的sheet + * @param sheet */ public void read(Sheet sheet) { analyser.analysis(sheet); } + @Deprecated + public void read(Sheet sheet,Class clazz){ + sheet.setClazz(clazz); + analyser.analysis(sheet); + } + /** - * 读取excel中包含哪些sheet * - * @return Sheets + * @return */ public List getSheets() { return analyser.getSheets(); } /** - * 关闭流,删除临时目录文件 - */ - public void finish(){ - analyser.stop(); - } - - /** - * 校验入参 * * @param in * @param excelTypeEnum diff --git a/src/main/java/com/alibaba/excel/ExcelWriter.java b/src/main/java/com/alibaba/excel/ExcelWriter.java index 7ead088..c526e99 100644 --- a/src/main/java/com/alibaba/excel/ExcelWriter.java +++ b/src/main/java/com/alibaba/excel/ExcelWriter.java @@ -1,17 +1,18 @@ package com.alibaba.excel; -import java.io.OutputStream; -import java.util.List; - import com.alibaba.excel.metadata.BaseRowModel; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Table; +import com.alibaba.excel.parameter.GenerateParam; import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.write.ExcelBuilder; import com.alibaba.excel.write.ExcelBuilderImpl; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + /** - * 生成excel,thread unsafe * * @author jipengfei */ @@ -19,80 +20,119 @@ public class ExcelWriter { private ExcelBuilder excelBuilder; - - /** - * 生成EXCEL * - * @param outputStream 文件输出流 - * @param typeEnum 输出文件类型03或07,强烈建议使用07版(可以输出超大excel而不内存溢出) + * */ public ExcelWriter(OutputStream outputStream, ExcelTypeEnum typeEnum) { this(outputStream, typeEnum, true); } + private Class objectClass; + + private String sheetName; + + public ExcelWriter(GenerateParam generateParam) { + + this(generateParam.getOutputStream(), generateParam.getType(), true); + this.objectClass = generateParam.getClazz(); + this.sheetName = generateParam.getSheetName(); + } + /** - * 生成EXCEL * - * @param outputStream 文件输出流 - * @param typeEnum 输出文件类型03或07,强烈建议使用07版(可以输出超大excel而不内存溢出) - * @param needHead 是否需要表头 + * + * @param outputStream + * @param typeEnum */ public ExcelWriter(OutputStream outputStream, ExcelTypeEnum typeEnum, boolean needHead) { excelBuilder = new ExcelBuilderImpl(); - excelBuilder.init(outputStream, typeEnum, needHead); + excelBuilder.init(null, outputStream, typeEnum, needHead); } /** - * 生成多sheet,每个sheet一张表 * - * @param data 一行数据是一个BaseRowModel子类的模型 - * @param sheet data写入某个sheet - * @return this(当前引用) + * @param templateInputStream + * @param outputStream + * @param typeEnum + */ + public ExcelWriter(InputStream templateInputStream, OutputStream outputStream, ExcelTypeEnum typeEnum, boolean needHead) { + excelBuilder = new ExcelBuilderImpl(); + excelBuilder.init(templateInputStream,outputStream, typeEnum, needHead); + } + + /** + * + * @param data + * @param sheet + * @return this */ public ExcelWriter write(List data, Sheet sheet) { excelBuilder.addContent(data, sheet); return this; } + //public Sheet(int sheetNo, int headLineMun, Class clazz, String sheetName, + // List> head) { + // this.sheetNo = sheetNo; + // this.clazz = clazz; + // this.headLineMun = headLineMun; + // this.sheetName = sheetName; + // this.head = head; + //} + + @Deprecated + public ExcelWriter write(List data) { + if (objectClass != null) { + return this.write(data,new Sheet(1,0,objectClass)); + }else { + return this.write0(data,new Sheet(1,0,objectClass)); + + } + } + /** - * 生成多sheet,每个sheet一张表 * - * @param data List代表一行数据 - * @param sheet data写入某个sheet - * @return this(当前引用) + * + * @param data + * @param sheet + * @return this */ - public ExcelWriter write0(List> data, Sheet sheet) { + public ExcelWriter write1(List> data, Sheet sheet) { excelBuilder.addContent(data, sheet); return this; } /** - * 可生成多sheet,每个sheet多张表 * - * @param data type 一个java模型一行数据 - * @param sheet data写入某个sheet - * @param table data写入某个table - * @return this(当前引用) + * @param data + * @param sheet + * @return this */ + public ExcelWriter write0(List> data, Sheet sheet) { + excelBuilder.addContent(data, sheet); + return this; + } + + + public ExcelWriter write(List data, Sheet sheet, Table table) { excelBuilder.addContent(data, sheet, table); return this; } - /** - * 可生成多sheet,每个sheet多张表 - * - * @param data List 代表一行数据 - * @param sheet data写入某个sheet - * @param table data写入某个table - * @return this(当前引用) - */ + public ExcelWriter write0(List> data, Sheet sheet, Table table) { excelBuilder.addContent(data, sheet, table); return this; } + + public ExcelWriter write1(List> data, Sheet sheet, Table table) { + excelBuilder.addContent(data, sheet, table); + return this; + } + public void finish() { excelBuilder.finish(); } diff --git a/src/main/java/com/alibaba/excel/read/BaseSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java similarity index 72% rename from src/main/java/com/alibaba/excel/read/BaseSaxAnalyser.java rename to src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java index e596543..55e906c 100644 --- a/src/main/java/com/alibaba/excel/read/BaseSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/BaseSaxAnalyser.java @@ -1,19 +1,20 @@ -package com.alibaba.excel.read; +package com.alibaba.excel.analysis; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisEventRegisterCenter; +import com.alibaba.excel.event.OneRowAnalysisFinishEvent; +import com.alibaba.excel.metadata.Sheet; +import com.alibaba.excel.support.ExcelTypeEnum; +import com.alibaba.excel.util.TypeUtil; import java.io.InputStream; +import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.event.AnalysisEventListener; -import com.alibaba.excel.read.event.AnalysisEventRegisterCenter; -import com.alibaba.excel.read.event.OneRowAnalysisFinishEvent; -import com.alibaba.excel.metadata.Sheet; -import com.alibaba.excel.support.ExcelTypeEnum; - /** - * 抽象sax模式 excel 解析类 * * @author jipengfei */ @@ -24,7 +25,6 @@ public abstract class BaseSaxAnalyser implements AnalysisEventRegisterCenter, Ex private LinkedHashMap listeners = new LinkedHashMap(); /** - * 开始执行解析 */ protected abstract void execute(); @@ -47,7 +47,6 @@ public abstract class BaseSaxAnalyser implements AnalysisEventRegisterCenter, Ex } /** - * 清空所有监听者 */ public void cleanAllListeners() { listeners = new LinkedHashMap(); @@ -56,7 +55,6 @@ public abstract class BaseSaxAnalyser implements AnalysisEventRegisterCenter, Ex public void notifyListeners(OneRowAnalysisFinishEvent event) { analysisContext.setCurrentRowAnalysisResult(event.getData()); - //表头数据 if (analysisContext.getCurrentRowNum() < analysisContext.getCurrentSheet().getHeadLineMun()) { if (analysisContext.getCurrentRowNum() <= analysisContext.getCurrentSheet().getHeadLineMun() - 1) { analysisContext.buildExcelHeadProperty(null, @@ -64,9 +62,23 @@ public abstract class BaseSaxAnalyser implements AnalysisEventRegisterCenter, Ex } } else { analysisContext.setCurrentRowAnalysisResult(event.getData()); + if (listeners.size() == 1) { + analysisContext.setCurrentRowAnalysisResult(converter((List)event.getData())); + } for (Map.Entry entry : listeners.entrySet()) { entry.getValue().invoke(analysisContext.getCurrentRowAnalysisResult(), analysisContext); } } } + + private List converter(List data) { + List list = new ArrayList(); + if (data != null) { + for (String str : data) { + list.add(TypeUtil.formatFloat(str)); + } + } + return list; + } + } diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java new file mode 100644 index 0000000..aef773d --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyser.java @@ -0,0 +1,30 @@ +package com.alibaba.excel.analysis; + +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.metadata.Sheet; +import com.alibaba.excel.support.ExcelTypeEnum; + +import java.io.InputStream; +import java.util.List; + +/** + * + * @author jipengfei + */ +public interface ExcelAnalyser { + + void init(InputStream inputStream, ExcelTypeEnum excelTypeEnum, Object custom, AnalysisEventListener eventListener, + boolean trim); + + void analysis(Sheet sheetParam); + + + + void analysis(); + + + List getSheets(); + + + +} diff --git a/src/main/java/com/alibaba/excel/read/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java similarity index 67% rename from src/main/java/com/alibaba/excel/read/ExcelAnalyserImpl.java rename to src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java index 9afed07..3283698 100644 --- a/src/main/java/com/alibaba/excel/read/ExcelAnalyserImpl.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java @@ -1,15 +1,18 @@ -package com.alibaba.excel.read; +package com.alibaba.excel.analysis; -import java.io.InputStream; -import java.util.List; - -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.context.AnalysisContextImpl; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.analysis.v03.XlsSaxAnalyser; +import com.alibaba.excel.analysis.v07.XlsxSaxAnalyser; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.context.AnalysisContextImpl; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.metadata.Sheet; -import com.alibaba.excel.read.modelbuild.ModelBuildEventListener; +import com.alibaba.excel.modelbuild.ModelBuildEventListener; import com.alibaba.excel.support.ExcelTypeEnum; +import java.io.InputStream; +import java.util.List; + /** * @author jipengfei */ @@ -21,14 +24,15 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { private BaseSaxAnalyser getSaxAnalyser() { if (saxAnalyser == null) { - if (ExcelTypeEnum.XLS.equals(analysisContext.getExcelType())) { - this.saxAnalyser = new SaxAnalyserV03(analysisContext); - } else { - try { - this.saxAnalyser = new SaxAnalyserV07(analysisContext); - } catch (Exception e) { - e.printStackTrace(); + try { + if (ExcelTypeEnum.XLS.equals(analysisContext.getExcelType())) { + this.saxAnalyser = new XlsSaxAnalyser(analysisContext); + } else { + this.saxAnalyser = new XlsxSaxAnalyser(analysisContext); } + } catch (Exception e) { + throw new ExcelAnalysisException("Analyse excel occur file error fileType " + analysisContext.getExcelType(), + e); } } return this.saxAnalyser; @@ -59,10 +63,6 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { return saxAnalyser.getSheets(); } - public void stop() { - saxAnalyser.stop(); - } - private void appendListeners(BaseSaxAnalyser saxAnalyser) { if (analysisContext.getCurrentSheet() != null && analysisContext.getCurrentSheet().getClazz() != null) { saxAnalyser.appendLister("model_build_listener", new ModelBuildEventListener()); @@ -72,8 +72,4 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { } } - protected void finalize() throws Throwable { - stop(); - } - } diff --git a/src/main/java/com/alibaba/excel/read/SaxAnalyserV03.java b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java similarity index 86% rename from src/main/java/com/alibaba/excel/read/SaxAnalyserV03.java rename to src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java index bc86fe6..bfaa3e9 100644 --- a/src/main/java/com/alibaba/excel/read/SaxAnalyserV03.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -1,60 +1,39 @@ -package com.alibaba.excel.read; +package com.alibaba.excel.analysis.v03; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.event.OneRowAnalysisFinishEvent; -import com.alibaba.excel.read.exception.ExcelAnalysisException; +import com.alibaba.excel.analysis.BaseSaxAnalyser; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.OneRowAnalysisFinishEvent; +import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.metadata.Sheet; - -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.*; import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord; import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord; import org.apache.poi.hssf.model.HSSFFormulaParser; -import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.BlankRecord; -import org.apache.poi.hssf.record.BoolErrRecord; -import org.apache.poi.hssf.record.BoundSheetRecord; -import org.apache.poi.hssf.record.FormulaRecord; -import org.apache.poi.hssf.record.LabelRecord; -import org.apache.poi.hssf.record.LabelSSTRecord; -import org.apache.poi.hssf.record.NoteRecord; -import org.apache.poi.hssf.record.NumberRecord; -import org.apache.poi.hssf.record.RKRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.SSTRecord; -import org.apache.poi.hssf.record.StringRecord; +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.List; + /** - * 2003版Excel解析器 * * @author jipengfei */ -public class SaxAnalyserV03 extends BaseSaxAnalyser implements HSSFListener { +public class XlsSaxAnalyser extends BaseSaxAnalyser implements HSSFListener { private boolean analyAllSheet = false; - public SaxAnalyserV03(AnalysisContext context) { + public XlsSaxAnalyser(AnalysisContext context) throws IOException { this.analysisContext = context; this.records = new ArrayList(); if (analysisContext.getCurrentSheet() == null) { this.analyAllSheet = true; } context.setCurrentRowNum(0); - try { - this.fs = new POIFSFileSystem(analysisContext.getInputStream()); - } catch (IOException e) { - throw new ExcelAnalysisException(e); - } + this.fs = new POIFSFileSystem(analysisContext.getInputStream()); + } public List getSheets() { @@ -62,10 +41,6 @@ public class SaxAnalyserV03 extends BaseSaxAnalyser implements HSSFListener { return sheets; } - public void stop() { - - } - @Override public void execute() { init(); diff --git a/src/main/java/com/alibaba/excel/read/v07/RowHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java similarity index 77% rename from src/main/java/com/alibaba/excel/read/v07/RowHandler.java rename to src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java index 7aaf6c9..12be50f 100644 --- a/src/main/java/com/alibaba/excel/read/v07/RowHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowHandler.java @@ -1,30 +1,26 @@ -package com.alibaba.excel.read.v07; - -import java.util.Arrays; -import java.util.List; +package com.alibaba.excel.analysis.v07; import com.alibaba.excel.annotation.FieldType; -import com.alibaba.excel.util.ExcelXmlConstants; -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.event.AnalysisEventRegisterCenter; -import com.alibaba.excel.read.event.OneRowAnalysisFinishEvent; +import com.alibaba.excel.constant.ExcelXmlConstants; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventRegisterCenter; +import com.alibaba.excel.event.OneRowAnalysisFinishEvent; import com.alibaba.excel.util.PositionUtils; - import org.apache.poi.xssf.model.SharedStringsTable; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -import static com.alibaba.excel.util.ExcelXmlConstants.CELL_VALUE_TAG; -import static com.alibaba.excel.util.ExcelXmlConstants.CELL_VALUE_TAG_1; -import static com.alibaba.excel.util.ExcelXmlConstants.DIMENSION; -import static com.alibaba.excel.util.ExcelXmlConstants.DIMENSION_REF; -import static com.alibaba.excel.util.ExcelXmlConstants.ROW_TAG; +import java.util.Arrays; + +import static com.alibaba.excel.constant.ExcelXmlConstants.*; /** * @author jipengfei + * @date 2017/08/23 */ -public class RowHandler extends DefaultHandler { +public class XlsxRowHandler extends DefaultHandler { private String currentCellIndex; @@ -44,14 +40,11 @@ public class RowHandler extends DefaultHandler { private AnalysisEventRegisterCenter registerCenter; - private List sharedStringList; - - public RowHandler(AnalysisEventRegisterCenter registerCenter, SharedStringsTable sst, - AnalysisContext analysisContext, List sharedStringList) { + public XlsxRowHandler(AnalysisEventRegisterCenter registerCenter, SharedStringsTable sst, + AnalysisContext analysisContext) { this.registerCenter = registerCenter; this.analysisContext = analysisContext; this.sst = sst; - this.sharedStringList = sharedStringList; } @@ -107,11 +100,7 @@ public class RowHandler extends DefaultHandler { switch (currentCellType) { case STRING: int idx = Integer.parseInt(currentCellValue); - if (idx < sharedStringList.size()) { - currentCellValue = sharedStringList.get(idx); - } else { - currentCellValue = ""; - } + currentCellValue = new XSSFRichTextString(sst.getEntryAt(idx)).toString(); currentCellType = FieldType.EMPTY; break; //case DATE: @@ -141,6 +130,7 @@ public class RowHandler extends DefaultHandler { } + private void setTotalRowCount(String name, Attributes attributes) { if (DIMENSION.equals(name)) { String d = attributes.getValue(DIMENSION_REF); diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java new file mode 100644 index 0000000..5d761f4 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -0,0 +1,144 @@ +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 org.apache.poi.openxml4j.exceptions.OpenXML4JException; +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.xssf.eventusermodel.XSSFReader; +import org.apache.poi.xssf.model.SharedStringsTable; +import org.apache.xmlbeans.XmlException; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument; +import org.xml.sax.ContentHandler; +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; + +import 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; + +/** + * @author jipengfei + * @date 2017/08/27 + */ +public class XlsxSaxAnalyser extends BaseSaxAnalyser { + + private XSSFReader xssfReader; + + private SharedStringsTable sharedStringsTable; + + private List sheetSourceList = new ArrayList(); + + private boolean use1904WindowDate = false; + + public XlsxSaxAnalyser(AnalysisContext analysisContext) throws IOException, OpenXML4JException, XmlException { + this.analysisContext = analysisContext; + + analysisContext.setCurrentRowNum(0); + this.xssfReader = new XSSFReader(OPCPackage.open(analysisContext.getInputStream())); + this.sharedStringsTable = this.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); + + + XSSFReader.SheetIterator ite; + sheetSourceList = new ArrayList(); + ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); + while (ite.hasNext()) { + InputStream inputStream = ite.next(); + String sheetName = ite.getSheetName(); + SheetSource sheetSource = new SheetSource(sheetName, inputStream); + sheetSourceList.add(sheetSource); + } + + } + + protected void execute() { + Sheet sheetParam = analysisContext.getCurrentSheet(); + if (sheetParam != null && sheetParam.getSheetNo() > 0 && sheetSourceList.size() >= sheetParam.getSheetNo()) { + InputStream sheetInputStream = sheetSourceList.get(sheetParam.getSheetNo() - 1).getInputStream(); + parseXmlSource(sheetInputStream); + + } else { + int i = 0; + for (SheetSource sheetSource : sheetSourceList) { + i++; + analysisContext.setCurrentSheet(new Sheet(i)); + parseXmlSource(sheetSource.getInputStream()); + } + } + } + + private void parseXmlSource(InputStream inputStream) { + InputSource sheetSource = new InputSource(inputStream); + 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 XlsxRowHandler(this, sharedStringsTable, analysisContext); + xmlReader.setContentHandler(handler); + xmlReader.parse(sheetSource); + inputStream.close(); + } catch (Exception e) { + throw new ExcelAnalysisException(e); + } + } + + public List getSheets() { + List sheets = new ArrayList(); + int i = 1; + for (SheetSource sheetSource : sheetSourceList) { + Sheet sheet = new Sheet(i, 0); + sheet.setSheetName(sheetSource.getSheetName()); + i++; + sheets.add(sheet); + } + + return sheets; + } + + class SheetSource { + + private String sheetName; + + private InputStream inputStream; + + public SheetSource(String sheetName, InputStream inputStream) { + this.sheetName = sheetName; + this.inputStream = inputStream; + } + + public String getSheetName() { + return sheetName; + } + + public void setSheetName(String sheetName) { + this.sheetName = sheetName; + } + + public InputStream getInputStream() { + return inputStream; + } + + public void setInputStream(InputStream inputStream) { + this.inputStream = inputStream; + } + } +} diff --git a/src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java b/src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java index 3b3ee81..6a53efa 100644 --- a/src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java +++ b/src/main/java/com/alibaba/excel/annotation/ExcelColumnNum.java @@ -1,17 +1,13 @@ package com.alibaba.excel.annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; /** * Created by jipengfei on 17/3/19. * Field column num at excel head * * @author jipengfei - * + * @date 2017/03/19 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @@ -20,16 +16,16 @@ public @interface ExcelColumnNum { /** * col num - * @return col num + * @return */ int value(); /** * - * Default @see com.alibaba.TypeUtil + * Default @see com.alibaba.excel.util.TypeUtil * if default is not meet you can set format * - * @return format + * @return */ String format() default ""; } diff --git a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java index 2d2d355..cc3afc8 100644 --- a/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java +++ b/src/main/java/com/alibaba/excel/annotation/ExcelProperty.java @@ -1,10 +1,6 @@ package com.alibaba.excel.annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; /** * @author jipengfei @@ -15,24 +11,22 @@ import java.lang.annotation.Target; public @interface ExcelProperty { /** - * 某列表头值 - * @return 表头值 + * @return */ String[] value() default {""}; /** - * 列顺序,越小越靠前 - * @return 列顺序 + * @return */ int index() default 99999; /** * - * default @see com.alibaba.TypeUtil + * default @see com.alibaba.excel.util.TypeUtil * if default is not meet you can set format * - * @return 日期格式化 + * @return */ String format() default ""; } diff --git a/src/main/java/com/alibaba/excel/annotation/FieldType.java b/src/main/java/com/alibaba/excel/annotation/FieldType.java index 8d2e57b..e5dc48d 100644 --- a/src/main/java/com/alibaba/excel/annotation/FieldType.java +++ b/src/main/java/com/alibaba/excel/annotation/FieldType.java @@ -3,7 +3,7 @@ package com.alibaba.excel.annotation; /** * * @author jipengfei - * + * @date 2017/03/15 */ public enum FieldType { diff --git a/src/main/java/com/alibaba/excel/util/ExcelXmlConstants.java b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java similarity index 88% rename from src/main/java/com/alibaba/excel/util/ExcelXmlConstants.java rename to src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java index b9c42af..8403f9e 100644 --- a/src/main/java/com/alibaba/excel/util/ExcelXmlConstants.java +++ b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java @@ -1,8 +1,8 @@ -package com.alibaba.excel.util; +package com.alibaba.excel.constant; /** * @author jipengfei - * + * @date 2017/08/24 */ public class ExcelXmlConstants { public static final String DIMENSION = "dimension"; diff --git a/src/main/java/com/alibaba/excel/read/context/AnalysisContext.java b/src/main/java/com/alibaba/excel/context/AnalysisContext.java similarity index 58% rename from src/main/java/com/alibaba/excel/read/context/AnalysisContext.java rename to src/main/java/com/alibaba/excel/context/AnalysisContext.java index 49b1bee..2f6b8ac 100644 --- a/src/main/java/com/alibaba/excel/read/context/AnalysisContext.java +++ b/src/main/java/com/alibaba/excel/context/AnalysisContext.java @@ -1,140 +1,123 @@ -package com.alibaba.excel.read.context; +package com.alibaba.excel.context; -import java.io.InputStream; -import java.util.List; - -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.BaseRowModel; import com.alibaba.excel.metadata.ExcelHeadProperty; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; +import java.io.InputStream; +import java.util.List; + /** - * 解析文件上下文 * * @author jipengfei */ public interface AnalysisContext { /** - * 返回用户自定义数据 * - * @return 返回用户自定义数据 */ Object getCustom(); /** - * 返回当前Sheet * - * @return current read sheet + * @return current analysis sheet */ Sheet getCurrentSheet(); /** - * 设置当前解析的Sheet * - * @param sheet 入参 + * @param sheet */ void setCurrentSheet(Sheet sheet); /** - * 返回解析的Excel类型 * * @return excel type */ ExcelTypeEnum getExcelType(); /** - * 返回输入IO * * @return file io */ InputStream getInputStream(); /** - * 获取当前监听者 * - * @return listener + * @return */ AnalysisEventListener getEventListener(); /** - * 获取当前行数 * - * @return 当前行 + * @return */ Integer getCurrentRowNum(); /** - * 设置当前行数 * - * @param row 设置行号 + * @param row */ void setCurrentRowNum(Integer row); /** - * 返回当前sheet共有多少行数据,仅限07版excel * - * @return 总行数 + * @return */ - @Deprecated Integer getTotalCount(); /** - * 设置总条数 * - * @param totalCount 总行数 + * @param totalCount */ void setTotalCount(Integer totalCount); /** - * 返回表头信息 * - * @return 表头信息 + * @return */ ExcelHeadProperty getExcelHeadProperty(); /** - * 构建 ExcelHeadProperty * - * @param clazz 自定义model - * @param headOneRow 表头内容 + * @param clazz + * @param headOneRow */ void buildExcelHeadProperty(Class clazz, List headOneRow); /** - * 是否trim() * - * @return 是否trim + * @return */ boolean trim(); /** * - * @param result 解析结果 */ void setCurrentRowAnalysisResult(Object result); + /** * - * @return 当前行解析结果 */ Object getCurrentRowAnalysisResult(); /** - * 中断 + * */ void interrupt(); /** * - * @return 是否use1904WindowDate + * @return */ boolean use1904WindowDate(); /** * - * @param use1904WindowDate 是否use1904WindowDate + * @param use1904WindowDate */ void setUse1904WindowDate(boolean use1904WindowDate); } diff --git a/src/main/java/com/alibaba/excel/read/context/AnalysisContextImpl.java b/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java similarity index 94% rename from src/main/java/com/alibaba/excel/read/context/AnalysisContextImpl.java rename to src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java index 7da12e5..43dae67 100644 --- a/src/main/java/com/alibaba/excel/read/context/AnalysisContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java @@ -1,18 +1,17 @@ -package com.alibaba.excel.read.context; +package com.alibaba.excel.context; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -import com.alibaba.excel.read.event.AnalysisEventListener; -import com.alibaba.excel.read.exception.ExcelAnalysisException; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.metadata.BaseRowModel; import com.alibaba.excel.metadata.ExcelHeadProperty; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + /** - * 解析Excel上线文默认实现 * * @author jipengfei */ diff --git a/src/main/java/com/alibaba/excel/write/context/GenerateContext.java b/src/main/java/com/alibaba/excel/context/GenerateContext.java similarity index 65% rename from src/main/java/com/alibaba/excel/write/context/GenerateContext.java rename to src/main/java/com/alibaba/excel/context/GenerateContext.java index 3ac0759..5d74b2d 100644 --- a/src/main/java/com/alibaba/excel/write/context/GenerateContext.java +++ b/src/main/java/com/alibaba/excel/context/GenerateContext.java @@ -1,14 +1,13 @@ -package com.alibaba.excel.write.context; - -import java.io.OutputStream; +package com.alibaba.excel.context; import com.alibaba.excel.metadata.ExcelHeadProperty; import com.alibaba.excel.metadata.Table; - import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; +import java.io.OutputStream; + /** * @author jipengfei */ @@ -16,58 +15,50 @@ public interface GenerateContext { /** - * 返回当前sheet - * @return current read sheet + * @return current analysis sheet */ Sheet getCurrentSheet(); /** * - * 获取表头样式 - * @return 当前行表头样式 + * @return */ CellStyle getCurrentHeadCellStyle(); /** - * 获取内容样式 - * @return 当前行内容样式 + * @return */ CellStyle getCurrentContentStyle(); /** - * 返回WorkBook - * @return 返回文件book + * @return */ Workbook getWorkbook(); /** - * 返回Io流 - * @return 返回out流 + * @return */ OutputStream getOutputStream(); /** - * 构建一个sheet * @param sheet */ void buildCurrentSheet(com.alibaba.excel.metadata.Sheet sheet); /** - * 构建一个Table * @param table */ void buildTable(Table table); /** - * 返回表头信息 - * @return 返回表头信息 + * @return */ ExcelHeadProperty getExcelHeadProperty(); /** * - * @return 是否需要表头 + * @return */ boolean needHead(); } diff --git a/src/main/java/com/alibaba/excel/write/context/GenerateContextImpl.java b/src/main/java/com/alibaba/excel/context/GenerateContextImpl.java similarity index 82% rename from src/main/java/com/alibaba/excel/write/context/GenerateContextImpl.java rename to src/main/java/com/alibaba/excel/context/GenerateContextImpl.java index 9e0ab62..9c2f171 100644 --- a/src/main/java/com/alibaba/excel/write/context/GenerateContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/GenerateContextImpl.java @@ -1,34 +1,26 @@ -package com.alibaba.excel.write.context; +package com.alibaba.excel.context; -import java.io.OutputStream; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import com.alibaba.excel.metadata.BaseRowModel; +import com.alibaba.excel.metadata.*; import com.alibaba.excel.metadata.CellRange; -import com.alibaba.excel.metadata.ExcelHeadProperty; import com.alibaba.excel.metadata.Table; -import com.alibaba.excel.metadata.TableStyle; import com.alibaba.excel.support.ExcelTypeEnum; - import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.BorderStyle; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.HorizontalAlignment; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.VerticalAlignment; -import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; /** - * 生成Excel上下文 * * @author jipengfei */ @@ -58,11 +50,20 @@ public class GenerateContextImpl implements GenerateContext { private boolean needHead = true; - public GenerateContextImpl(OutputStream out, ExcelTypeEnum excelType, boolean needHead) { + public GenerateContextImpl(InputStream templateInputStream, OutputStream out, ExcelTypeEnum excelType, + boolean needHead) throws IOException { if (ExcelTypeEnum.XLS.equals(excelType)) { - this.workbook = new HSSFWorkbook(); + if(templateInputStream == null) { + this.workbook = new HSSFWorkbook(); + }else { + this.workbook = new HSSFWorkbook(new POIFSFileSystem(templateInputStream)); + } } else { - this.workbook = new SXSSFWorkbook(500); + if(templateInputStream == null) { + this.workbook = new SXSSFWorkbook(500); + }else { + this.workbook = new SXSSFWorkbook(new XSSFWorkbook(templateInputStream)); + } } this.outputStream = out; this.defaultCellStyle = buildDefaultCellStyle(); @@ -91,9 +92,22 @@ public class GenerateContextImpl implements GenerateContext { if (sheetMap.containsKey(sheet.getSheetNo())) { this.currentSheet = sheetMap.get(sheet.getSheetNo()); } else { - this.currentSheet = workbook.createSheet( - sheet.getSheetName() != null ? sheet.getSheetName() : sheet.getSheetNo() + ""); - this.currentSheet.setDefaultColumnWidth(20); + Sheet sheet1 = null; + try { + sheet1 = workbook.getSheetAt(sheet.getSheetNo()); + }catch (Exception e){ + + } + if(sheet1 == null) { + this.currentSheet = workbook.createSheet( + sheet.getSheetName() != null ? sheet.getSheetName() : sheet.getSheetNo() + ""); + this.currentSheet.setDefaultColumnWidth(20); + for (Map.Entry entry : sheet.getColumnWidthMap().entrySet()) { + currentSheet.setColumnWidth(entry.getKey(), entry.getValue()); + } + }else { + this.currentSheet = sheet1; + } sheetMap.put(sheet.getSheetNo(), this.currentSheet); buildHead(sheet.getHead(), sheet.getClazz()); buildTableStyle(sheet.getTableStyle()); diff --git a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java new file mode 100644 index 0000000..2a30da4 --- /dev/null +++ b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java @@ -0,0 +1,26 @@ +package com.alibaba.excel.event; + +import com.alibaba.excel.context.AnalysisContext; + +/** + * + * + * @author jipengfei + */ +public abstract class AnalysisEventListener { + + /** + * when analysis one row trigger invoke function + * + * @param object one row data + * @param context analysis context + */ + public abstract void invoke(T object, AnalysisContext context); + + /** + * if have something to do after all analysis + * + * @param context + */ + public abstract void doAfterAllAnalysed(AnalysisContext context); +} diff --git a/src/main/java/com/alibaba/excel/read/event/AnalysisEventRegisterCenter.java b/src/main/java/com/alibaba/excel/event/AnalysisEventRegisterCenter.java similarity index 55% rename from src/main/java/com/alibaba/excel/read/event/AnalysisEventRegisterCenter.java rename to src/main/java/com/alibaba/excel/event/AnalysisEventRegisterCenter.java index cfa10ae..5c557ec 100644 --- a/src/main/java/com/alibaba/excel/read/event/AnalysisEventRegisterCenter.java +++ b/src/main/java/com/alibaba/excel/event/AnalysisEventRegisterCenter.java @@ -1,29 +1,25 @@ -package com.alibaba.excel.read.event; +package com.alibaba.excel.event; /** - * 管理每个监听者 * * @author jipengfei */ public interface AnalysisEventRegisterCenter { /** - * 增加监听者 - * @param name 名称 - * @param listener 监听器 + * @param name + * @param listener */ void appendLister(String name, AnalysisEventListener listener); /** - * 通知所有监听者 - * @param event 事件 + * @param event */ void notifyListeners(OneRowAnalysisFinishEvent event); /** - * 清空所有监听者 */ void cleanAllListeners(); } diff --git a/src/main/java/com/alibaba/excel/read/event/OneRowAnalysisFinishEvent.java b/src/main/java/com/alibaba/excel/event/OneRowAnalysisFinishEvent.java similarity index 85% rename from src/main/java/com/alibaba/excel/read/event/OneRowAnalysisFinishEvent.java rename to src/main/java/com/alibaba/excel/event/OneRowAnalysisFinishEvent.java index 277472b..a9e9966 100644 --- a/src/main/java/com/alibaba/excel/read/event/OneRowAnalysisFinishEvent.java +++ b/src/main/java/com/alibaba/excel/event/OneRowAnalysisFinishEvent.java @@ -1,7 +1,8 @@ -package com.alibaba.excel.read.event; +package com.alibaba.excel.event; /** * @author jipengfei + * @date 2017/07/21 */ public class OneRowAnalysisFinishEvent { diff --git a/src/main/java/com/alibaba/excel/read/exception/ExcelAnalysisException.java b/src/main/java/com/alibaba/excel/exception/ExcelAnalysisException.java similarity index 84% rename from src/main/java/com/alibaba/excel/read/exception/ExcelAnalysisException.java rename to src/main/java/com/alibaba/excel/exception/ExcelAnalysisException.java index f5150eb..80d7a25 100644 --- a/src/main/java/com/alibaba/excel/read/exception/ExcelAnalysisException.java +++ b/src/main/java/com/alibaba/excel/exception/ExcelAnalysisException.java @@ -1,7 +1,6 @@ -package com.alibaba.excel.read.exception; +package com.alibaba.excel.exception; /** - * Excel解析时候封装的异常 * * @author jipengfei */ diff --git a/src/main/java/com/alibaba/excel/write/exception/ExcelGenerateException.java b/src/main/java/com/alibaba/excel/exception/ExcelGenerateException.java similarity index 83% rename from src/main/java/com/alibaba/excel/write/exception/ExcelGenerateException.java rename to src/main/java/com/alibaba/excel/exception/ExcelGenerateException.java index 69eea6b..b2a4900 100644 --- a/src/main/java/com/alibaba/excel/write/exception/ExcelGenerateException.java +++ b/src/main/java/com/alibaba/excel/exception/ExcelGenerateException.java @@ -1,7 +1,6 @@ -package com.alibaba.excel.write.exception; +package com.alibaba.excel.exception; /** - * 生成Excel封装的异常 * @author jipengfei */ public class ExcelGenerateException extends RuntimeException { @@ -18,4 +17,5 @@ public class ExcelGenerateException extends RuntimeException { public ExcelGenerateException(Throwable cause) { super(cause); } + } diff --git a/src/main/java/com/alibaba/excel/metadata/BaseRowModel.java b/src/main/java/com/alibaba/excel/metadata/BaseRowModel.java index 744bc0a..963b9da 100644 --- a/src/main/java/com/alibaba/excel/metadata/BaseRowModel.java +++ b/src/main/java/com/alibaba/excel/metadata/BaseRowModel.java @@ -1,9 +1,34 @@ package com.alibaba.excel.metadata; +import org.apache.poi.ss.usermodel.CellStyle; + +import java.util.HashMap; +import java.util.Map; + /** * Excel基础模型 * @author jipengfei */ public class BaseRowModel { + /** + * 每列样式 + */ + private Map cellStyleMap = new HashMap(); + + public void addStyle(Integer row, CellStyle cellStyle){ + cellStyleMap.put(row,cellStyle); + } + + public CellStyle getStyle(Integer row){ + return cellStyleMap.get(row); + } + + public Map getCellStyleMap() { + return cellStyleMap; + } + + public void setCellStyleMap(Map cellStyleMap) { + this.cellStyleMap = cellStyleMap; + } } diff --git a/src/main/java/com/alibaba/excel/metadata/CellRange.java b/src/main/java/com/alibaba/excel/metadata/CellRange.java index 6805526..7fac539 100644 --- a/src/main/java/com/alibaba/excel/metadata/CellRange.java +++ b/src/main/java/com/alibaba/excel/metadata/CellRange.java @@ -2,6 +2,7 @@ package com.alibaba.excel.metadata; /** * @author jipengfei + * @date 2017/06/02 */ public class CellRange { diff --git a/src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java b/src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java index d8ece78..8b3ed71 100644 --- a/src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/ExcelColumnProperty.java @@ -6,26 +6,23 @@ import java.util.List; /** * @author jipengfei + * @date 2017/05/31 */ public class ExcelColumnProperty implements Comparable { /** - * 列对应的Class field字段 */ private Field field; /** - * 列顺序 默认很大 */ private int index = 99999; /** - * 该列对应的表头 */ private List head = new ArrayList(); /** - * 日期类型format 如:"yyyy-MM-dd HH:mm:ss" */ private String format; diff --git a/src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java b/src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java index 9a8508e..675c1a4 100644 --- a/src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java +++ b/src/main/java/com/alibaba/excel/metadata/ExcelHeadProperty.java @@ -1,40 +1,31 @@ package com.alibaba.excel.metadata; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import com.alibaba.excel.annotation.ExcelColumnNum; import com.alibaba.excel.annotation.ExcelProperty; +import java.lang.reflect.Field; +import java.util.*; + /** - * 表头信息 * * @author jipengfei + * @date 2017/05/31 */ public class ExcelHeadProperty { /** - * 表头数据对应的Class */ private Class headClazz; /** - * 表头名称 */ private List> head = new ArrayList>(); /** - * Excel每列表头数据 */ private List columnPropertyList = new ArrayList(); /** - * key:Excel列号,value:表头数据 */ private Map excelColumnPropertyMap1 = new HashMap(); @@ -45,7 +36,6 @@ public class ExcelHeadProperty { } /** - * 初始化每列 */ private void initColumnProperties() { if (this.headClazz != null) { @@ -66,7 +56,6 @@ public class ExcelHeadProperty { } /** - * 初始化一列 * * @param f */ @@ -97,9 +86,7 @@ public class ExcelHeadProperty { } /** - * 将表头的一行数据,转换为一列一列形式,组成表头 * - * @param row 表头中的一行数据 */ public void appendOneRow(List row) { @@ -117,10 +104,9 @@ public class ExcelHeadProperty { } /** - * 根据Excel中的列号,获取Excel的表头信息 * - * @param columnNum 列号 - * @return ExcelColumnProperty + * @param columnNum + * @return */ public ExcelColumnProperty getExcelColumnProperty(int columnNum) { ExcelColumnProperty excelColumnProperty = excelColumnPropertyMap1.get(columnNum); @@ -138,18 +124,6 @@ public class ExcelHeadProperty { } /** - * 根据Excel中的列号,获取Excel的表头信息 - * - * @param columnNum 列号 - * @return ExcelColumnProperty - */ - public ExcelColumnProperty getExcelColumnProperty1(int columnNum) { - return excelColumnPropertyMap1.get(columnNum); - - } - - /** - * 判断表头是否相同 * * @param columnHead * @param head diff --git a/src/main/java/com/alibaba/excel/metadata/Font.java b/src/main/java/com/alibaba/excel/metadata/Font.java index f5453e1..3eea50b 100644 --- a/src/main/java/com/alibaba/excel/metadata/Font.java +++ b/src/main/java/com/alibaba/excel/metadata/Font.java @@ -1,24 +1,21 @@ package com.alibaba.excel.metadata; /** - * 字体样式 * * @author jipengfei + * @date 2017/05/24 */ public class Font { /** - * 字体名称,如:宋体、黑体 */ private String fontName; /** - * 字体大小 */ private short fontHeightInPoints; /** - * 是否加粗 */ private boolean bold; diff --git a/src/main/java/com/alibaba/excel/metadata/Sheet.java b/src/main/java/com/alibaba/excel/metadata/Sheet.java index 2db84a0..f282800 100644 --- a/src/main/java/com/alibaba/excel/metadata/Sheet.java +++ b/src/main/java/com/alibaba/excel/metadata/Sheet.java @@ -1,36 +1,32 @@ package com.alibaba.excel.metadata; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** - * Sheet参数 * * @author jipengfei */ public class Sheet { /** - * 表头行数 */ private int headLineMun; /** - * sheet序号 从0开始 */ private int sheetNo; /** - * 名称 可不填 */ private String sheetName; /** - * 对用的表头模型 */ private Class clazz; /** - * 对用的表头层级树,用于clazz不确定时候,动态生成表头 */ private List> head; @@ -39,6 +35,22 @@ public class Sheet { */ private TableStyle tableStyle; + /** + * column with + */ + private Map columnWidthMap = new HashMap(); + + /** + * + */ + private Boolean autoWidth = Boolean.FALSE; + + /** + * + */ + private int startRow = -1; + + public Sheet(int sheetNo) { this.sheetNo = sheetNo; } @@ -114,6 +126,16 @@ public class Sheet { this.tableStyle = tableStyle; } + + + public Map getColumnWidthMap() { + return columnWidthMap; + } + + public void setColumnWidthMap(Map columnWidthMap) { + this.columnWidthMap = columnWidthMap; + } + @Override public String toString() { return "Sheet{" + @@ -123,6 +145,23 @@ public class Sheet { ", clazz=" + clazz + ", head=" + head + ", tableStyle=" + tableStyle + + ", columnWidthMap=" + columnWidthMap + '}'; } + + public Boolean getAutoWidth() { + return autoWidth; + } + + public void setAutoWidth(Boolean autoWidth) { + this.autoWidth = autoWidth; + } + + public int getStartRow() { + return startRow; + } + + public void setStartRow(int startRow) { + this.startRow = startRow; + } } diff --git a/src/main/java/com/alibaba/excel/metadata/Table.java b/src/main/java/com/alibaba/excel/metadata/Table.java index a2f9290..c4b3a8e 100644 --- a/src/main/java/com/alibaba/excel/metadata/Table.java +++ b/src/main/java/com/alibaba/excel/metadata/Table.java @@ -4,25 +4,22 @@ import java.util.List; /** * @author jipengfei + * @date 2017/05/16 */ public class Table { /** - * 对用的表头模型 */ private Class clazz; /** - * 对用的表头层级树,用于clazz不确定时候,动态生成表头 */ private List> head; /** - * 第几个table,用于和其他table区分 */ private Integer tableNo; /** - * 支持表格简单样式自定义 */ private TableStyle tableStyle; diff --git a/src/main/java/com/alibaba/excel/metadata/TableStyle.java b/src/main/java/com/alibaba/excel/metadata/TableStyle.java index 228019c..6618197 100644 --- a/src/main/java/com/alibaba/excel/metadata/TableStyle.java +++ b/src/main/java/com/alibaba/excel/metadata/TableStyle.java @@ -4,6 +4,7 @@ import org.apache.poi.ss.usermodel.IndexedColors; /** * @author jipengfei + * @date 2017/05/24 */ public class TableStyle { diff --git a/src/main/java/com/alibaba/excel/read/modelbuild/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/modelbuild/ModelBuildEventListener.java similarity index 87% rename from src/main/java/com/alibaba/excel/read/modelbuild/ModelBuildEventListener.java rename to src/main/java/com/alibaba/excel/modelbuild/ModelBuildEventListener.java index 3a4b8dc..b998603 100644 --- a/src/main/java/com/alibaba/excel/read/modelbuild/ModelBuildEventListener.java +++ b/src/main/java/com/alibaba/excel/modelbuild/ModelBuildEventListener.java @@ -1,18 +1,16 @@ -package com.alibaba.excel.read.modelbuild; +package com.alibaba.excel.modelbuild; -import java.util.List; - -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.event.AnalysisEventListener; -import com.alibaba.excel.write.exception.ExcelGenerateException; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelGenerateException; import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.ExcelHeadProperty; import com.alibaba.excel.util.TypeUtil; - import org.apache.commons.beanutils.BeanUtils; +import java.util.List; + /** - * 监听POI Sax解析的每行结果 * * @author jipengfei */ @@ -43,7 +41,7 @@ public class ModelBuildEventListener extends AnalysisEventListener { } if (excelHeadProperty != null) { for (int i = 0; i < stringList.size(); i++) { - ExcelColumnProperty columnProperty = excelHeadProperty.getExcelColumnProperty1(i); + ExcelColumnProperty columnProperty = excelHeadProperty.getExcelColumnProperty(i); if (columnProperty != null) { Object value = TypeUtil.convert(stringList.get(i), columnProperty.getField(), columnProperty.getFormat(),context.use1904WindowDate()); diff --git a/src/main/java/com/alibaba/excel/parameter/AnalysisParam.java b/src/main/java/com/alibaba/excel/parameter/AnalysisParam.java new file mode 100644 index 0000000..2f0cc59 --- /dev/null +++ b/src/main/java/com/alibaba/excel/parameter/AnalysisParam.java @@ -0,0 +1,58 @@ +package com.alibaba.excel.parameter; + +import com.alibaba.excel.support.ExcelTypeEnum; + +import java.io.InputStream; + +/** + * + * @author jipengfei + */ +@Deprecated +public class AnalysisParam { + + /** + * @see ExcelTypeEnum + */ + private ExcelTypeEnum excelTypeEnum; + + /** + * file in + */ + private InputStream in; + + /** + * user defined param to listener use + */ + private Object customContent; + + public AnalysisParam(InputStream in, ExcelTypeEnum excelTypeEnum, Object customContent) { + this.in = in; + this.excelTypeEnum = excelTypeEnum; + this.customContent = customContent; + } + + public ExcelTypeEnum getExcelTypeEnum() { + return excelTypeEnum; + } + + public void setExcelTypeEnum(ExcelTypeEnum excelTypeEnum) { + this.excelTypeEnum = excelTypeEnum; + } + + public Object getCustomContent() { + return customContent; + } + + public void setCustomContent(Object customContent) { + this.customContent = customContent; + } + + public InputStream getIn() { + return in; + } + + public void setIn(InputStream in) { + this.in = in; + } +} diff --git a/src/main/java/com/alibaba/excel/parameter/ExcelWriteParam.java b/src/main/java/com/alibaba/excel/parameter/ExcelWriteParam.java new file mode 100644 index 0000000..53e5d50 --- /dev/null +++ b/src/main/java/com/alibaba/excel/parameter/ExcelWriteParam.java @@ -0,0 +1,45 @@ +package com.alibaba.excel.parameter; + +import com.alibaba.excel.support.ExcelTypeEnum; + +import java.io.OutputStream; + +/** + * {@link com.alibaba.excel.ExcelWriter} + * + * @author jipengfei + * @date 2017/05/15 + */ +@Deprecated +public class ExcelWriteParam { + + /** + */ + private OutputStream outputStream; + + /** + */ + private ExcelTypeEnum type; + + public ExcelWriteParam(OutputStream outputStream, ExcelTypeEnum type) { + this.outputStream = outputStream; + this.type = type; + + } + + public OutputStream getOutputStream() { + return outputStream; + } + + public void setOutputStream(OutputStream outputStream) { + this.outputStream = outputStream; + } + + public ExcelTypeEnum getType() { + return type; + } + + public void setType(ExcelTypeEnum type) { + this.type = type; + } +} diff --git a/src/main/java/com/alibaba/excel/parameter/GenerateParam.java b/src/main/java/com/alibaba/excel/parameter/GenerateParam.java new file mode 100644 index 0000000..00910e6 --- /dev/null +++ b/src/main/java/com/alibaba/excel/parameter/GenerateParam.java @@ -0,0 +1,58 @@ +package com.alibaba.excel.parameter; + +import com.alibaba.excel.support.ExcelTypeEnum; + +import java.io.OutputStream; + +/** + * Created by jipengfei on 17/2/19. + */ +public class GenerateParam { + + private OutputStream outputStream; + + private String sheetName; + + private Class clazz; + + private ExcelTypeEnum type; + + public GenerateParam(String sheetName, Class clazz, OutputStream outputStream) { + this.outputStream = outputStream; + this.sheetName = sheetName; + this.clazz = clazz; + } + + public OutputStream getOutputStream() { + return outputStream; + } + + public void setOutputStream(OutputStream outputStream) { + this.outputStream = outputStream; + } + + + public String getSheetName() { + return sheetName; + } + + public void setSheetName(String sheetName) { + this.sheetName = sheetName; + } + + public Class getClazz() { + return clazz; + } + + public void setClazz(Class clazz) { + this.clazz = clazz; + } + + public ExcelTypeEnum getType() { + return type; + } + + public void setType(ExcelTypeEnum type) { + this.type = type; + } +} diff --git a/src/main/java/com/alibaba/excel/read/ExcelAnalyser.java b/src/main/java/com/alibaba/excel/read/ExcelAnalyser.java deleted file mode 100644 index 0f7f17a..0000000 --- a/src/main/java/com/alibaba/excel/read/ExcelAnalyser.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.alibaba.excel.read; - -import java.io.InputStream; -import java.util.List; - -import com.alibaba.excel.read.event.AnalysisEventListener; -import com.alibaba.excel.metadata.Sheet; -import com.alibaba.excel.support.ExcelTypeEnum; - -/** - * Excel解析器 - * - * @author jipengfei - */ -public interface ExcelAnalyser { - - /** - * Excel解析初始化 - * - * @param inputStream 解析为文件流 - * @param excelTypeEnum 解析文件类型 - * @param custom 用户自定义参数用户回调时候可以获取到 - * @param eventListener 解析器需要的监听器 - * @param trim 是否去空格 - */ - void init(InputStream inputStream, ExcelTypeEnum excelTypeEnum, Object custom, AnalysisEventListener eventListener, - boolean trim); - - /** - * 解析指定sheet,{@link AnalysisEventListener}监听中使用 - * - * @param sheetParam 入参 - */ - void analysis(Sheet sheetParam); - - - /** - * - * 默认解析第一个sheet,解析结果在 {@link AnalysisEventListener}监听中使用 - */ - void analysis(); - - /** - * 返回excel中包含哪些sheet - * - * @return 返回所有sheet - */ - List getSheets(); - - /** - * 关闭流 - */ - void stop(); -} diff --git a/src/main/java/com/alibaba/excel/read/SaxAnalyserV07.java b/src/main/java/com/alibaba/excel/read/SaxAnalyserV07.java deleted file mode 100644 index f3251d2..0000000 --- a/src/main/java/com/alibaba/excel/read/SaxAnalyserV07.java +++ /dev/null @@ -1,331 +0,0 @@ -package com.alibaba.excel.read; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; - -import javax.xml.parsers.ParserConfigurationException; - -import com.alibaba.excel.read.v07.RowHandler; -import com.alibaba.excel.read.v07.XmlParserFactory; -import com.alibaba.excel.read.v07.XMLTempFile; -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.exception.ExcelAnalysisException; -import com.alibaba.excel.metadata.Sheet; -import com.alibaba.excel.util.FileUtil; - -import org.apache.poi.xssf.model.SharedStringsTable; -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.Attributes; -import org.xml.sax.ContentHandler; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -/** - * @author jipengfei - */ -public class SaxAnalyserV07 extends BaseSaxAnalyser { - - private SharedStringsTable sharedStringsTable; - - private List sharedStringList = new LinkedList(); - - private List sheetSourceList = new ArrayList(); - - private boolean use1904WindowDate = false; - - private final String path; - - private File tmpFile; - - private String workBookXMLFilePath; - - private String sharedStringXMLFilePath; - - public SaxAnalyserV07(AnalysisContext analysisContext) throws Exception { - this.analysisContext = analysisContext; - this.path = XMLTempFile.createPath(); - this.tmpFile = new File(XMLTempFile.getTmpFilePath(path)); - this.workBookXMLFilePath = XMLTempFile.getWorkBookFilePath(path); - this.sharedStringXMLFilePath = XMLTempFile.getSharedStringFilePath(path); - start(); - } - - @Override - protected void execute() { - try { - Sheet sheet = analysisContext.getCurrentSheet(); - if (!isAnalysisAllSheets(sheet)) { - if (this.sheetSourceList.size() < sheet.getSheetNo() || sheet.getSheetNo() == 0) { - return; - } - InputStream sheetInputStream = this.sheetSourceList.get(sheet.getSheetNo() - 1).getInputStream(); - parseXmlSource(sheetInputStream); - return; - } - int i = 0; - for (SheetSource sheetSource : this.sheetSourceList) { - i++; - this.analysisContext.setCurrentSheet(new Sheet(i)); - parseXmlSource(sheetSource.getInputStream()); - } - - } catch (Exception e) { - stop(); - throw new ExcelAnalysisException(e); - } finally { - - } - - } - - private boolean isAnalysisAllSheets(Sheet sheet) { - if (sheet == null) { - return true; - } - if (sheet.getSheetNo() < 0) { - return true; - } - return false; - } - - public void stop() { - for (SheetSource sheet : sheetSourceList) { - if (sheet.getInputStream() != null) { - try { - sheet.getInputStream().close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - FileUtil.deletefile(path); - } - - private void parseXmlSource(InputStream inputStream) { - try { - ContentHandler handler = new RowHandler(this, this.sharedStringsTable, this.analysisContext, - sharedStringList); - XmlParserFactory.parse(inputStream, handler); - inputStream.close(); - } catch (Exception e) { - try { - inputStream.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - throw new ExcelAnalysisException(e); - } - } - - public List getSheets() { - List sheets = new ArrayList(); - try { - int i = 1; - for (SheetSource sheetSource : this.sheetSourceList) { - Sheet sheet = new Sheet(i, 0); - sheet.setSheetName(sheetSource.getSheetName()); - i++; - sheets.add(sheet); - } - } catch (Exception e) { - stop(); - throw new ExcelAnalysisException(e); - } finally { - - } - - return sheets; - } - - private void start() throws IOException, XmlException, ParserConfigurationException, SAXException { - - createTmpFile(); - - unZipTempFile(); - - initSharedStringsTable(); - - initUse1904WindowDate(); - - initSheetSourceList(); - - } - - private void createTmpFile() throws FileNotFoundException { - FileUtil.writeFile(tmpFile, analysisContext.getInputStream()); - } - - private void unZipTempFile() throws IOException { - FileUtil.doUnZip(path, tmpFile); - } - - private void initSheetSourceList() throws IOException, ParserConfigurationException, SAXException { - this.sheetSourceList = new ArrayList(); - InputStream workbookXml = new FileInputStream(this.workBookXMLFilePath); - XmlParserFactory.parse(workbookXml, new DefaultHandler() { - - private int id = 0; - - @Override - public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { - if (qName.toLowerCase(Locale.US).equals("sheet")) { - String name = null; - id++; - for (int i = 0; i < attrs.getLength(); i++) { - if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("name")) { - name = attrs.getValue(i); - } else if (attrs.getLocalName(i).toLowerCase(Locale.US).equals("r:id")) { - //id = Integer.parseInt(attrs.getValue(i).replaceAll("rId", "")); - try { - InputStream inputStream = new FileInputStream(XMLTempFile.getSheetFilePath(path, id)); - sheetSourceList.add(new SheetSource(id, name, inputStream)); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - } - } - - } - } - - }); - workbookXml.close(); - Collections.sort(sheetSourceList); - } - - private void initUse1904WindowDate() throws IOException, XmlException { - InputStream workbookXml = new FileInputStream(workBookXMLFilePath); - 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); - workbookXml.close(); - } - - private void initSharedStringsTable() throws IOException, ParserConfigurationException, SAXException { - - InputStream inputStream = new FileInputStream(this.sharedStringXMLFilePath); - //this.sharedStringsTable = new SharedStringsTable(); - //this.sharedStringsTable.readFrom(inputStream); - - XmlParserFactory.parse(inputStream, new DefaultHandler() { - //int lastElementPosition = -1; - // - //int lastHandledElementPosition = -1; - - String beforeQName = ""; - - String currentQName = ""; - - @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) { - //if (hasSkippedEmptySharedString()) { - // sharedStringList.add(""); - //} - //if ("t".equals(qName)) { - // lastElementPosition++; - //} - if ("si".equals(qName) || "t".equals(qName)) { - beforeQName = currentQName; - currentQName = qName; - } - - } - //@Override - //public void endElement (String uri, String localName, String qName) - // throws SAXException - //{ - // if ("si".equals(qName) || "t".equals(qName)) { - // beforeQName = qName; - // currentQName = ""; - // } - //} - - //private boolean hasSkippedEmptySharedString() { - // return lastElementPosition > lastHandledElementPosition; - //} - - @Override - public void characters(char[] ch, int start, int length) { - if ("t".equals(currentQName) && ("t".equals(beforeQName))) { - String pre = sharedStringList.get(sharedStringList.size() - 1); - String str = pre + new String(ch, start, length); - sharedStringList.remove(sharedStringList.size() - 1); - sharedStringList.add(str); - }else if ("t".equals(currentQName) && ("si".equals(beforeQName))){ - sharedStringList.add(new String(ch, start, length)); - } - // lastHandledElementPosition++; - - - } - - }); - inputStream.close(); - } - - private class SheetSource implements Comparable { - - private int id; - - private String sheetName; - - private InputStream inputStream; - - public SheetSource(int id, String sheetName, InputStream inputStream) { - this.id = id; - 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; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public int compareTo(SheetSource o) { - if (o.id == this.id) { - return 0; - } else if (o.id > this.id) { - return -1; - } else { - return 1; - } - } - } - -} diff --git a/src/main/java/com/alibaba/excel/read/event/AnalysisEventListener.java b/src/main/java/com/alibaba/excel/read/event/AnalysisEventListener.java deleted file mode 100644 index 6cbfa64..0000000 --- a/src/main/java/com/alibaba/excel/read/event/AnalysisEventListener.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.alibaba.excel.read.event; - -import com.alibaba.excel.read.context.AnalysisContext; - -/** - * 监听Excel解析每行数据 - * 不能单列,每次使用new一个 - * 不能单列,每次使用new一个 - * 不能单列,每次使用new一个 - * 重要事情说三遍 - * - * @author jipengfei - */ -public abstract class AnalysisEventListener { - - /** - * when read one row trigger invoke function - * - * @param object one row data - * @param context read context - */ - public abstract void invoke(T object, AnalysisContext context); - - /** - * if have something to do after all read - * - * @param context context - */ - public abstract void doAfterAllAnalysed(AnalysisContext context); -} diff --git a/src/main/java/com/alibaba/excel/read/v07/XMLTempFile.java b/src/main/java/com/alibaba/excel/read/v07/XMLTempFile.java deleted file mode 100644 index 2811225..0000000 --- a/src/main/java/com/alibaba/excel/read/v07/XMLTempFile.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.alibaba.excel.read.v07; - -import java.io.File; -import java.security.SecureRandom; - -import com.alibaba.excel.util.EasyExcelTempFile; - -/** - * @author jipengfei - * - */ -public class XMLTempFile { - - private static final String TMP_FILE_NAME = "tmp.xlsx"; - - private static final String XL = "xl"; - - private static final String XML_WORKBOOK = "workbook.xml"; - - private static final String XML_SHARED_STRING = "sharedStrings.xml"; - - private static final String SHEET = "sheet"; - - private static final String WORK_SHEETS = "worksheets"; - - private static final SecureRandom random = new SecureRandom(); - - public static String getTmpFilePath(String path) { - return path + File.separator + TMP_FILE_NAME; - } - - public static String createPath() { - return EasyExcelTempFile.getEasyExcelTmpDir() + File.separator + random.nextLong(); - } - - public static String getWorkBookFilePath(String path) { - return path + File.separator + XL + File.separator + XML_WORKBOOK; - } - - public static String getSharedStringFilePath(String path) { - return path + File.separator + XL + File.separator + XML_SHARED_STRING; - } - - public static String getSheetFilePath(String path, int id) { - return path + File.separator + XL + File.separator + WORK_SHEETS + File.separator + SHEET + id - + ".xml"; - } -} diff --git a/src/main/java/com/alibaba/excel/read/v07/XmlParserFactory.java b/src/main/java/com/alibaba/excel/read/v07/XmlParserFactory.java deleted file mode 100644 index 5b4b113..0000000 --- a/src/main/java/com/alibaba/excel/read/v07/XmlParserFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.alibaba.excel.read.v07; - -import java.io.IOException; -import java.io.InputStream; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.xml.sax.ContentHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; - -/** - * @author jipengfei - * - */ -public class XmlParserFactory { - - /** - * xml解析 - * @param inputStream - * @param contentHandler - * @throws ParserConfigurationException - * @throws SAXException - * @throws IOException - */ - public static void parse(InputStream inputStream, ContentHandler contentHandler) - throws ParserConfigurationException, SAXException, IOException { - InputSource sheetSource = new InputSource(inputStream); - SAXParserFactory saxFactory = SAXParserFactory.newInstance(); - //防止XML实体注注入 - 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(); - xmlReader.setContentHandler(contentHandler); - xmlReader.parse(sheetSource); - } -} diff --git a/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java b/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java index 623e530..37a8478 100644 --- a/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java +++ b/src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java @@ -1,7 +1,6 @@ package com.alibaba.excel.support; /** - * 支持读写的数据格式 * * @author jipengfei */ diff --git a/src/main/java/com/alibaba/excel/util/EasyExcelTempFile.java b/src/main/java/com/alibaba/excel/util/EasyExcelTempFile.java deleted file mode 100644 index 05f9113..0000000 --- a/src/main/java/com/alibaba/excel/util/EasyExcelTempFile.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.alibaba.excel.util; - -import java.io.File; - -/** - * 用于修复POI {@link org.apache.poi.util.DefaultTempFileCreationStrategy}在并发写,创建临时目录抛出异常的BUG。 - * - * @author jipengfei - */ -public class EasyExcelTempFile { - - private static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; - - private static final String POIFILES = "poifiles"; - - private static final String EASY_EXCEL_FILES = "easyexcel"; - - /** - * 在创建ExcelBuilder后尝试创建临时目录,避免poi创建时候报错 - */ - public static void createPOIFilesDirectory() { - - 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); - if (!directory.exists()) { - syncCreatePOIFilesDirectory(directory); - } - - } - - /** - * 获取环境变量的配置 - * @return easyexcel临时目录 - */ - public static String getEasyExcelTmpDir() { - 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, EASY_EXCEL_FILES); - if (!directory.exists()) { - syncCreatePOIFilesDirectory(directory); - } - return tmpDir + File.separator + EASY_EXCEL_FILES; - } - - /** - * 如果directory 不存在则创建 - * - * @param directory - */ - private static synchronized void syncCreatePOIFilesDirectory(File directory) { - if (!directory.exists()) { - directory.mkdirs(); - } - } -} diff --git a/src/main/java/com/alibaba/excel/util/FileUtil.java b/src/main/java/com/alibaba/excel/util/FileUtil.java deleted file mode 100644 index 15408e5..0000000 --- a/src/main/java/com/alibaba/excel/util/FileUtil.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.alibaba.excel.util; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Enumeration; - -import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; -import org.apache.commons.compress.archivers.zip.ZipFile; -import org.apache.commons.compress.utils.IOUtils; - -/** - * @author jipengfei - */ -public class FileUtil { - - private static final int BUF = 4096; - - public static boolean writeFile(File file, InputStream stream) throws FileNotFoundException { - OutputStream o = null; - try { - makeDirs(file.getAbsolutePath()); - if (!file.exists()) { - file.createNewFile(); - } - - o = new FileOutputStream(file); - byte data[] = new byte[1024]; - int length = -1; - while ((length = stream.read(data)) != -1) { - o.write(data, 0, length); - } - o.flush(); - return true; - } catch (FileNotFoundException e) { - throw new RuntimeException("FileNotFoundException occurred. ", e); - } catch (IOException e) { - throw new RuntimeException("IOException occurred. ", e); - } finally { - try { - o.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - public static boolean makeDirs(String filePath) { - String folderName = getFolderName(filePath); - if (folderName == null || "".equals(folderName)) { - return false; - } - File folder = new File(folderName); - return (folder.exists() && folder.isDirectory()) ? true : folder.mkdirs(); - } - - public static String getFolderName(String filePath) { - - if (filePath == null || "".equals(filePath)) { - return filePath; - } - int filePosi = filePath.lastIndexOf(File.separator); - return (filePosi == -1) ? "" : filePath.substring(0, filePosi); - } - - /** - * 文件解压 - * @param path - * @param file - * @return - * @throws IOException - */ - public static boolean doUnZip(String path, File file) throws IOException { - ZipFile zipFile = new ZipFile(file, "utf-8"); - Enumeration en = zipFile.getEntries(); - ZipArchiveEntry ze; - while (en.hasMoreElements()) { - ze = en.nextElement(); - if(ze.getName().contains("../")){ - //防止目录穿越 - throw new IllegalStateException("unsecurity zipfile!"); - } - File f = new File(path, ze.getName()); - if (ze.isDirectory()) { - f.mkdirs(); - continue; - } else { f.getParentFile().mkdirs(); } - - InputStream is = zipFile.getInputStream(ze); - OutputStream os = new FileOutputStream(f); - IOUtils.copy(is, os, BUF); - is.close(); - os.close(); - } - zipFile.close(); - return true; - } - - public static void deletefile(String delpath) { - File file = new File(delpath); - // 当且仅当此抽象路径名表示的文件存在且 是一个目录时,返回 true - if (!file.isDirectory()) { - file.delete(); - } else if (file.isDirectory()) { - String[] filelist = file.list(); - for (int i = 0; i < filelist.length; i++) { - File delfile = new File(delpath + File.separator + filelist[i]); - if (!delfile.isDirectory()) { - delfile.delete(); - } else if (delfile.isDirectory()) { - deletefile(delpath + File.separator + filelist[i]); - } - } - file.delete(); - } - } - - -} diff --git a/src/main/java/com/alibaba/excel/util/IndexValueConverter.java b/src/main/java/com/alibaba/excel/util/IndexValueConverter.java index ca7e2e2..dc6f13f 100644 --- a/src/main/java/com/alibaba/excel/util/IndexValueConverter.java +++ b/src/main/java/com/alibaba/excel/util/IndexValueConverter.java @@ -1,71 +1,74 @@ -//package com.alibaba.excel.util; -// -//import java.util.ArrayList; -//import java.util.List; -//import java.util.Stack; -// -//import com.alibaba.excel.metadata.IndexValue; -// -///** -// * 去除空Cell -// * @author jipengfei -// */ -//public class IndexValueConverter { -// public static List converter(List i_list) { -// -// List tem = new ArrayList(); -// -// char[] start = {'@'}; -// int j = 0; -// for (; j < i_list.size(); j++) { -// IndexValue currentIndexValue = i_list.get(j); -// char[] currentIndex = currentIndexValue.getV_index().replaceAll("[0-9]", "").toCharArray(); -// if (j > 0) { -// start = i_list.get(j - 1).getV_index().replaceAll("[0-9]", "").toCharArray(); -// } -// int deep = subtraction26(currentIndex, start); -// int k = 0; -// for (; k < deep - 1; k++) { -// tem.add(null); -// } -// tem.add(currentIndexValue.getV_value()); -// } -// return tem; -// } -// -// private static int subtraction26(char[] currentIndex, char[] beforeIndex) { -// int result = 0; -// -// Stack currentStack = new Stack(); -// Stack beforeStack = new Stack(); -// -// for (int i = 0; i < currentIndex.length; i++) { -// currentStack.push(currentIndex[i]); -// } -// for (int i = 0; i < beforeIndex.length; i++) { -// beforeStack.push(beforeIndex[i]); -// } -// int i = 0; -// char beforeChar = '@'; -// while (!currentStack.isEmpty()) { -// char currentChar = currentStack.pop(); -// if (!beforeStack.isEmpty()) { -// beforeChar = beforeStack.pop(); -// } -// int n = currentChar - beforeChar; -// if(n<0){ -// n = n+26; -// if(!currentStack.isEmpty()){ -// char borrow = currentStack.pop(); -// char newBorrow =(char)(borrow -1); -// currentStack.push(newBorrow); -// } -// } -// result += n * Math.pow(26, i); -// i++; -// beforeChar='@'; -// } -// -// return result; -// } -//} +package com.alibaba.excel.util; + +import com.alibaba.excel.metadata.IndexValue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * 去除空Cell + * @author jipengfei + * @date 2017/04/13 + */ +public class IndexValueConverter { + public static List converter(List i_list) { + + List tem = new ArrayList(); + + char[] start = {'@'}; + int j = 0; + for (; j < i_list.size(); j++) { + IndexValue currentIndexValue = i_list.get(j); + char[] currentIndex = currentIndexValue.getV_index().replaceAll("[0-9]", "").toCharArray(); + if (j > 0) { + start = i_list.get(j - 1).getV_index().replaceAll("[0-9]", "").toCharArray(); + } + int deep = subtraction26(currentIndex, start); + int k = 0; + for (; k < deep - 1; k++) { + tem.add(null); + } + tem.add(currentIndexValue.getV_value()); + } + return tem; + } + + private static int subtraction26(char[] currentIndex, char[] beforeIndex) { + int result = 0; + + Stack currentStack = new Stack(); + Stack berforStack = new Stack(); + + for (int i = 0; i < currentIndex.length; i++) { + currentStack.push(currentIndex[i]); + } + for (int i = 0; i < beforeIndex.length; i++) { + berforStack.push(beforeIndex[i]); + } + int i = 0; + char beforechar = '@'; + while (!currentStack.isEmpty()) { + char currentChar = currentStack.pop(); + if (!berforStack.isEmpty()) { + beforechar = berforStack.pop(); + } + int n = currentChar - beforechar; + if(n<0){ + n = n+26; + if(!currentStack.isEmpty()){ + char borrow = currentStack.pop(); + char newBorrow =(char)(borrow -1); + currentStack.push(newBorrow); + } + } + + + result += n * Math.pow(26, i); + i++; + beforechar='@'; + } + + return result; + } +} diff --git a/src/main/java/com/alibaba/excel/util/POITempFile.java b/src/main/java/com/alibaba/excel/util/POITempFile.java new file mode 100644 index 0000000..c342968 --- /dev/null +++ b/src/main/java/com/alibaba/excel/util/POITempFile.java @@ -0,0 +1,41 @@ +package com.alibaba.excel.util; + +import java.io.File; + +/** + * + * @author jipengfei + * @date 2017/06/22 + */ +public class POITempFile { + + private static final String JAVA_IO_TMPDIR = "java.io.tmpdir"; + + private static final String POIFILES = "poifiles"; + + /** + */ + public static void createPOIFilesDirectory() { + + 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); + if (!directory.exists()) { + syncCreatePOIFilesDirectory(directory); + } + + } + + /** + * + * @param directory + */ + private static synchronized void syncCreatePOIFilesDirectory(File directory) { + if (!directory.exists()) { + directory.mkdirs(); + } + } +} diff --git a/src/main/java/com/alibaba/excel/util/PositionUtils.java b/src/main/java/com/alibaba/excel/util/PositionUtils.java index 37a87dd..f5f084a 100644 --- a/src/main/java/com/alibaba/excel/util/PositionUtils.java +++ b/src/main/java/com/alibaba/excel/util/PositionUtils.java @@ -2,6 +2,7 @@ package com.alibaba.excel.util; /** * @author jipengfei + * @date 2017/08/27 */ public class PositionUtils { diff --git a/src/main/java/com/alibaba/excel/util/TypeUtil.java b/src/main/java/com/alibaba/excel/util/TypeUtil.java index 3ae92f9..dbac004 100644 --- a/src/main/java/com/alibaba/excel/util/TypeUtil.java +++ b/src/main/java/com/alibaba/excel/util/TypeUtil.java @@ -1,5 +1,7 @@ package com.alibaba.excel.util; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; + import java.lang.reflect.Field; import java.math.BigDecimal; import java.text.ParseException; @@ -10,12 +12,9 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.poi.hssf.usermodel.HSSFDateUtil; - /** - * 类型转换工具类 - * * @author jipengfei + * @date 2017/03/15 */ public class TypeUtil { @@ -26,16 +25,35 @@ public class TypeUtil { DATE_FORMAT_LIST.add(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); } + private static int getCountOfChar(String value, char c) { + int n = 0; + if (value == null) { + return 0; + } + char[] chars = value.toCharArray(); + for (char cc : chars) { + if (cc == c) { + n++; + } + } + return n; + } + public static Object convert(String value, Field field, String format, boolean us) { if (isNotEmpty(value)) { if (String.class.equals(field.getType())) { - return value; + return TypeUtil.formatFloat(value); } if (Integer.class.equals(field.getType()) || int.class.equals(field.getType())) { return Integer.parseInt(value); } if (Double.class.equals(field.getType()) || double.class.equals(field.getType())) { - return Double.parseDouble(value); + if (null != format && !"".equals(format)) { + int n = getCountOfChar(value, '0'); + return Double.parseDouble(TypeUtil.formatFloat0(value, n)); + } else { + return Double.parseDouble(TypeUtil.formatFloat(value)); + } } if (Boolean.class.equals(field.getType()) || boolean.class.equals(field.getType())) { String valueLower = value.toLowerCase(); @@ -68,6 +86,27 @@ public class TypeUtil { return null; } + public static Boolean isNum(Field field) { + if (field == null) { + return false; + } + if (Integer.class.equals(field.getType()) || int.class.equals(field.getType())) { + return true; + } + if (Double.class.equals(field.getType()) || double.class.equals(field.getType())) { + return true; + } + + if (Long.class.equals(field.getType()) || long.class.equals(field.getType())) { + return true; + } + + if (BigDecimal.class.equals(field.getType())) { + return true; + } + return false; + } + public static String getDefaultDateString(Date date) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return simpleDateFormat.format(date); @@ -102,7 +141,7 @@ public class TypeUtil { } - private static Boolean isNotEmpty(String value) { + public static Boolean isNotEmpty(String value) { if (value == null) { return false; } @@ -114,7 +153,7 @@ public class TypeUtil { } public static String formatFloat(String value) { - if (value.contains(".")) { + if (null != value && value.contains(".")) { if (isNumeric(value)) { try { BigDecimal decimal = new BigDecimal(value); @@ -127,6 +166,20 @@ public class TypeUtil { return value; } + public static String formatFloat0(String value, int n) { + if (null != value && value.contains(".")) { + if (isNumeric(value)) { + try { + BigDecimal decimal = new BigDecimal(value); + BigDecimal setScale = decimal.setScale(n, BigDecimal.ROUND_HALF_DOWN); + return setScale.toPlainString(); + } catch (Exception e) { + } + } + } + return value; + } + public static final Pattern pattern = Pattern.compile("[\\+\\-]?[\\d]+([\\.][\\d]*)?([Ee][+-]?[\\d]+)?$"); private static boolean isNumeric(String str) { @@ -137,5 +190,13 @@ public class TypeUtil { return true; } + public static String formatDate(Date cellValue, String format) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); + + return simpleDateFormat.format(cellValue); + } + public static void main(String[] args) { + System.out.println(new Date().toString()); + } } diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilder.java b/src/main/java/com/alibaba/excel/write/ExcelBuilder.java index 4385ea8..75acb58 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilder.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilder.java @@ -1,54 +1,31 @@ package com.alibaba.excel.write; -import java.io.OutputStream; -import java.util.List; - import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Table; import com.alibaba.excel.support.ExcelTypeEnum; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; + /** - * Excel构建器 * * @author jipengfei */ public interface ExcelBuilder { - /** - * 初始化Excel构造器 - * - * @param out 文件输出流 - * @param excelType 输出Excel类型,建议使用07版xlsx(性能,内存消耗,cpu使用都远低于03版xls) - * @param needHead 是否需要将表头写入Excel - */ - void init(OutputStream out, ExcelTypeEnum excelType, boolean needHead); - - /** - * 向Excel增加的内容 - * - * @param data 数据格式 - */ - void addContent(List data); - - /** - * 向Excel增加的内容 - * - * @param data 数据格式 - * @param sheetParam 数据写到某个sheet中 - */ + + void init(InputStream templateInputStream, OutputStream out, ExcelTypeEnum excelType, boolean needHead); + + + void addContent(List data, int startRow); + + void addContent(List data, Sheet sheetParam); - /** - * 向Excel增加的内容 - * - * @param data 数据格式 - * @param sheetParam 数据写到某个sheet中 - * @param table 写到某个sheet的某个Table - */ + void addContent(List data, Sheet sheetParam, Table table); - /** - * 关闭资源 - */ + void finish(); } diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java index 55402ab..998078d 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -1,64 +1,81 @@ package com.alibaba.excel.write; -import java.io.IOException; -import java.io.OutputStream; -import java.util.List; - -import com.alibaba.excel.write.context.GenerateContext; -import com.alibaba.excel.write.context.GenerateContextImpl; +import com.alibaba.excel.context.GenerateContext; +import com.alibaba.excel.context.GenerateContextImpl; +import com.alibaba.excel.metadata.BaseRowModel; import com.alibaba.excel.metadata.ExcelColumnProperty; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.metadata.Table; import com.alibaba.excel.support.ExcelTypeEnum; -import com.alibaba.excel.util.EasyExcelTempFile; - -import org.apache.commons.beanutils.BeanUtils; +import com.alibaba.excel.util.POITempFile; +import com.alibaba.excel.util.TypeUtil; +import org.apache.commons.beanutils.BeanUtilsBean; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Date; +import java.util.List; + /** * @author jipengfei + * @date 2017/05/27 */ public class ExcelBuilderImpl implements ExcelBuilder { private GenerateContext context; - public void init(OutputStream out, ExcelTypeEnum excelType, boolean needHead) { - //初始化时候创建临时缓存目录,用于规避POI在并发写bug - EasyExcelTempFile.createPOIFilesDirectory(); + @Override + public void init(InputStream templateInputStream, OutputStream out, ExcelTypeEnum excelType, boolean needHead) { + try { + //初始化时候创建临时缓存目录,用于规避POI在并发写bug + POITempFile.createPOIFilesDirectory(); - context = new GenerateContextImpl(out, excelType, needHead); + context = new GenerateContextImpl(templateInputStream, out, excelType, needHead); + } catch (Exception e) { + throw new RuntimeException(e); + } } - public void addContent(List data) { + @Override + public void addContent(List data, int startRow) { if (data != null && data.size() > 0) { int rowNum = context.getCurrentSheet().getLastRowNum(); if (rowNum == 0) { Row row = context.getCurrentSheet().getRow(0); - if(row ==null) { + if (row == null) { if (context.getExcelHeadProperty() == null || !context.needHead()) { rowNum = -1; } } } + if (rowNum < startRow) { + rowNum = startRow; + } for (int i = 0; i < data.size(); i++) { int n = i + rowNum + 1; + addOneRowOfDataToExcel(data.get(i), n); } } } + @Override public void addContent(List data, Sheet sheetParam) { context.buildCurrentSheet(sheetParam); - addContent(data); + addContent(data, sheetParam.getStartRow()); } + @Override public void addContent(List data, Sheet sheetParam, Table table) { context.buildCurrentSheet(sheetParam); context.buildTable(table); - addContent(data); + addContent(data, sheetParam.getStartRow()); } + @Override public void finish() { try { context.getWorkbook().write(context.getOutputStream()); @@ -67,12 +84,25 @@ public class ExcelBuilderImpl implements ExcelBuilder { } } - private void addOneRowOfDataToExcel(List oneRowData, Row row) { + private void addOneRowOfDataToExcel(List oneRowData, Row row) { if (oneRowData != null && oneRowData.size() > 0) { for (int i = 0; i < oneRowData.size(); i++) { Cell cell = row.createCell(i); cell.setCellStyle(context.getCurrentContentStyle()); - cell.setCellValue(oneRowData.get(i)); + Object cellValue = oneRowData.get(i); + if (cellValue != null) { + if (cellValue instanceof String) { + cell.setCellValue((String)cellValue); + } else if (cellValue instanceof Integer) { + cell.setCellValue(Double.parseDouble(cellValue.toString())); + } else if (cellValue instanceof Double) { + cell.setCellValue((Double)cellValue); + } else if (cellValue instanceof Short) { + cell.setCellValue((Double.parseDouble(cellValue.toString()))); + } + } else { + cell.setCellValue((String)null); + } } } } @@ -81,26 +111,43 @@ public class ExcelBuilderImpl implements ExcelBuilder { int i = 0; for (ExcelColumnProperty excelHeadProperty : context.getExcelHeadProperty().getColumnPropertyList()) { Cell cell = row.createCell(i); - cell.setCellStyle(context.getCurrentContentStyle()); + BaseRowModel baseRowModel = (BaseRowModel)oneRowData; + if (baseRowModel.getStyle(i) != null) { + cell.setCellStyle(baseRowModel.getStyle(i)); + } else { + cell.setCellStyle(context.getCurrentContentStyle()); + } String cellValue = null; try { - cellValue = BeanUtils.getProperty(oneRowData, excelHeadProperty.getField().getName()); + Object value = BeanUtilsBean.getInstance().getPropertyUtils().getNestedProperty(oneRowData, + excelHeadProperty.getField().getName()); + + if (value instanceof Date) { + cellValue = TypeUtil.formatDate((Date)value, excelHeadProperty.getFormat()); + } else { + cellValue = BeanUtilsBean.getInstance().getConvertUtils().convert(value); + } } catch (Exception e) { e.printStackTrace(); } - if (cellValue != null) { - cell.setCellValue(cellValue); + if (TypeUtil.isNotEmpty(cellValue)) { + if (TypeUtil.isNum(excelHeadProperty.getField())) { + cell.setCellValue(Double.parseDouble(cellValue)); + } else { + cell.setCellValue(cellValue); + } } else { cell.setCellValue(""); } i++; } + } private void addOneRowOfDataToExcel(Object oneRowData, int n) { Row row = context.getCurrentSheet().createRow(n); if (oneRowData instanceof List) { - addOneRowOfDataToExcel((List)oneRowData, row); + addOneRowOfDataToExcel((List)oneRowData, row); } else { addOneRowOfDataToExcel(oneRowData, row); } diff --git a/src/test/java/function/listener/ExcelListener.java b/src/test/java/function/listener/ExcelListener.java index 1194597..d89f367 100644 --- a/src/test/java/function/listener/ExcelListener.java +++ b/src/test/java/function/listener/ExcelListener.java @@ -1,18 +1,14 @@ package function.listener; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.ArrayList; -import java.util.List; - import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.Sheet; +import java.io.*; +import java.util.ArrayList; +import java.util.List; + /** * Created by jipengfei on 17/3/14. * 解析监听器, diff --git a/src/test/java/function/read/ExelAllDataTypeTest.java b/src/test/java/function/read/ExelAllDataTypeTest.java index e8b925b..a324044 100644 --- a/src/test/java/function/read/ExelAllDataTypeTest.java +++ b/src/test/java/function/read/ExelAllDataTypeTest.java @@ -1,17 +1,16 @@ package function.read; -import java.io.IOException; -import java.io.InputStream; - import com.alibaba.excel.ExcelReader; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; - import function.listener.ExcelListener; import junit.framework.TestCase; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; + /** * Created by jipengfei on 17/3/15. * diff --git a/src/test/java/function/read/NumTest3.java b/src/test/java/function/read/NumTest3.java index 1b96d2a..b1c8fb0 100644 --- a/src/test/java/function/read/NumTest3.java +++ b/src/test/java/function/read/NumTest3.java @@ -1,17 +1,16 @@ package function.read; -import java.io.IOException; -import java.io.InputStream; - import com.alibaba.excel.ExcelReader; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; - import function.listener.ExcelListener; import function.model.TestModel3; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; + /** * Created by jipengfei on 17/3/19. * diff --git a/src/test/java/function/read/ReadSheets.java b/src/test/java/function/read/ReadSheets.java index 61b081b..d5e05b6 100644 --- a/src/test/java/function/read/ReadSheets.java +++ b/src/test/java/function/read/ReadSheets.java @@ -1,19 +1,18 @@ package function.read; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - import com.alibaba.excel.ExcelReader; import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; - import function.listener.ExcelListener; import org.junit.Test; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + /** * Created by jipengfei on 17/3/22. * diff --git a/src/test/java/function/read/XLSX2007FunctionTest.java b/src/test/java/function/read/XLSX2007FunctionTest.java index 0ef5e0a..8cc66d4 100644 --- a/src/test/java/function/read/XLSX2007FunctionTest.java +++ b/src/test/java/function/read/XLSX2007FunctionTest.java @@ -1,18 +1,17 @@ package function.read; -import java.io.IOException; -import java.io.InputStream; - import com.alibaba.excel.ExcelReader; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; - import function.listener.ExcelListener; import function.model.OneRowHeadExcelModel; import junit.framework.TestCase; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; + /** * Created by jipengfei on 17/2/18. */ diff --git a/src/test/java/function/write/ExcelWriteTest1.java b/src/test/java/function/write/ExcelWriteTest1.java index fc2ab92..25618e3 100644 --- a/src/test/java/function/write/ExcelWriteTest1.java +++ b/src/test/java/function/write/ExcelWriteTest1.java @@ -1,19 +1,10 @@ package function.write; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.ArrayList; -import java.util.List; - import com.alibaba.excel.ExcelReader; import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; - import function.listener.ExcelListener; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; @@ -21,6 +12,10 @@ import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.junit.Test; +import java.io.*; +import java.util.ArrayList; +import java.util.List; + /** * @author jipengfei * @date 2017/08/15 diff --git a/src/test/java/javamodel/IdentificationExcel.java b/src/test/java/javamodel/IdentificationExcel.java new file mode 100755 index 0000000..7abfbd7 --- /dev/null +++ b/src/test/java/javamodel/IdentificationExcel.java @@ -0,0 +1,48 @@ +package javamodel; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.metadata.BaseRowModel; + +public class IdentificationExcel extends BaseRowModel{ + @ExcelProperty(index=0) + private String materialnumber; + + @ExcelProperty(index=17) + private String unit; + + @ExcelProperty(index=42) + private String specproc; + + public String getMaterialnumber() { + return materialnumber; + } + + public void setMaterialnumber(String materialnumber) { + this.materialnumber = materialnumber; + } + + public String getUnit() { + return unit; + } + + public void setUnit(String unit) { + this.unit = unit; + } + + public String getSpecproc() { + return specproc; + } + + public void setSpecproc(String specproc) { + this.specproc = specproc; + } + + @Override + public String toString() { + return "IdentificationExcel{" + + "materialnumber='" + materialnumber + '\'' + + ", unit='" + unit + '\'' + + ", specproc='" + specproc + '\'' + + '}'; + } +} diff --git a/src/test/java/read/v03/XLS2003FunctionTest.java b/src/test/java/read/v03/XLS2003FunctionTest.java index 805c8d9..3770375 100644 --- a/src/test/java/read/v03/XLS2003FunctionTest.java +++ b/src/test/java/read/v03/XLS2003FunctionTest.java @@ -1,18 +1,17 @@ package read.v03; -import java.io.IOException; -import java.io.InputStream; - import com.alibaba.excel.ExcelReader; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; - import function.listener.ExcelListener; import function.model.LoanInfo; import junit.framework.TestCase; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; + /** * Created by jipengfei on 17/2/19. */ diff --git a/src/test/java/read/v07/Read2007MeanWhileWrite.java b/src/test/java/read/v07/Read2007MeanWhileWrite.java index 10ecc61..15285b0 100644 --- a/src/test/java/read/v07/Read2007MeanWhileWrite.java +++ b/src/test/java/read/v07/Read2007MeanWhileWrite.java @@ -1,21 +1,20 @@ package read.v07; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; - import com.alibaba.excel.ExcelReader; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; - import javamodel.ExcelRowJavaModel; import javamodel.ExcelRowJavaModel1; import org.junit.Test; import read.v07.listener.Excel2007NoJavaModelAnalysisListener; import read.v07.listener.Excel2007WithJavaModelAnalysisListener; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + /** * @author jipengfei * @date 2017/08/27 diff --git a/src/test/java/read/v07/Read2007Xlsx.java b/src/test/java/read/v07/Read2007Xlsx.java index fa1958e..672caef 100644 --- a/src/test/java/read/v07/Read2007Xlsx.java +++ b/src/test/java/read/v07/Read2007Xlsx.java @@ -1,21 +1,20 @@ package read.v07; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import com.alibaba.excel.ExcelReader; -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.Sheet; import com.alibaba.excel.support.ExcelTypeEnum; - import javamodel.ExcelRowJavaModel; import javamodel.ExcelRowJavaModel1; +import javamodel.IdentificationExcel; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + /** * @author jipengfei * @date 2017/08/27 @@ -24,7 +23,9 @@ public class Read2007Xlsx { //创建没有自定义模型,没有sheet的解析器,默认解析所有sheet解析结果以List的方式通知监听者 @Test public void noModel() { - InputStream inputStream = getInputStream("1.xlsx"); + InputStream inputStream = getInputStream("需要分批关闭客户名单 2018.8.24.xlsx"); + + final List> ll = new ArrayList>(); try { ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null, new AnalysisEventListener>() { @@ -34,6 +35,7 @@ public class Read2007Xlsx { "当前sheet:" + context.getCurrentSheet().getSheetNo() + " 当前行:" + context.getCurrentRowNum() + " data:" + object); + ll.add(object); } @Override @@ -42,6 +44,21 @@ public class Read2007Xlsx { }); reader.read(); + + String aa= ""; + int i= 0; + for (List strings:ll) { + i++; + aa = aa+","+ strings.get(1)+""; + if(i==25000){ + System.out.println(aa); + aa=""; + i=0; + } + + } + System.out.println(aa); + } catch (Exception e) { e.printStackTrace(); @@ -56,12 +73,12 @@ public class Read2007Xlsx { @Test public void withJavaModel() { - InputStream inputStream = getInputStream("2007WithModel.xlsx"); + InputStream inputStream = getInputStream("2-拆分标识数据库.xlsx"); try { ExcelReader reader = new ExcelReader(inputStream, ExcelTypeEnum.XLSX, null, - new AnalysisEventListener() { + new AnalysisEventListener() { @Override - public void invoke(ExcelRowJavaModel object, AnalysisContext context) { + public void invoke(IdentificationExcel object, AnalysisContext context) { System.out.println( "当前sheet:" + context.getCurrentSheet().getSheetNo() + " 当前行:" + context.getCurrentRowNum() + " data:" + object); @@ -73,7 +90,7 @@ public class Read2007Xlsx { } }); - reader.read(new Sheet(1, 2, ExcelRowJavaModel.class)); + reader.read(new Sheet(1, 1, IdentificationExcel.class)); } catch (Exception e) { e.printStackTrace(); @@ -375,14 +392,7 @@ public class Read2007Xlsx { } - public static void main(String[] args) { - List mm = new ArrayList(); - mm.add(null); - mm.add(null); - mm.add(null); - mm.add(null); - mm.removeAll(Collections.singleton(null)); - System.out.println(mm); - } + + } diff --git a/src/test/java/read/v07/listener/Excel2007NoJavaModelAnalysisListener.java b/src/test/java/read/v07/listener/Excel2007NoJavaModelAnalysisListener.java index c1334d8..85b6e76 100644 --- a/src/test/java/read/v07/listener/Excel2007NoJavaModelAnalysisListener.java +++ b/src/test/java/read/v07/listener/Excel2007NoJavaModelAnalysisListener.java @@ -1,12 +1,12 @@ package read.v07.listener; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; + import java.util.ArrayList; import java.util.List; -import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.event.AnalysisEventListener; - /** * @author jipengfei * @date 2017/08/27 @@ -27,7 +27,7 @@ public class Excel2007NoJavaModelAnalysisListener extends AnalysisEventListener List> ll = new ArrayList>(); ll.add((List)object); System.out.println(object); - excelWriter.write0(ll,context.getCurrentSheet()); + excelWriter.write0(ll, context.getCurrentSheet()); } public void doAfterAllAnalysed(AnalysisContext context) { diff --git a/src/test/java/read/v07/listener/Excel2007WithJavaModelAnalysisListener.java b/src/test/java/read/v07/listener/Excel2007WithJavaModelAnalysisListener.java index eb4fd52..2248a74 100644 --- a/src/test/java/read/v07/listener/Excel2007WithJavaModelAnalysisListener.java +++ b/src/test/java/read/v07/listener/Excel2007WithJavaModelAnalysisListener.java @@ -1,16 +1,15 @@ package read.v07.listener; -import java.util.ArrayList; -import java.util.List; - import com.alibaba.excel.ExcelWriter; -import com.alibaba.excel.read.context.AnalysisContext; -import com.alibaba.excel.read.event.AnalysisEventListener; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.metadata.BaseRowModel; import com.alibaba.excel.metadata.Sheet; - import javamodel.ExcelRowJavaModel; +import java.util.ArrayList; +import java.util.List; + /** * @author jipengfei * @date 2017/08/27 diff --git a/src/test/resources/1.xlsx b/src/test/resources/1.xlsx deleted file mode 100644 index 609646c..0000000 Binary files a/src/test/resources/1.xlsx and /dev/null differ