未验证 提交 b73da424 编写于 作者: 庄家钜's avatar 庄家钜 提交者: GitHub

Merge pull request #1159 from alibaba/2.1.x

2.1.x
......@@ -6,5 +6,5 @@ cache:
before_install:
- chmod +x mvnw
install:
- ./mvnw install -Dgpg.skip -B -V -Dmaven.test.skip=true
- ./mvnw install -B -V -Dmaven.test.skip=true
- ./mvnw javadoc:javadoc
\ No newline at end of file
......@@ -20,6 +20,7 @@ Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都
* [快速使用](https://alibaba-easyexcel.github.io/)
* [关于软件](/abouteasyexcel.md)
* [更新记事](/update.md)
* [贡献代码](https://alibaba-easyexcel.github.io/support/contribute.html)
## 维护者
玉霄、庄家钜、怀宇
......@@ -31,7 +32,7 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja
/**
* 最简单的读
* <p>1. 创建excel对应的实体对象 参照{@link DemoData}
* <p>2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
* <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
* <p>3. 直接读即可
*/
@Test
......@@ -82,7 +83,7 @@ DEMO代码地址:[https://github.com/alibaba/easyexcel/blob/master/src/test/ja
/**
* 文件上传
* <p>1. 创建excel对应的实体对象 参照{@link UploadData}
* <p>2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link UploadDataListener}
* <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link UploadDataListener}
* <p>3. 直接读即可
*/
@PostMapping("upload")
......
......@@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
<version>2.2.0-beta1</version>
<packaging>jar</packaging>
<name>easyexcel</name>
......@@ -15,9 +15,10 @@
<properties>
<!--<gpg.skip>true</gpg.skip>-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.7</jdk.version>
<jdk.version>1.6</jdk.version>
<gpg.skip>true</gpg.skip>
<maven.javadoc.skip>true</maven.javadoc.skip>
</properties>
<scm>
......@@ -66,6 +67,11 @@
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
......@@ -79,7 +85,7 @@
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.7.1</version>
<version>3.4.0</version>
</dependency>
<!--test-->
<dependency>
......@@ -154,6 +160,8 @@
</rulesets>
<excludes>
<exclude>com/alibaba/excel/event/AnalysisEventListener.java</exclude>
<exclude>com/alibaba/excel/metadata/DataFormatter.java</exclude>
<exclude>com/alibaba/excel/util/DateUtils.java</exclude>
</excludes>
</configuration>
<executions>
......@@ -196,7 +204,6 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
......
......@@ -14,15 +14,22 @@ import org.slf4j.LoggerFactory;
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.context.xls.DefaultXlsReadContext;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.context.xlsx.DefaultXlsxReadContext;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelAnalysisStopException;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.NumberDataFormatterUtils;
import com.alibaba.excel.util.StringUtils;
/**
......@@ -41,8 +48,7 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
public ExcelAnalyserImpl(ReadWorkbook readWorkbook) {
try {
analysisContext = new AnalysisContextImpl(readWorkbook);
choiceExcelExecutor();
choiceExcelExecutor(readWorkbook);
} catch (RuntimeException e) {
finish();
throw e;
......@@ -52,29 +58,25 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
}
}
private void choiceExcelExecutor() throws Exception {
ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder();
ExcelTypeEnum excelType = readWorkbookHolder.getExcelType();
if (excelType == null) {
excelReadExecutor = new XlsxSaxAnalyser(analysisContext, null);
return;
}
private void choiceExcelExecutor(ReadWorkbook readWorkbook) throws Exception {
ExcelTypeEnum excelType = ExcelTypeEnum.valueOf(readWorkbook);
switch (excelType) {
case XLS:
POIFSFileSystem poifsFileSystem;
if (readWorkbookHolder.getFile() != null) {
poifsFileSystem = new POIFSFileSystem(readWorkbookHolder.getFile());
if (readWorkbook.getFile() != null) {
poifsFileSystem = new POIFSFileSystem(readWorkbook.getFile());
} else {
poifsFileSystem = new POIFSFileSystem(readWorkbookHolder.getInputStream());
poifsFileSystem = new POIFSFileSystem(readWorkbook.getInputStream());
}
// So in encrypted excel, it looks like XLS but it's actually XLSX
if (poifsFileSystem.getRoot().hasEntry(Decryptor.DEFAULT_POIFS_ENTRY)) {
InputStream decryptedStream = null;
try {
decryptedStream =
DocumentFactoryHelper.getDecryptedStream(poifsFileSystem.getRoot().getFileSystem(),
analysisContext.readWorkbookHolder().getPassword());
excelReadExecutor = new XlsxSaxAnalyser(analysisContext, decryptedStream);
decryptedStream = DocumentFactoryHelper
.getDecryptedStream(poifsFileSystem.getRoot().getFileSystem(), readWorkbook.getPassword());
XlsxReadContext xlsxReadContext = new DefaultXlsxReadContext(readWorkbook, ExcelTypeEnum.XLSX);
analysisContext = xlsxReadContext;
excelReadExecutor = new XlsxSaxAnalyser(xlsxReadContext, decryptedStream);
return;
} finally {
IOUtils.closeQuietly(decryptedStream);
......@@ -83,15 +85,21 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
poifsFileSystem.close();
}
}
if (analysisContext.readWorkbookHolder().getPassword() != null) {
Biff8EncryptionKey.setCurrentUserPassword(analysisContext.readWorkbookHolder().getPassword());
if (readWorkbook.getPassword() != null) {
Biff8EncryptionKey.setCurrentUserPassword(readWorkbook.getPassword());
}
excelReadExecutor = new XlsSaxAnalyser(analysisContext, poifsFileSystem);
XlsReadContext xlsReadContext = new DefaultXlsReadContext(readWorkbook, ExcelTypeEnum.XLS);
xlsReadContext.xlsReadWorkbookHolder().setPoifsFileSystem(poifsFileSystem);
analysisContext = xlsReadContext;
excelReadExecutor = new XlsSaxAnalyser(xlsReadContext);
break;
case XLSX:
excelReadExecutor = new XlsxSaxAnalyser(analysisContext, null);
XlsxReadContext xlsxReadContext = new DefaultXlsxReadContext(readWorkbook, ExcelTypeEnum.XLSX);
analysisContext = xlsxReadContext;
excelReadExecutor = new XlsxSaxAnalyser(xlsxReadContext, null);
break;
default:
break;
}
}
......@@ -101,19 +109,15 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
if (!readAll && CollectionUtils.isEmpty(readSheetList)) {
throw new IllegalArgumentException("Specify at least one read sheet.");
}
analysisContext.readWorkbookHolder().setParameterSheetDataList(readSheetList);
analysisContext.readWorkbookHolder().setReadAll(readAll);
try {
excelReadExecutor.execute(readSheetList, readAll);
excelReadExecutor.execute();
} catch (ExcelAnalysisStopException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Custom stop!");
}
}
// The last sheet is read
if (excelReadExecutor instanceof XlsSaxAnalyser) {
if (analysisContext.readSheetHolder() != null) {
analysisContext.readSheetHolder().notifyAfterAllAnalysed(analysisContext);
}
}
} catch (RuntimeException e) {
finish();
throw e;
......@@ -144,15 +148,17 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
throwable = t;
}
try {
if (readWorkbookHolder.getOpcPackage() != null) {
readWorkbookHolder.getOpcPackage().revert();
if ((readWorkbookHolder instanceof XlsxReadWorkbookHolder)
&& ((XlsxReadWorkbookHolder)readWorkbookHolder).getOpcPackage() != null) {
((XlsxReadWorkbookHolder)readWorkbookHolder).getOpcPackage().revert();
}
} catch (Throwable t) {
throwable = t;
}
try {
if (readWorkbookHolder.getPoifsFileSystem() != null) {
readWorkbookHolder.getPoifsFileSystem().close();
if ((readWorkbookHolder instanceof XlsReadWorkbookHolder)
&& ((XlsReadWorkbookHolder)readWorkbookHolder).getPoifsFileSystem() != null) {
((XlsReadWorkbookHolder)readWorkbookHolder).getPoifsFileSystem().close();
}
} catch (Throwable t) {
throwable = t;
......@@ -175,11 +181,18 @@ public class ExcelAnalyserImpl implements ExcelAnalyser {
clearEncrypt03();
removeThreadLocalCache();
if (throwable != null) {
throw new ExcelAnalysisException("Can not close IO.", throwable);
}
}
private void removeThreadLocalCache() {
NumberDataFormatterUtils.removeThreadLocalCache();
DateUtils.removeThreadLocalCache();
}
private void clearEncrypt03() {
if (StringUtils.isEmpty(analysisContext.readWorkbookHolder().getPassword())
|| !ExcelTypeEnum.XLS.equals(analysisContext.readWorkbookHolder().getExcelType())) {
......
......@@ -20,11 +20,6 @@ public interface ExcelReadExecutor {
/**
* Read the sheet.
*
* @param readSheetList
* Which sheets you need to read.
* @param readAll
* The <code>readSheetList</code> parameter is ignored, and all sheets are read.
*/
void execute(List<ReadSheet> readSheetList, Boolean readAll);
void execute();
}
package com.alibaba.excel.analysis.v03;
import com.alibaba.excel.metadata.CellData;
/**
*
* @author Dan Zheng
*/
public abstract class AbstractXlsRecordHandler implements XlsRecordHandler {
protected int row = -1;
protected int column = -1;
protected CellData cellData;
@Override
public int getRow() {
return row;
}
@Override
public int getColumn() {
return column;
}
@Override
public CellData getCellData() {
return cellData;
}
@Override
public int compareTo(XlsRecordHandler o) {
return this.getOrder() - o.getOrder();
}
}
package com.alibaba.excel.analysis.v03;
/**
* Need to ignore the current handler without reading the current sheet.
*
* @author Jiaju Zhuang
*/
public interface IgnorableXlsRecordHandler extends XlsRecordHandler {}
package com.alibaba.excel.analysis.v03;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
......@@ -10,13 +10,14 @@ 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.record.BOFRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import com.alibaba.excel.analysis.v03.handlers.BofRecordHandler;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.analysis.v03.handlers.BoundSheetRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.read.metadata.ReadSheet;
/**
* In some cases, you need to know the number of sheets in advance and only read the file once in advance.
......@@ -24,24 +25,29 @@ import com.alibaba.excel.read.metadata.ReadSheet;
* @author Jiaju Zhuang
*/
public class XlsListSheetListener implements HSSFListener {
private POIFSFileSystem poifsFileSystem;
private List<ReadSheet> sheetList;
private BofRecordHandler bofRecordHandler;
public XlsListSheetListener(AnalysisContext analysisContext, POIFSFileSystem poifsFileSystem) {
this.poifsFileSystem = poifsFileSystem;
sheetList = new ArrayList<ReadSheet>();
bofRecordHandler = new BofRecordHandler(analysisContext, sheetList, false, false);
bofRecordHandler.init();
bofRecordHandler.init(null, true);
private XlsReadContext xlsReadContext;
private static final Map<Short, XlsRecordHandler> XLS_RECORD_HANDLER_MAP = new HashMap<Short, XlsRecordHandler>();
static {
XLS_RECORD_HANDLER_MAP.put(BOFRecord.sid, new BofRecordHandler());
XLS_RECORD_HANDLER_MAP.put(BoundSheetRecord.sid, new BoundSheetRecordHandler());
}
public XlsListSheetListener(XlsReadContext xlsReadContext) {
this.xlsReadContext = xlsReadContext;
xlsReadContext.xlsReadWorkbookHolder().setNeedReadSheet(Boolean.FALSE);
}
@Override
public void processRecord(Record record) {
bofRecordHandler.processRecord(record);
XlsRecordHandler handler = XLS_RECORD_HANDLER_MAP.get(record.getSid());
if (handler == null) {
return;
}
handler.processRecord(xlsReadContext, record);
}
public List<ReadSheet> getSheetList() {
public void execute() {
MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);
HSSFListener formatListener = new FormatTrackingHSSFListener(listener);
HSSFEventFactory factory = new HSSFEventFactory();
......@@ -49,12 +55,10 @@ public class XlsListSheetListener implements HSSFListener {
EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener =
new EventWorkbookBuilder.SheetRecordCollectingListener(formatListener);
request.addListenerForAllRecords(workbookBuildingListener);
try {
factory.processWorkbookEvents(request, poifsFileSystem);
factory.processWorkbookEvents(request, xlsReadContext.xlsReadWorkbookHolder().getPoifsFileSystem());
} catch (IOException e) {
throw new ExcelAnalysisException(e);
}
return sheetList;
}
}
......@@ -2,60 +2,28 @@ package com.alibaba.excel.analysis.v03;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.context.xls.XlsReadContext;
/**
* Intercepts handle xls reads.
*
* @author Dan Zheng
*/
public interface XlsRecordHandler extends Comparable<XlsRecordHandler> {
public interface XlsRecordHandler {
/**
* Which tags are supported
* Whether to support
*
* @param xlsReadContext
* @param record
* Excel analysis record
* @return Which tags are supported
* @return
*/
boolean support(Record record);
/**
* Initialize
*/
void init();
boolean support(XlsReadContext xlsReadContext, Record record);
/**
* Processing record
*
* @param xlsReadContext
* @param record
*/
void processRecord(Record record);
/**
* Get row
*
* @return Row index
*/
int getRow();
/**
* Get column
*
* @return Column index
*/
int getColumn();
/**
* Get value
*
* @return Excel internal cell data
*/
CellData getCellData();
/**
* Get order
*
* @return Order
*/
int getOrder();
void processRecord(XlsReadContext xlsReadContext, Record record);
}
package com.alibaba.excel.analysis.v03;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
......@@ -16,32 +13,52 @@ import org.apache.poi.hssf.eventusermodel.HSSFRequest;
import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;
import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
import org.apache.poi.hssf.record.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.EOFRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.HyperlinkRecord;
import org.apache.poi.hssf.record.IndexRecord;
import org.apache.poi.hssf.record.LabelRecord;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.MergeCellsRecord;
import org.apache.poi.hssf.record.NoteRecord;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.ObjRecord;
import org.apache.poi.hssf.record.RKRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.record.TextObjectRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.ExcelReadExecutor;
import com.alibaba.excel.analysis.v03.handlers.BlankOrErrorRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.BlankRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.BofRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.BoolErrRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.BoundSheetRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.DummyRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.EofRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.FormulaRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.HyperlinkRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.IndexRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.LabelRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.MissingCellDummyRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.LabelSstRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.MergeCellsRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.NoteRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.NumberRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.ObjRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.RkRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.SstRecordHandler;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.analysis.v03.handlers.StringRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.TextObjectRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.read.listener.event.EachRowAnalysisFinishEvent;
import com.alibaba.excel.exception.ExcelAnalysisStopException;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder;
/**
* /** * A text extractor for Excel files. *
......@@ -60,168 +77,90 @@ import com.alibaba.excel.util.CollectionUtils;
*/
public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor {
private static final Logger LOGGER = LoggerFactory.getLogger(XlsSaxAnalyser.class);
private static final short DUMMY_RECORD_SID = -1;
private XlsReadContext xlsReadContext;
private static final Map<Short, XlsRecordHandler> XLS_RECORD_HANDLER_MAP = new HashMap<Short, XlsRecordHandler>(32);
static {
XLS_RECORD_HANDLER_MAP.put(BlankRecord.sid, new BlankRecordHandler());
XLS_RECORD_HANDLER_MAP.put(BOFRecord.sid, new BofRecordHandler());
XLS_RECORD_HANDLER_MAP.put(BoolErrRecord.sid, new BoolErrRecordHandler());
XLS_RECORD_HANDLER_MAP.put(BoundSheetRecord.sid, new BoundSheetRecordHandler());
XLS_RECORD_HANDLER_MAP.put(DUMMY_RECORD_SID, new DummyRecordHandler());
XLS_RECORD_HANDLER_MAP.put(EOFRecord.sid, new EofRecordHandler());
XLS_RECORD_HANDLER_MAP.put(FormulaRecord.sid, new FormulaRecordHandler());
XLS_RECORD_HANDLER_MAP.put(HyperlinkRecord.sid, new HyperlinkRecordHandler());
XLS_RECORD_HANDLER_MAP.put(IndexRecord.sid, new IndexRecordHandler());
XLS_RECORD_HANDLER_MAP.put(LabelRecord.sid, new LabelRecordHandler());
XLS_RECORD_HANDLER_MAP.put(LabelSSTRecord.sid, new LabelSstRecordHandler());
XLS_RECORD_HANDLER_MAP.put(MergeCellsRecord.sid, new MergeCellsRecordHandler());
XLS_RECORD_HANDLER_MAP.put(NoteRecord.sid, new NoteRecordHandler());
XLS_RECORD_HANDLER_MAP.put(NumberRecord.sid, new NumberRecordHandler());
XLS_RECORD_HANDLER_MAP.put(ObjRecord.sid, new ObjRecordHandler());
XLS_RECORD_HANDLER_MAP.put(RKRecord.sid, new RkRecordHandler());
XLS_RECORD_HANDLER_MAP.put(SSTRecord.sid, new SstRecordHandler());
XLS_RECORD_HANDLER_MAP.put(StringRecord.sid, new StringRecordHandler());
XLS_RECORD_HANDLER_MAP.put(TextObjectRecord.sid, new TextObjectRecordHandler());
}
private POIFSFileSystem poifsFileSystem;
private Boolean readAll;
private List<ReadSheet> readSheetList;
private int lastRowNumber;
private int lastColumnNumber;
/**
* For parsing Formulas
*/
private EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener;
private FormatTrackingHSSFListener formatListener;
private Map<Integer, CellData> records;
private List<ReadSheet> sheets;
private HSSFWorkbook stubWorkbook;
private List<XlsRecordHandler> recordHandlers = new ArrayList<XlsRecordHandler>();
private AnalysisContext analysisContext;
public XlsSaxAnalyser(AnalysisContext context, POIFSFileSystem poifsFileSystem) {
this.analysisContext = context;
this.records = new LinkedHashMap<Integer, CellData>();
this.poifsFileSystem = poifsFileSystem;
analysisContext.readWorkbookHolder().setPoifsFileSystem(poifsFileSystem);
public XlsSaxAnalyser(XlsReadContext xlsReadContext) {
this.xlsReadContext = xlsReadContext;
}
@Override
public List<ReadSheet> sheetList() {
if (sheets == null) {
LOGGER.warn("Getting the 'sheetList' before reading will cause the file to be read twice.");
XlsListSheetListener xlsListSheetListener = new XlsListSheetListener(analysisContext, poifsFileSystem);
sheets = xlsListSheetListener.getSheetList();
try {
if (xlsReadContext.readWorkbookHolder().getActualSheetDataList() == null) {
new XlsListSheetListener(xlsReadContext).execute();
}
} catch (ExcelAnalysisStopException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Custom stop!");
}
}
return sheets;
return xlsReadContext.readWorkbookHolder().getActualSheetDataList();
}
@Override
public void execute(List<ReadSheet> readSheetList, Boolean readAll) {
this.readAll = readAll;
this.readSheetList = readSheetList;
public void execute() {
XlsReadWorkbookHolder xlsReadWorkbookHolder = xlsReadContext.xlsReadWorkbookHolder();
MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);
formatListener = new FormatTrackingHSSFListener(listener);
workbookBuildingListener = new EventWorkbookBuilder.SheetRecordCollectingListener(formatListener);
if (workbookBuildingListener != null && stubWorkbook == null) {
stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook();
}
init();
xlsReadWorkbookHolder.setFormatTrackingHSSFListener(new FormatTrackingHSSFListener(listener));
EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener =
new EventWorkbookBuilder.SheetRecordCollectingListener(
xlsReadWorkbookHolder.getFormatTrackingHSSFListener());
xlsReadWorkbookHolder.setHssfWorkbook(workbookBuildingListener.getStubHSSFWorkbook());
HSSFEventFactory factory = new HSSFEventFactory();
HSSFRequest request = new HSSFRequest();
request.addListenerForAllRecords(formatListener);
request.addListenerForAllRecords(xlsReadWorkbookHolder.getFormatTrackingHSSFListener());
try {
factory.processWorkbookEvents(request, poifsFileSystem);
factory.processWorkbookEvents(request, xlsReadWorkbookHolder.getPoifsFileSystem());
} catch (IOException e) {
throw new ExcelAnalysisException(e);
}
// Sometimes tables lack the end record of the last column
if (!records.isEmpty()) {
endRow();
if (!xlsReadContext.xlsReadSheetHolder().getCellMap().isEmpty()) {
// Forge a termination data
processRecord(new LastCellOfRowDummyRecord(xlsReadContext.xlsReadSheetHolder().getRowIndex() + 1, -1));
}
}
private void init() {
lastRowNumber = 0;
lastColumnNumber = 0;
records = new LinkedHashMap<Integer, CellData>();
buildXlsRecordHandlers();
}
@Override
public void processRecord(Record record) {
// Not data from the current sheet
if (ignoreRecord(record)) {
XlsRecordHandler handler = XLS_RECORD_HANDLER_MAP.get(record.getSid());
if (handler == null) {
return;
}
int thisRow = -1;
int thisColumn = -1;
CellData cellData = null;
for (XlsRecordHandler handler : this.recordHandlers) {
if (handler.support(record)) {
handler.processRecord(record);
thisRow = handler.getRow();
thisColumn = handler.getColumn();
cellData = handler.getCellData();
if (cellData != null) {
cellData.checkEmpty();
if (CellDataTypeEnum.EMPTY != cellData.getType()) {
records.put(thisColumn, cellData);
}
}
break;
}
}
// If we got something to print out, do so
if (cellData != null && analysisContext.currentReadHolder().globalConfiguration().getAutoTrim()
&& CellDataTypeEnum.STRING == cellData.getType()) {
cellData.setStringValue(cellData.getStringValue().trim());
}
// Handle new row
if (thisRow != -1 && thisRow != lastRowNumber) {
lastColumnNumber = -1;
}
// Update column and row count
if (thisRow > -1) {
lastRowNumber = thisRow;
}
if (thisColumn > -1) {
lastColumnNumber = thisColumn;
}
processLastCellOfRow(record);
}
private boolean ignoreRecord(Record record) {
return analysisContext.readWorkbookHolder().getIgnoreRecord03() && record.getSid() != BoundSheetRecord.sid
&& record.getSid() != BOFRecord.sid;
}
private void processLastCellOfRow(Record record) {
// Handle end of row
if (record instanceof LastCellOfRowDummyRecord) {
endRow();
boolean ignoreRecord = (handler instanceof IgnorableXlsRecordHandler)
&& xlsReadContext.xlsReadSheetHolder() != null && xlsReadContext.xlsReadSheetHolder().getIgnoreRecord();
if (ignoreRecord) {
// No need to read the current sheet
return;
}
}
private void endRow() {
if (lastColumnNumber == -1) {
lastColumnNumber = 0;
if (!handler.support(xlsReadContext, record)) {
return;
}
analysisContext.readRowHolder(
new ReadRowHolder(lastRowNumber, analysisContext.readSheetHolder().getGlobalConfiguration()));
analysisContext.readSheetHolder().notifyEndOneRow(new EachRowAnalysisFinishEvent(records), analysisContext);
records.clear();
lastColumnNumber = -1;
handler.processRecord(xlsReadContext, record);
}
private void buildXlsRecordHandlers() {
if (CollectionUtils.isEmpty(recordHandlers)) {
recordHandlers.add(new BlankOrErrorRecordHandler());
// The table has been counted and there are no duplicate statistics
if (sheets == null) {
sheets = new ArrayList<ReadSheet>();
recordHandlers.add(new BofRecordHandler(analysisContext, sheets, false, true));
} else {
recordHandlers.add(new BofRecordHandler(analysisContext, sheets, true, true));
}
recordHandlers.add(new FormulaRecordHandler(stubWorkbook, formatListener));
recordHandlers.add(new LabelRecordHandler());
recordHandlers.add(new NoteRecordHandler());
recordHandlers.add(new NumberRecordHandler(formatListener));
recordHandlers.add(new RkRecordHandler());
recordHandlers.add(new SstRecordHandler());
recordHandlers.add(new MissingCellDummyRecordHandler());
recordHandlers.add(new IndexRecordHandler(analysisContext));
Collections.sort(recordHandlers);
}
for (XlsRecordHandler x : recordHandlers) {
x.init();
if (x instanceof BofRecordHandler) {
BofRecordHandler bofRecordHandler = (BofRecordHandler)x;
bofRecordHandler.init(readSheetList, readAll);
}
}
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.XlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
/**
* Abstract xls record handler
*
* @author Jiaju Zhuang
**/
public abstract class AbstractXlsRecordHandler implements XlsRecordHandler {
@Override
public boolean support(XlsReadContext xlsReadContext, Record record) {
return true;
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
/**
* Record handler
*
* @author Dan Zheng
*/
public class BlankOrErrorRecordHandler extends AbstractXlsRecordHandler {
@Override
public boolean support(Record record) {
return BlankRecord.sid == record.getSid() || BoolErrRecord.sid == record.getSid();
}
@Override
public void processRecord(Record record) {
if (record.getSid() == BlankRecord.sid) {
BlankRecord br = (BlankRecord)record;
this.row = br.getRow();
this.column = br.getColumn();
this.cellData = new CellData(CellDataTypeEnum.EMPTY);
} else if (record.getSid() == BoolErrRecord.sid) {
BoolErrRecord ber = (BoolErrRecord)record;
this.row = ber.getRow();
this.column = ber.getColumn();
this.cellData = new CellData(ber.getBooleanValue());
}
}
@Override
public void init() {
}
@Override
public int getOrder() {
return 0;
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.metadata.CellData;
/**
* Record handler
*
* @author Dan Zheng
*/
public class BlankRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
BlankRecord br = (BlankRecord)record;
xlsReadContext.xlsReadSheetHolder().getCellMap().put((int)br.getColumn(),
CellData.newEmptyInstance(br.getRow(), (int)br.getColumn()));
}
}
......@@ -7,9 +7,10 @@ import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.exception.ExcelAnalysisStopException;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder;
import com.alibaba.excel.util.SheetUtils;
/**
......@@ -18,91 +19,55 @@ import com.alibaba.excel.util.SheetUtils;
* @author Dan Zheng
*/
public class BofRecordHandler extends AbstractXlsRecordHandler {
private List<BoundSheetRecord> boundSheetRecords = new ArrayList<BoundSheetRecord>();
private BoundSheetRecord[] orderedBsrs;
private int sheetIndex;
private List<ReadSheet> sheets;
private Boolean readAll;
private List<ReadSheet> readSheetList;
private AnalysisContext context;
private boolean alreadyInit;
private boolean needInitSheet;
public BofRecordHandler(AnalysisContext context, List<ReadSheet> sheets, boolean alreadyInit,
boolean needInitSheet) {
this.context = context;
this.sheets = sheets;
this.alreadyInit = alreadyInit;
this.needInitSheet = needInitSheet;
}
@Override
public boolean support(Record record) {
return BoundSheetRecord.sid == record.getSid() || BOFRecord.sid == record.getSid();
}
@Override
public void processRecord(Record record) {
if (record.getSid() == BoundSheetRecord.sid) {
boundSheetRecords.add((BoundSheetRecord)record);
} else if (record.getSid() == BOFRecord.sid) {
BOFRecord br = (BOFRecord)record;
if (br.getType() == BOFRecord.TYPE_WORKSHEET) {
if (orderedBsrs == null) {
orderedBsrs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
}
String sheetName = orderedBsrs[sheetIndex].getSheetname();
// Find the currently read sheet
ReadSheet readSheet = null;
if (!alreadyInit) {
readSheet = new ReadSheet(sheetIndex, sheetName);
sheets.add(readSheet);
}
if (needInitSheet) {
if (readSheet == null) {
for (ReadSheet sheet : sheets) {
if (sheet.getSheetNo() == sheetIndex) {
readSheet = sheet;
break;
}
}
}
assert readSheet != null : "Can't find the sheet.";
context.readWorkbookHolder().setIgnoreRecord03(Boolean.TRUE);
// Copy the parameter to the current sheet
readSheet = SheetUtils.match(readSheet, readSheetList, readAll,
context.readWorkbookHolder().getGlobalConfiguration());
if (readSheet != null) {
if (readSheet.getSheetNo() != 0 && context.readSheetHolder() != null) {
// Prompt for the end of the previous form read
context.readSheetHolder().notifyAfterAllAnalysed(context);
}
context.currentSheet(readSheet);
context.readWorkbookHolder().setIgnoreRecord03(Boolean.FALSE);
}
}
sheetIndex++;
}
public void processRecord(XlsReadContext xlsReadContext, Record record) {
BOFRecord br = (BOFRecord)record;
XlsReadWorkbookHolder xlsReadWorkbookHolder = xlsReadContext.xlsReadWorkbookHolder();
if (br.getType() == BOFRecord.TYPE_WORKBOOK) {
xlsReadWorkbookHolder.setReadSheetIndex(null);
return;
}
}
@Override
public void init() {
sheetIndex = 0;
orderedBsrs = null;
boundSheetRecords.clear();
if (!alreadyInit) {
sheets.clear();
if (br.getType() != BOFRecord.TYPE_WORKSHEET) {
return;
}
// Init read sheet Data
initReadSheetDataList(xlsReadWorkbookHolder);
Integer readSheetIndex = xlsReadWorkbookHolder.getReadSheetIndex();
if (readSheetIndex == null) {
readSheetIndex = 0;
xlsReadWorkbookHolder.setReadSheetIndex(readSheetIndex);
}
ReadSheet readSheet = xlsReadWorkbookHolder.getActualSheetDataList().get(readSheetIndex);
assert readSheet != null : "Can't find the sheet.";
// Copy the parameter to the current sheet
readSheet = SheetUtils.match(readSheet, xlsReadContext);
if (readSheet != null) {
xlsReadContext.currentSheet(readSheet);
xlsReadContext.xlsReadSheetHolder().setIgnoreRecord(Boolean.FALSE);
} else {
xlsReadContext.xlsReadSheetHolder().setIgnoreRecord(Boolean.TRUE);
}
// Go read the next one
xlsReadWorkbookHolder.setReadSheetIndex(xlsReadWorkbookHolder.getReadSheetIndex() + 1);
}
public void init(List<ReadSheet> readSheetList, Boolean readAll) {
this.readSheetList = readSheetList;
this.readAll = readAll;
}
@Override
public int getOrder() {
return 0;
private void initReadSheetDataList(XlsReadWorkbookHolder xlsReadWorkbookHolder) {
if (xlsReadWorkbookHolder.getActualSheetDataList() != null) {
return;
}
BoundSheetRecord[] boundSheetRecords =
BoundSheetRecord.orderByBofPosition(xlsReadWorkbookHolder.getBoundSheetRecordList());
List<ReadSheet> readSheetDataList = new ArrayList<ReadSheet>();
for (int i = 0; i < boundSheetRecords.length; i++) {
BoundSheetRecord boundSheetRecord = boundSheetRecords[i];
ReadSheet readSheet = new ReadSheet(i, boundSheetRecord.getSheetname());
readSheetDataList.add(readSheet);
}
xlsReadWorkbookHolder.setActualSheetDataList(readSheetDataList);
// Just need to get the list of sheets
if (!xlsReadWorkbookHolder.getNeedReadSheet()) {
throw new ExcelAnalysisStopException("Just need to get the list of sheets.");
}
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.metadata.CellData;
/**
* Record handler
*
* @author Dan Zheng
*/
public class BoolErrRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
BoolErrRecord ber = (BoolErrRecord)record;
xlsReadContext.xlsReadSheetHolder().getCellMap().put((int)ber.getColumn(),
CellData.newInstance(ber.getBooleanValue(), ber.getRow(), (int)ber.getColumn()));
xlsReadContext.xlsReadSheetHolder().setTempRowType(RowTypeEnum.DATA);
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.BoundSheetRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
/**
* Record handler
*
* @author Dan Zheng
*/
public class BoundSheetRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
BoundSheetRecord bsr = (BoundSheetRecord)record;
xlsReadContext.xlsReadWorkbookHolder().getBoundSheetRecordList().add((BoundSheetRecord)record);
}
}
package com.alibaba.excel.analysis.v03.handlers;
import java.util.LinkedHashMap;
import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.metadata.Cell;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder;
/**
* Record handler
*
* @author Dan Zheng
*/
public class DummyRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
XlsReadSheetHolder xlsReadSheetHolder = xlsReadContext.xlsReadSheetHolder();
if (record instanceof LastCellOfRowDummyRecord) {
// End of this row
LastCellOfRowDummyRecord lcrdr = (LastCellOfRowDummyRecord)record;
xlsReadSheetHolder.setRowIndex(lcrdr.getRow());
xlsReadContext.readRowHolder(new ReadRowHolder(lcrdr.getRow(), xlsReadSheetHolder.getTempRowType(),
xlsReadContext.readSheetHolder().getGlobalConfiguration(), xlsReadSheetHolder.getCellMap()));
xlsReadContext.analysisEventProcessor().endRow(xlsReadContext);
xlsReadSheetHolder.setCellMap(new LinkedHashMap<Integer, Cell>());
xlsReadSheetHolder.setTempRowType(RowTypeEnum.EMPTY);
} else if (record instanceof MissingCellDummyRecord) {
MissingCellDummyRecord mcdr = (MissingCellDummyRecord)record;
xlsReadSheetHolder.getCellMap().put(mcdr.getColumn(),
CellData.newEmptyInstance(mcdr.getRow(), mcdr.getColumn()));
}
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
/**
* Record handler
*
* @author Dan Zheng
*/
public class EofRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
if (xlsReadContext.readSheetHolder() != null) {
xlsReadContext.analysisEventProcessor().endSheet(xlsReadContext);
}
}
}
package com.alibaba.excel.analysis.v03.handlers;
import java.math.BigDecimal;
import java.util.Map;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Cell;
import com.alibaba.excel.metadata.CellData;
/**
......@@ -21,96 +22,59 @@ import com.alibaba.excel.metadata.CellData;
*
* @author Dan Zheng
*/
public class FormulaRecordHandler extends AbstractXlsRecordHandler {
public class FormulaRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(FormulaRecordHandler.class);
private static final String ERROR = "#VALUE!";
private int nextRow;
private int nextColumn;
private boolean outputNextStringRecord;
private CellData tempCellData;
private FormatTrackingHSSFListener formatListener;
private HSSFWorkbook stubWorkbook;
public FormulaRecordHandler(HSSFWorkbook stubWorkbook, FormatTrackingHSSFListener formatListener) {
this.stubWorkbook = stubWorkbook;
this.formatListener = formatListener;
}
@Override
public boolean support(Record record) {
return FormulaRecord.sid == record.getSid() || StringRecord.sid == record.getSid();
}
@Override
public void processRecord(Record record) {
if (record.getSid() == FormulaRecord.sid) {
FormulaRecord frec = (FormulaRecord)record;
this.row = frec.getRow();
this.column = frec.getColumn();
CellType cellType = CellType.forInt(frec.getCachedResultType());
String formulaValue = null;
try {
formulaValue = HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression());
} catch (Exception e) {
LOGGER.warn("Get formula value error.{}", e.getMessage());
}
switch (cellType) {
case STRING:
// Formula result is a string
// This is stored in the next record
outputNextStringRecord = true;
nextRow = frec.getRow();
nextColumn = frec.getColumn();
tempCellData = new CellData(CellDataTypeEnum.STRING);
tempCellData.setFormula(Boolean.TRUE);
tempCellData.setFormulaValue(formulaValue);
break;
case NUMERIC:
this.cellData = new CellData(BigDecimal.valueOf(frec.getValue()));
this.cellData.setFormula(Boolean.TRUE);
this.cellData.setFormulaValue(formulaValue);
break;
case ERROR:
this.cellData = new CellData(CellDataTypeEnum.ERROR);
this.cellData.setStringValue(ERROR);
this.cellData.setFormula(Boolean.TRUE);
this.cellData.setFormulaValue(formulaValue);
break;
case BOOLEAN:
this.cellData = new CellData(frec.getCachedBooleanValue());
this.cellData.setFormula(Boolean.TRUE);
this.cellData.setFormulaValue(formulaValue);
break;
default:
this.cellData = new CellData(CellDataTypeEnum.EMPTY);
this.cellData.setFormula(Boolean.TRUE);
this.cellData.setFormulaValue(formulaValue);
break;
}
} else if (record.getSid() == StringRecord.sid) {
if (outputNextStringRecord) {
// String for formula
StringRecord srec = (StringRecord)record;
this.cellData = tempCellData;
this.cellData.setStringValue(srec.getString());
this.row = nextRow;
this.column = nextColumn;
outputNextStringRecord = false;
tempCellData = null;
}
public void processRecord(XlsReadContext xlsReadContext, Record record) {
FormulaRecord frec = (FormulaRecord)record;
Map<Integer, Cell> cellMap = xlsReadContext.xlsReadSheetHolder().getCellMap();
CellData tempCellData = new CellData();
tempCellData.setRowIndex(frec.getRow());
tempCellData.setColumnIndex((int)frec.getColumn());
CellType cellType = CellType.forInt(frec.getCachedResultType());
String formulaValue = null;
try {
formulaValue = HSSFFormulaParser.toFormulaString(xlsReadContext.xlsReadWorkbookHolder().getHssfWorkbook(),
frec.getParsedExpression());
} catch (Exception e) {
LOGGER.debug("Get formula value error.", e);
}
tempCellData.setFormula(Boolean.TRUE);
tempCellData.setFormulaValue(formulaValue);
switch (cellType) {
case STRING:
// Formula result is a string
// This is stored in the next record
tempCellData.setType(CellDataTypeEnum.STRING);
xlsReadContext.xlsReadSheetHolder().setTempCellData(tempCellData);
break;
case NUMERIC:
tempCellData.setType(CellDataTypeEnum.NUMBER);
tempCellData.setNumberValue(BigDecimal.valueOf(frec.getValue()));
Integer dataFormat =
xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(frec);
tempCellData.setDataFormat(dataFormat);
tempCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat,
xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(frec),
xlsReadContext.readSheetHolder().getGlobalConfiguration().getLocale()));
cellMap.put((int)frec.getColumn(), tempCellData);
break;
case ERROR:
tempCellData.setType(CellDataTypeEnum.ERROR);
tempCellData.setStringValue(ERROR);
cellMap.put((int)frec.getColumn(), tempCellData);
break;
case BOOLEAN:
tempCellData.setType(CellDataTypeEnum.BOOLEAN);
tempCellData.setBooleanValue(frec.getCachedBooleanValue());
cellMap.put((int)frec.getColumn(), tempCellData);
break;
default:
tempCellData.setType(CellDataTypeEnum.EMPTY);
cellMap.put((int)frec.getColumn(), tempCellData);
break;
}
}
@Override
public void init() {
this.nextRow = 0;
this.nextColumn = 0;
}
@Override
public int getOrder() {
return 0;
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.HyperlinkRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
/**
* Record handler
*
* @author Dan Zheng
*/
public class HyperlinkRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public boolean support(XlsReadContext xlsReadContext, Record record) {
return xlsReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.HYPERLINK);
}
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
HyperlinkRecord hr = (HyperlinkRecord)record;
CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.HYPERLINK, hr.getAddress(), hr.getFirstRow(),
hr.getLastRow(), hr.getFirstColumn(), hr.getLastColumn());
xlsReadContext.xlsReadSheetHolder().setCellExtra(cellExtra);
xlsReadContext.analysisEventProcessor().extra(xlsReadContext);
}
}
......@@ -3,40 +3,20 @@ package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.IndexRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
/**
* Record handler
*
* @author Jiaju Zhuang
*/
public class IndexRecordHandler extends AbstractXlsRecordHandler {
private AnalysisContext context;
public IndexRecordHandler(AnalysisContext context) {
this.context = context;
}
@Override
public boolean support(Record record) {
return record instanceof IndexRecord;
}
@Override
public void init() {}
public class IndexRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public void processRecord(Record record) {
if (context.readSheetHolder() == null) {
public void processRecord(XlsReadContext xlsReadContext, Record record) {
if (xlsReadContext.readSheetHolder() == null) {
return;
}
context.readSheetHolder().setApproximateTotalRowNumber(((IndexRecord)record).getLastRowAdd1());
}
@Override
public int getOrder() {
return 1;
xlsReadContext.readSheetHolder().setApproximateTotalRowNumber(((IndexRecord)record).getLastRowAdd1());
}
}
......@@ -3,7 +3,9 @@ package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.LabelRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.metadata.CellData;
/**
......@@ -11,27 +13,16 @@ import com.alibaba.excel.metadata.CellData;
*
* @author Dan Zheng
*/
public class LabelRecordHandler extends AbstractXlsRecordHandler {
public class LabelRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public boolean support(Record record) {
return LabelRecord.sid == record.getSid();
}
@Override
public void processRecord(Record record) {
public void processRecord(XlsReadContext xlsReadContext, Record record) {
LabelRecord lrec = (LabelRecord)record;
this.row = lrec.getRow();
this.column = lrec.getColumn();
this.cellData = new CellData(lrec.getValue());
}
@Override
public void init() {
}
@Override
public int getOrder() {
return 0;
String data = lrec.getValue();
if (data != null && xlsReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
data = data.trim();
}
xlsReadContext.xlsReadSheetHolder().getCellMap().put((int)lrec.getColumn(),
CellData.newInstance(data, lrec.getRow(), (int)lrec.getColumn()));
xlsReadContext.xlsReadSheetHolder().setTempRowType(RowTypeEnum.DATA);
}
}
package com.alibaba.excel.analysis.v03.handlers;
import java.util.Map;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.cache.ReadCache;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.metadata.Cell;
import com.alibaba.excel.metadata.CellData;
/**
* Record handler
*
* @author Dan Zheng
*/
public class LabelSstRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
LabelSSTRecord lsrec = (LabelSSTRecord)record;
ReadCache readCache = xlsReadContext.readWorkbookHolder().getReadCache();
Map<Integer, Cell> cellMap = xlsReadContext.xlsReadSheetHolder().getCellMap();
if (readCache == null) {
cellMap.put((int)lsrec.getColumn(), CellData.newEmptyInstance(lsrec.getRow(), (int)lsrec.getColumn()));
return;
}
String data = readCache.get(lsrec.getSSTIndex());
if (data == null) {
cellMap.put((int)lsrec.getColumn(), CellData.newEmptyInstance(lsrec.getRow(), (int)lsrec.getColumn()));
return;
}
if (xlsReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
data = data.trim();
}
cellMap.put((int)lsrec.getColumn(), CellData.newInstance(data, lsrec.getRow(), (int)lsrec.getColumn()));
xlsReadContext.xlsReadSheetHolder().setTempRowType(RowTypeEnum.DATA);
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.MergeCellsRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.ss.util.CellRangeAddress;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
/**
* Record handler
*
* @author Dan Zheng
*/
public class MergeCellsRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public boolean support(XlsReadContext xlsReadContext, Record record) {
return xlsReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.MERGE);
}
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
MergeCellsRecord mcr = (MergeCellsRecord)record;
for (int i = 0; i < mcr.getNumAreas(); i++) {
CellRangeAddress cellRangeAddress = mcr.getAreaAt(i);
CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.MERGE, null, cellRangeAddress.getFirstRow(),
cellRangeAddress.getLastRow(), cellRangeAddress.getFirstColumn(), cellRangeAddress.getLastColumn());
xlsReadContext.xlsReadSheetHolder().setCellExtra(cellExtra);
xlsReadContext.analysisEventProcessor().extra(xlsReadContext);
}
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
/**
* Record handler
*
* @author Dan Zheng
*/
public class MissingCellDummyRecordHandler extends AbstractXlsRecordHandler {
@Override
public boolean support(Record record) {
return record instanceof MissingCellDummyRecord;
}
@Override
public void init() {
}
@Override
public void processRecord(Record record) {
MissingCellDummyRecord mcdr = (MissingCellDummyRecord)record;
this.row = mcdr.getRow();
this.column = mcdr.getColumn();
this.cellData = new CellData(CellDataTypeEnum.EMPTY);
}
@Override
public int getOrder() {
return 1;
}
}
......@@ -3,36 +3,29 @@ package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.NoteRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
/**
* Record handler
*
* @author Dan Zheng
*/
public class NoteRecordHandler extends AbstractXlsRecordHandler {
@Override
public boolean support(Record record) {
return NoteRecord.sid == record.getSid();
}
@Override
public void processRecord(Record record) {
NoteRecord nrec = (NoteRecord)record;
this.row = nrec.getRow();
this.column = nrec.getColumn();
this.cellData = new CellData(CellDataTypeEnum.EMPTY);
}
public class NoteRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public void init() {
public boolean support(XlsReadContext xlsReadContext, Record record) {
return xlsReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.COMMENT);
}
@Override
public int getOrder() {
return 0;
public void processRecord(XlsReadContext xlsReadContext, Record record) {
NoteRecord nr = (NoteRecord)record;
String text = xlsReadContext.xlsReadSheetHolder().getObjectCacheMap().get(nr.getShapeId());
CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.COMMENT, text, nr.getRow(), nr.getColumn());
xlsReadContext.xlsReadSheetHolder().setCellExtra(cellExtra);
xlsReadContext.analysisEventProcessor().extra(xlsReadContext);
}
}
......@@ -2,11 +2,13 @@ package com.alibaba.excel.analysis.v03.handlers;
import java.math.BigDecimal;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.metadata.CellData;
/**
......@@ -14,35 +16,18 @@ import com.alibaba.excel.metadata.CellData;
*
* @author Dan Zheng
*/
public class NumberRecordHandler extends AbstractXlsRecordHandler {
private FormatTrackingHSSFListener formatListener;
public NumberRecordHandler(FormatTrackingHSSFListener formatListener) {
this.formatListener = formatListener;
}
@Override
public boolean support(Record record) {
return NumberRecord.sid == record.getSid();
}
@Override
public void processRecord(Record record) {
NumberRecord numrec = (NumberRecord)record;
this.row = numrec.getRow();
this.column = numrec.getColumn();
this.cellData = new CellData(BigDecimal.valueOf(numrec.getValue()));
this.cellData.setDataFormat(formatListener.getFormatIndex(numrec));
this.cellData.setDataFormatString(formatListener.getFormatString(numrec));
}
@Override
public void init() {
}
public class NumberRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public int getOrder() {
return 0;
public void processRecord(XlsReadContext xlsReadContext, Record record) {
NumberRecord nr = (NumberRecord)record;
CellData cellData = CellData.newInstance(BigDecimal.valueOf(nr.getValue()), nr.getRow(), (int)nr.getColumn());
Integer dataFormat = xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatIndex(nr);
cellData.setDataFormat(dataFormat);
cellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat,
xlsReadContext.xlsReadWorkbookHolder().getFormatTrackingHSSFListener().getFormatString(nr),
xlsReadContext.readSheetHolder().getGlobalConfiguration().getLocale()));
xlsReadContext.xlsReadSheetHolder().getCellMap().put((int)nr.getColumn(), cellData);
xlsReadContext.xlsReadSheetHolder().setTempRowType(RowTypeEnum.DATA);
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.ObjRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SubRecord;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
/**
* Record handler
*
* @author Jiaju Zhuang
*/
public class ObjRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
ObjRecord or = (ObjRecord)record;
for (SubRecord subRecord : or.getSubRecords()) {
if (subRecord instanceof CommonObjectDataSubRecord) {
CommonObjectDataSubRecord codsr = (CommonObjectDataSubRecord)subRecord;
if (CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT == codsr.getObjectType()) {
xlsReadContext.xlsReadSheetHolder().setTempObjectIndex(codsr.getObjectId());
}
break;
}
}
}
}
......@@ -3,8 +3,8 @@ package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.RKRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.metadata.CellData;
/**
......@@ -12,28 +12,12 @@ import com.alibaba.excel.metadata.CellData;
*
* @author Dan Zheng
*/
public class RkRecordHandler extends AbstractXlsRecordHandler {
@Override
public boolean support(Record record) {
return RKRecord.sid == record.getSid();
}
@Override
public void processRecord(Record record) {
RKRecord rkrec = (RKRecord)record;
this.row = rkrec.getRow();
this.row = rkrec.getColumn();
this.cellData = new CellData(CellDataTypeEnum.EMPTY);
}
@Override
public void init() {
}
public class RkRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public int getOrder() {
return 0;
public void processRecord(XlsReadContext xlsReadContext, Record record) {
RKRecord re = (RKRecord)record;
xlsReadContext.xlsReadSheetHolder().getCellMap().put((int)re.getColumn(),
CellData.newEmptyInstance(re.getRow(), (int)re.getColumn()));
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SSTRecord;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.cache.XlsCache;
import com.alibaba.excel.context.xls.XlsReadContext;
/**
* Record handler
*
* @author Dan Zheng
*/
public class SstRecordHandler extends AbstractXlsRecordHandler {
private SSTRecord sstRecord;
@Override
public boolean support(Record record) {
return SSTRecord.sid == record.getSid() || LabelSSTRecord.sid == record.getSid();
}
@Override
public void processRecord(Record record) {
if (record.getSid() == SSTRecord.sid) {
sstRecord = (SSTRecord)record;
} else if (record.getSid() == LabelSSTRecord.sid) {
LabelSSTRecord lsrec = (LabelSSTRecord)record;
this.row = lsrec.getRow();
this.column = lsrec.getColumn();
if (sstRecord == null) {
this.cellData = new CellData(CellDataTypeEnum.EMPTY);
} else {
this.cellData = new CellData(sstRecord.getString(lsrec.getSSTIndex()).toString());
}
}
}
@Override
public void init() {
}
public class SstRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
@Override
public int getOrder() {
return 0;
public void processRecord(XlsReadContext xlsReadContext, Record record) {
xlsReadContext.readWorkbookHolder().setReadCache(new XlsCache((SSTRecord)record));
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.StringRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder;
/**
* Record handler
*
* @author Dan Zheng
*/
public class StringRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(StringRecordHandler.class);
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
// String for formula
StringRecord srec = (StringRecord)record;
XlsReadSheetHolder xlsReadSheetHolder = xlsReadContext.xlsReadSheetHolder();
CellData tempCellData = xlsReadSheetHolder.getTempCellData();
if (tempCellData == null) {
LOGGER.warn("String type formula but no value found.");
return;
}
tempCellData.setStringValue(srec.getString());
xlsReadSheetHolder.getCellMap().put(tempCellData.getColumnIndex(), tempCellData);
xlsReadSheetHolder.setTempCellData(null);
}
}
package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.TextObjectRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.v03.IgnorableXlsRecordHandler;
import com.alibaba.excel.context.xls.XlsReadContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder;
/**
* Record handler
*
* @author Jiaju Zhuang
*/
public class TextObjectRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(TextObjectRecordHandler.class);
@Override
public boolean support(XlsReadContext xlsReadContext, Record record) {
return xlsReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.COMMENT);
}
@Override
public void processRecord(XlsReadContext xlsReadContext, Record record) {
TextObjectRecord tor = (TextObjectRecord)record;
XlsReadSheetHolder xlsReadSheetHolder = xlsReadContext.xlsReadSheetHolder();
Integer tempObjectIndex = xlsReadSheetHolder.getTempObjectIndex();
if (tempObjectIndex == null) {
LOGGER.debug("tempObjectIndex is null.");
return;
}
xlsReadSheetHolder.getObjectCacheMap().put(tempObjectIndex, tor.getStr().getString());
xlsReadSheetHolder.setTempObjectIndex(null);
}
}
package com.alibaba.excel.analysis.v07;
import org.xml.sax.Attributes;
/**
* Cell handler
*
* @author Dan Zheng
*/
public interface XlsxCellHandler {
/**
* Which tags are supported
*
* @param name
* Tag name
* @return Support parsing or not
*/
boolean support(String name);
/**
* Start handle
*
* @param name
* Tag name
* @param attributes
* Tag attributes
*/
void startHandle(String name, Attributes attributes);
/**
* End handle
*
* @param name
* Tag name
*/
void endHandle(String name);
}
package com.alibaba.excel.analysis.v07;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.xssf.model.StylesTable;
import com.alibaba.excel.analysis.v07.handlers.CountRowCellHandler;
import com.alibaba.excel.analysis.v07.handlers.DefaultCellHandler;
import com.alibaba.excel.analysis.v07.handlers.ProcessResultCellHandler;
import com.alibaba.excel.context.AnalysisContext;
/**
* Build handler
*
* @author Dan Zheng
*/
public class XlsxHandlerFactory {
public static List<XlsxCellHandler> buildCellHandlers(AnalysisContext analysisContext, StylesTable stylesTable) {
List<XlsxCellHandler> result = new ArrayList<XlsxCellHandler>();
result.add(new CountRowCellHandler(analysisContext));
DefaultCellHandler defaultCellHandler = new DefaultCellHandler(analysisContext, stylesTable);
result.add(defaultCellHandler);
result.add(new ProcessResultCellHandler(analysisContext, defaultCellHandler));
return result;
}
}
package com.alibaba.excel.analysis.v07;
import java.util.List;
import org.apache.poi.xssf.model.StylesTable;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.alibaba.excel.context.AnalysisContext;
/**
*
* @author jipengfei
*/
public class XlsxRowHandler extends DefaultHandler {
private List<XlsxCellHandler> cellHandlers;
private XlsxRowResultHolder rowResultHolder;
public XlsxRowHandler(AnalysisContext analysisContext, StylesTable stylesTable) {
this.cellHandlers = XlsxHandlerFactory.buildCellHandlers(analysisContext, stylesTable);
for (XlsxCellHandler cellHandler : cellHandlers) {
if (cellHandler instanceof XlsxRowResultHolder) {
this.rowResultHolder = (XlsxRowResultHolder)cellHandler;
break;
}
}
}
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
for (XlsxCellHandler cellHandler : cellHandlers) {
if (cellHandler.support(name)) {
cellHandler.startHandle(name, attributes);
}
}
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
for (XlsxCellHandler cellHandler : cellHandlers) {
if (cellHandler.support(name)) {
cellHandler.endHandle(name);
}
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (rowResultHolder != null) {
rowResultHolder.appendCurrentCellValue(ch, start, length);
}
}
}
package com.alibaba.excel.analysis.v07;
import java.util.Map;
import com.alibaba.excel.metadata.CellData;
/**
* Result holder
*
* @author jipengfei
*/
public interface XlsxRowResultHolder {
/**
* Clear Result
*/
void clearResult();
/**
* Append current 'cellValue'
*
* @param ch
* @param start
* @param length
*/
void appendCurrentCellValue(char[] ch, int start, int length);
/**
* Get row content
*
* @return
*/
Map<Integer, CellData> getCurRowContent();
}
......@@ -15,8 +15,10 @@ import javax.xml.parsers.SAXParserFactory;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
......@@ -26,37 +28,40 @@ import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import com.alibaba.excel.analysis.ExcelReadExecutor;
import com.alibaba.excel.analysis.v07.handlers.sax.SharedStringsTableHandler;
import com.alibaba.excel.analysis.v07.handlers.sax.XlsxRowHandler;
import com.alibaba.excel.cache.ReadCache;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.SheetUtils;
import com.alibaba.excel.util.StringUtils;
/**
*
* @author jipengfei
*/
public class XlsxSaxAnalyser implements ExcelReadExecutor {
private AnalysisContext analysisContext;
private XlsxReadContext xlsxReadContext;
private List<ReadSheet> sheetList;
private Map<Integer, InputStream> sheetMap;
/**
* Current style information
* excel comments key: sheetNo value: CommentsTable
*/
private StylesTable stylesTable;
private Map<Integer, CommentsTable> commentsTableMap;
public XlsxSaxAnalyser(AnalysisContext analysisContext, InputStream decryptedStream) throws Exception {
this.analysisContext = analysisContext;
public XlsxSaxAnalyser(XlsxReadContext xlsxReadContext, InputStream decryptedStream) throws Exception {
this.xlsxReadContext = xlsxReadContext;
// Initialize cache
ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder();
XlsxReadWorkbookHolder xlsxReadWorkbookHolder = xlsxReadContext.xlsxReadWorkbookHolder();
OPCPackage pkg = readOpcPackage(readWorkbookHolder, decryptedStream);
readWorkbookHolder.setOpcPackage(pkg);
OPCPackage pkg = readOpcPackage(xlsxReadWorkbookHolder, decryptedStream);
xlsxReadWorkbookHolder.setOpcPackage(pkg);
ArrayList<PackagePart> packageParts = pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType());
......@@ -64,18 +69,19 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor {
PackagePart sharedStringsTablePackagePart = packageParts.get(0);
// Specify default cache
defaultReadCache(readWorkbookHolder, sharedStringsTablePackagePart);
defaultReadCache(xlsxReadWorkbookHolder, sharedStringsTablePackagePart);
// Analysis sharedStringsTable.xml
analysisSharedStringsTable(sharedStringsTablePackagePart.getInputStream(), readWorkbookHolder);
analysisSharedStringsTable(sharedStringsTablePackagePart.getInputStream(), xlsxReadWorkbookHolder);
}
XSSFReader xssfReader = new XSSFReader(pkg);
analysisUse1904WindowDate(xssfReader, readWorkbookHolder);
analysisUse1904WindowDate(xssfReader, xlsxReadWorkbookHolder);
stylesTable = xssfReader.getStylesTable();
xlsxReadWorkbookHolder.setStylesTable(xssfReader.getStylesTable());
sheetList = new ArrayList<ReadSheet>();
sheetMap = new HashMap<Integer, InputStream>();
commentsTableMap = new HashMap<Integer, CommentsTable>();
XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData();
int index = 0;
if (!ite.hasNext()) {
......@@ -85,19 +91,26 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor {
InputStream inputStream = ite.next();
sheetList.add(new ReadSheet(index, ite.getSheetName()));
sheetMap.put(index, inputStream);
if (xlsxReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.COMMENT)) {
CommentsTable commentsTable = ite.getSheetComments();
if (null != commentsTable) {
commentsTableMap.put(index, commentsTable);
}
}
index++;
}
}
private void defaultReadCache(ReadWorkbookHolder readWorkbookHolder, PackagePart sharedStringsTablePackagePart) {
ReadCache readCache = readWorkbookHolder.getReadCacheSelector().readCache(sharedStringsTablePackagePart);
readWorkbookHolder.setReadCache(readCache);
readCache.init(analysisContext);
private void defaultReadCache(XlsxReadWorkbookHolder xlsxReadWorkbookHolder,
PackagePart sharedStringsTablePackagePart) {
ReadCache readCache = xlsxReadWorkbookHolder.getReadCacheSelector().readCache(sharedStringsTablePackagePart);
xlsxReadWorkbookHolder.setReadCache(readCache);
readCache.init(xlsxReadContext);
}
private void analysisUse1904WindowDate(XSSFReader xssfReader, ReadWorkbookHolder readWorkbookHolder)
private void analysisUse1904WindowDate(XSSFReader xssfReader, XlsxReadWorkbookHolder xlsxReadWorkbookHolder)
throws Exception {
if (readWorkbookHolder.globalConfiguration().getUse1904windowing() != null) {
if (xlsxReadWorkbookHolder.globalConfiguration().getUse1904windowing() != null) {
return;
}
InputStream workbookXml = xssfReader.getWorkbookData();
......@@ -105,38 +118,38 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor {
CTWorkbook wb = ctWorkbook.getWorkbook();
CTWorkbookPr prefix = wb.getWorkbookPr();
if (prefix != null && prefix.getDate1904()) {
readWorkbookHolder.getGlobalConfiguration().setUse1904windowing(Boolean.TRUE);
xlsxReadWorkbookHolder.getGlobalConfiguration().setUse1904windowing(Boolean.TRUE);
} else {
readWorkbookHolder.getGlobalConfiguration().setUse1904windowing(Boolean.FALSE);
xlsxReadWorkbookHolder.getGlobalConfiguration().setUse1904windowing(Boolean.FALSE);
}
}
private void analysisSharedStringsTable(InputStream sharedStringsTableInputStream,
ReadWorkbookHolder readWorkbookHolder) throws Exception {
ContentHandler handler = new SharedStringsTableHandler(readWorkbookHolder.getReadCache());
XlsxReadWorkbookHolder xlsxReadWorkbookHolder) throws Exception {
ContentHandler handler = new SharedStringsTableHandler(xlsxReadWorkbookHolder.getReadCache());
parseXmlSource(sharedStringsTableInputStream, handler);
readWorkbookHolder.getReadCache().putFinished();
xlsxReadWorkbookHolder.getReadCache().putFinished();
}
private OPCPackage readOpcPackage(ReadWorkbookHolder readWorkbookHolder, InputStream decryptedStream)
private OPCPackage readOpcPackage(XlsxReadWorkbookHolder xlsxReadWorkbookHolder, InputStream decryptedStream)
throws Exception {
if (decryptedStream == null && readWorkbookHolder.getFile() != null) {
return OPCPackage.open(readWorkbookHolder.getFile());
if (decryptedStream == null && xlsxReadWorkbookHolder.getFile() != null) {
return OPCPackage.open(xlsxReadWorkbookHolder.getFile());
}
if (readWorkbookHolder.getMandatoryUseInputStream()) {
if (xlsxReadWorkbookHolder.getMandatoryUseInputStream()) {
if (decryptedStream != null) {
return OPCPackage.open(decryptedStream);
} else {
return OPCPackage.open(readWorkbookHolder.getInputStream());
return OPCPackage.open(xlsxReadWorkbookHolder.getInputStream());
}
}
File readTempFile = FileUtils.createCacheTmpFile();
readWorkbookHolder.setTempFile(readTempFile);
xlsxReadWorkbookHolder.setTempFile(readTempFile);
File tempFile = new File(readTempFile.getPath(), UUID.randomUUID().toString() + ".xlsx");
if (decryptedStream != null) {
FileUtils.writeToFile(tempFile, decryptedStream);
} else {
FileUtils.writeToFile(tempFile, readWorkbookHolder.getInputStream());
FileUtils.writeToFile(tempFile, xlsxReadWorkbookHolder.getInputStream());
}
return OPCPackage.open(tempFile, PackageAccess.READ);
}
......@@ -150,7 +163,7 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor {
InputSource inputSource = new InputSource(inputStream);
try {
SAXParserFactory saxFactory;
String xlsxSAXParserFactoryName = analysisContext.readWorkbookHolder().getXlsxSAXParserFactoryName();
String xlsxSAXParserFactoryName = xlsxReadContext.xlsxReadWorkbookHolder().getSaxParserFactoryName();
if (StringUtils.isEmpty(xlsxSAXParserFactoryName)) {
saxFactory = SAXParserFactory.newInstance();
} else {
......@@ -180,16 +193,34 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor {
}
@Override
public void execute(List<ReadSheet> readSheetList, Boolean readAll) {
public void execute() {
for (ReadSheet readSheet : sheetList) {
readSheet = SheetUtils.match(readSheet, readSheetList, readAll,
analysisContext.readWorkbookHolder().getGlobalConfiguration());
readSheet = SheetUtils.match(readSheet, xlsxReadContext);
if (readSheet != null) {
analysisContext.currentSheet(readSheet);
parseXmlSource(sheetMap.get(readSheet.getSheetNo()), new XlsxRowHandler(analysisContext, stylesTable));
xlsxReadContext.currentSheet(readSheet);
parseXmlSource(sheetMap.get(readSheet.getSheetNo()), new XlsxRowHandler(xlsxReadContext));
// Read comments
readComments(readSheet);
// The last sheet is read
analysisContext.readSheetHolder().notifyAfterAllAnalysed(analysisContext);
xlsxReadContext.analysisEventProcessor().endSheet(xlsxReadContext);
}
}
}
private void readComments(ReadSheet readSheet) {
if (!xlsxReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.COMMENT)) {
return;
}
CommentsTable commentsTable = commentsTableMap.get(readSheet.getSheetNo());
if (commentsTable == null) {
return;
}
Map<CellAddress, XSSFComment> cellComments = commentsTable.getCellComments();
for (XSSFComment xssfComment : cellComments.values()) {
CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.COMMENT, xssfComment.getString().toString(),
xssfComment.getRow(), xssfComment.getColumn());
xlsxReadContext.readSheetHolder().setCellExtra(cellExtra);
xlsxReadContext.analysisEventProcessor().extra(xlsxReadContext);
}
}
}
package com.alibaba.excel.analysis.v07.handlers;
import java.math.BigDecimal;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.util.BooleanUtils;
/**
* Cell Value Handler
*
* @author jipengfei
*/
public abstract class AbstractCellValueTagHandler extends AbstractXlsxTagHandler {
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
CellData tempCellData = xlsxReadSheetHolder.getTempCellData();
StringBuilder tempData = xlsxReadSheetHolder.getTempData();
CellDataTypeEnum oldType = tempCellData.getType();
switch (oldType) {
case DIRECT_STRING:
case STRING:
case ERROR:
tempCellData.setStringValue(tempData.toString());
break;
case BOOLEAN:
tempCellData.setBooleanValue(BooleanUtils.valueOf(tempData.toString()));
break;
case NUMBER:
case EMPTY:
tempCellData.setType(CellDataTypeEnum.NUMBER);
tempCellData.setNumberValue(new BigDecimal(tempData.toString()));
break;
default:
throw new IllegalStateException("Cannot set values now");
}
// set string value
setStringValue(xlsxReadContext);
if (tempCellData.getStringValue() != null
&& xlsxReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
tempCellData.setStringValue(tempCellData.getStringValue());
}
tempCellData.checkEmpty();
xlsxReadSheetHolder.getCellMap().put(xlsxReadSheetHolder.getColumnIndex(), tempCellData);
}
@Override
public void characters(XlsxReadContext xlsxReadContext, char[] ch, int start, int length) {
xlsxReadContext.xlsxReadSheetHolder().getTempData().append(ch, start, length);
}
/**
* Set string value.
*
* @param xlsxReadContext
*/
protected abstract void setStringValue(XlsxReadContext xlsxReadContext);
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
/**
* Abstract tag handler
*
* @author Jiaju Zhuang
*/
public abstract class AbstractXlsxTagHandler implements XlsxTagHandler {
@Override
public boolean support(XlsxReadContext xlsxReadContext) {
return true;
}
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
}
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
}
@Override
public void characters(XlsxReadContext xlsxReadContext, char[] ch, int start, int length) {
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
/**
* Cell Handler
*
* @author jipengfei
*/
public class CellFormulaTagHandler extends AbstractXlsxTagHandler {
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
xlsxReadSheetHolder.getTempCellData().setFormula(Boolean.TRUE);
xlsxReadSheetHolder.setTempFormula(new StringBuilder());
}
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
xlsxReadSheetHolder.getTempCellData().setFormulaValue(xlsxReadSheetHolder.getTempFormula().toString());
}
@Override
public void characters(XlsxReadContext xlsxReadContext, char[] ch, int start, int length) {
xlsxReadContext.xlsxReadSheetHolder().getTempFormula().append(ch, start, length);
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.metadata.CellData;
/**
* Cell inline string value handler
*
* @author jipengfei
*/
public class CellInlineStringValueTagHandler extends AbstractCellValueTagHandler {
@Override
protected void setStringValue(XlsxReadContext xlsxReadContext) {
// This is a special form of string
CellData tempCellData = xlsxReadContext.xlsxReadSheetHolder().getTempCellData();
XSSFRichTextString richTextString = new XSSFRichTextString(tempCellData.getStringValue());
tempCellData.setStringValue(richTextString.toString());
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.xml.sax.Attributes;
import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.util.PositionUtils;
import com.alibaba.excel.util.StringUtils;
/**
* Cell Handler
*
* @author jipengfei
*/
public class CellTagHandler extends AbstractXlsxTagHandler {
private static final int DEFAULT_FORMAT_INDEX = 0;
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
xlsxReadSheetHolder.setColumnIndex(PositionUtils.getCol(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R),
xlsxReadSheetHolder.getColumnIndex()));
// t="s" ,it's means String
// t="str" ,it's means String,but does not need to be read in the 'sharedStrings.xml'
// t="inlineStr" ,it's means String
// t="b" ,it's means Boolean
// t="e" ,it's means Error
// t="n" ,it's means Number
// t is null ,it's means Empty or Number
CellDataTypeEnum type = CellDataTypeEnum.buildFromCellType(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_T));
xlsxReadSheetHolder.setTempCellData(new CellData(type));
xlsxReadSheetHolder.setTempData(new StringBuilder());
// Put in data transformation information
String dateFormatIndex = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_S);
Integer dateFormatIndexInteger;
if (StringUtils.isEmpty(dateFormatIndex)) {
dateFormatIndexInteger = DEFAULT_FORMAT_INDEX;
} else {
dateFormatIndexInteger = Integer.parseInt(dateFormatIndex);
}
XSSFCellStyle xssfCellStyle =
xlsxReadContext.xlsxReadWorkbookHolder().getStylesTable().getStyleAt(dateFormatIndexInteger);
int dataFormat = xssfCellStyle.getDataFormat();
xlsxReadSheetHolder.getTempCellData().setDataFormat(dataFormat);
xlsxReadSheetHolder.getTempCellData().setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat,
xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale()));
}
}
package com.alibaba.excel.analysis.v07.handlers;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
/**
* Cell Value Handler
*
* @author jipengfei
*/
public class CellValueTagHandler extends AbstractCellValueTagHandler {
@Override
protected void setStringValue(XlsxReadContext xlsxReadContext) {
// Have to go "sharedStrings.xml" and get it
CellData tempCellData = xlsxReadContext.xlsxReadSheetHolder().getTempCellData();
switch (tempCellData.getType()) {
case STRING:
String stringValue = xlsxReadContext.readWorkbookHolder().getReadCache()
.get(Integer.valueOf(tempCellData.getStringValue()));
if (stringValue != null && xlsxReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
stringValue = stringValue.trim();
}
tempCellData.setStringValue(stringValue);
break;
case DIRECT_STRING:
tempCellData.setType(CellDataTypeEnum.STRING);
break;
default:
}
}
}
package com.alibaba.excel.analysis.v07.handlers;
import static com.alibaba.excel.constant.ExcelXmlConstants.DIMENSION;
import static com.alibaba.excel.constant.ExcelXmlConstants.DIMENSION_REF;
import org.xml.sax.Attributes;
import com.alibaba.excel.analysis.v07.XlsxCellHandler;
import com.alibaba.excel.context.AnalysisContext;
/**
* Cell Handler
*
* @author jipengfei
*/
public class CountRowCellHandler implements XlsxCellHandler {
private final AnalysisContext analysisContext;
public CountRowCellHandler(AnalysisContext analysisContext) {
this.analysisContext = analysisContext;
}
@Override
public boolean support(String name) {
return DIMENSION.equals(name);
}
@Override
public void startHandle(String name, Attributes attributes) {
String d = attributes.getValue(DIMENSION_REF);
String totalStr = d.substring(d.indexOf(":") + 1, d.length());
String c = totalStr.toUpperCase().replaceAll("[A-Z]", "");
analysisContext.readSheetHolder().setApproximateTotalRowNumber(Integer.parseInt(c));
}
@Override
public void endHandle(String name) {
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
/**
* Cell Handler
*
* @author jipengfei
*/
public class CountTagHandler extends AbstractXlsxTagHandler {
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
String d = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_REF);
String totalStr = d.substring(d.indexOf(":") + 1, d.length());
String c = totalStr.toUpperCase().replaceAll("[A-Z]", "");
xlsxReadContext.readSheetHolder().setApproximateTotalRowNumber(Integer.parseInt(c));
}
}
package com.alibaba.excel.analysis.v07.handlers;
import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_DATA_FORMAT_TAG;
import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_FORMULA_TAG;
import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG;
import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_TAG;
import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TAG;
import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TYPE_TAG;
import java.math.BigDecimal;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.Map;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.Attributes;
import com.alibaba.excel.analysis.v07.XlsxCellHandler;
import com.alibaba.excel.analysis.v07.XlsxRowResultHolder;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.util.PositionUtils;
/**
* Cell Handler
*
* @author jipengfei
*/
public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder {
private final AnalysisContext analysisContext;
private Deque<String> currentTagDeque = new LinkedList<String>();
private int curCol = -1;
private Map<Integer, CellData> curRowContent = new LinkedHashMap<Integer, CellData>();
private CellData currentCellData;
private StringBuilder dataStringBuilder;
private StringBuilder formulaStringBuilder;
/**
* Current style information
*/
private StylesTable stylesTable;
public DefaultCellHandler(AnalysisContext analysisContext, StylesTable stylesTable) {
this.analysisContext = analysisContext;
this.stylesTable = stylesTable;
}
@Override
public void clearResult() {
curRowContent = new LinkedHashMap<Integer, CellData>();
curCol=-1;
}
@Override
public boolean support(String name) {
return CELL_VALUE_TAG.equals(name) || CELL_FORMULA_TAG.equals(name) || CELL_INLINE_STRING_VALUE_TAG.equals(name)
|| CELL_TAG.equals(name);
}
@Override
public void startHandle(String name, Attributes attributes) {
currentTagDeque.push(name);
// start a cell
if (CELL_TAG.equals(name)) {
curCol = PositionUtils.getCol(attributes.getValue(ExcelXmlConstants.POSITION),curCol);
// t="s" ,it's means String
// t="str" ,it's means String,but does not need to be read in the 'sharedStrings.xml'
// t="inlineStr" ,it's means String
// t="b" ,it's means Boolean
// t="e" ,it's means Error
// t="n" ,it's means Number
// t is null ,it's means Empty or Number
CellDataTypeEnum type = CellDataTypeEnum.buildFromCellType(attributes.getValue(CELL_VALUE_TYPE_TAG));
currentCellData = new CellData(type);
dataStringBuilder = new StringBuilder();
// Put in data transformation information
String dateFormatIndex = attributes.getValue(CELL_DATA_FORMAT_TAG);
if (dateFormatIndex != null) {
int dateFormatIndexInteger = Integer.parseInt(dateFormatIndex);
XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(dateFormatIndexInteger);
int dataFormat = xssfCellStyle.getDataFormat();
String dataFormatString = xssfCellStyle.getDataFormatString();
currentCellData.setDataFormat(dataFormat);
if (dataFormatString == null) {
currentCellData.setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat));
} else {
currentCellData.setDataFormatString(dataFormatString);
}
}
}
// cell is formula
if (CELL_FORMULA_TAG.equals(name)) {
currentCellData.setFormula(Boolean.TRUE);
formulaStringBuilder = new StringBuilder();
}
}
@Override
public void endHandle(String name) {
currentTagDeque.pop();
// cell is formula
if (CELL_FORMULA_TAG.equals(name)) {
currentCellData.setFormulaValue(formulaStringBuilder.toString());
return;
}
if (CELL_VALUE_TAG.equals(name) || CELL_INLINE_STRING_VALUE_TAG.equals(name)) {
CellDataTypeEnum oldType = currentCellData.getType();
switch (oldType) {
case DIRECT_STRING:
case STRING:
case ERROR:
currentCellData.setStringValue(dataStringBuilder.toString());
break;
case BOOLEAN:
currentCellData.setBooleanValue(BooleanUtils.valueOf(dataStringBuilder.toString()));
break;
case NUMBER:
case EMPTY:
currentCellData.setType(CellDataTypeEnum.NUMBER);
currentCellData.setNumberValue(new BigDecimal(dataStringBuilder.toString()));
break;
default:
throw new IllegalStateException("Cannot set values now");
}
if (CELL_VALUE_TAG.equals(name)) {
// Have to go "sharedStrings.xml" and get it
if (currentCellData.getType() == CellDataTypeEnum.STRING) {
String stringValue = analysisContext.readWorkbookHolder().getReadCache()
.get(Integer.valueOf(currentCellData.getStringValue()));
if (stringValue != null
&& analysisContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
stringValue = stringValue.trim();
}
currentCellData.setStringValue(stringValue);
} else if (currentCellData.getType() == CellDataTypeEnum.DIRECT_STRING) {
currentCellData.setType(CellDataTypeEnum.STRING);
}
}
// This is a special form of string
if (CELL_INLINE_STRING_VALUE_TAG.equals(name)) {
XSSFRichTextString richTextString = new XSSFRichTextString(currentCellData.getStringValue());
String stringValue = richTextString.toString();
if (stringValue != null && analysisContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
stringValue = stringValue.trim();
}
currentCellData.setStringValue(stringValue);
}
currentCellData.checkEmpty();
curRowContent.put(curCol, currentCellData);
}
}
@Override
public void appendCurrentCellValue(char[] ch, int start, int length) {
String currentTag = currentTagDeque.peek();
if (currentTag == null) {
return;
}
if (CELL_FORMULA_TAG.equals(currentTag)) {
formulaStringBuilder.append(ch, start, length);
return;
}
if (!CELL_VALUE_TAG.equals(currentTag) && !CELL_INLINE_STRING_VALUE_TAG.equals(currentTag)) {
return;
}
dataStringBuilder.append(ch, start, length);
}
@Override
public Map<Integer, CellData> getCurRowContent() {
return curRowContent;
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.util.StringUtils;
/**
* Cell Handler
*
* @author Jiaju Zhuang
*/
public class HyperlinkTagHandler extends AbstractXlsxTagHandler {
@Override
public boolean support(XlsxReadContext xlsxReadContext) {
return xlsxReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.HYPERLINK);
}
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
String ref = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_REF);
String location = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_LOCATION);
if (StringUtils.isEmpty(ref)) {
return;
}
CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.HYPERLINK, location, ref);
xlsxReadContext.readSheetHolder().setCellExtra(cellExtra);
xlsxReadContext.analysisEventProcessor().extra(xlsxReadContext);
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.util.StringUtils;
/**
* Cell Handler
*
* @author Jiaju Zhuang
*/
public class MergeCellTagHandler extends AbstractXlsxTagHandler {
@Override
public boolean support(XlsxReadContext xlsxReadContext) {
return xlsxReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.MERGE);
}
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
String ref = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_REF);
if (StringUtils.isEmpty(ref)) {
return;
}
CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.MERGE, null, ref);
xlsxReadContext.readSheetHolder().setCellExtra(cellExtra);
xlsxReadContext.analysisEventProcessor().extra(xlsxReadContext);
}
}
package com.alibaba.excel.analysis.v07.handlers;
import static com.alibaba.excel.constant.ExcelXmlConstants.ROW_TAG;
import org.xml.sax.Attributes;
import com.alibaba.excel.analysis.v07.XlsxCellHandler;
import com.alibaba.excel.analysis.v07.XlsxRowResultHolder;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.event.EachRowAnalysisFinishEvent;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.util.PositionUtils;
/**
* Cell Handler
*
* @author jipengfei
*/
public class ProcessResultCellHandler implements XlsxCellHandler {
private AnalysisContext analysisContext;
private XlsxRowResultHolder rowResultHandler;
private int currentRow = -1;
public ProcessResultCellHandler(AnalysisContext analysisContext, XlsxRowResultHolder rowResultHandler) {
this.analysisContext = analysisContext;
this.rowResultHandler = rowResultHandler;
}
@Override
public boolean support(String name) {
return ROW_TAG.equals(name);
}
@Override
public void startHandle(String name, Attributes attributes) {
currentRow = PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.POSITION),currentRow);
analysisContext.readRowHolder(
new ReadRowHolder(currentRow, analysisContext.readSheetHolder().getGlobalConfiguration()));
}
@Override
public void endHandle(String name) {
analysisContext.readSheetHolder()
.notifyEndOneRow(new EachRowAnalysisFinishEvent(rowResultHandler.getCurRowContent()), analysisContext);
rowResultHandler.clearResult();
}
}
package com.alibaba.excel.analysis.v07.handlers;
import java.util.LinkedHashMap;
import org.xml.sax.Attributes;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.RowTypeEnum;
import com.alibaba.excel.metadata.Cell;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.util.PositionUtils;
/**
* Cell Handler
*
* @author jipengfei
*/
public class RowTagHandler extends AbstractXlsxTagHandler {
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
int rowIndex = PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.ATTRIBUTE_R),
xlsxReadSheetHolder.getRowIndex());
Integer lastRowIndex = xlsxReadContext.readSheetHolder().getRowIndex();
if (lastRowIndex != null) {
while (lastRowIndex + 1 < rowIndex) {
xlsxReadContext.readRowHolder(new ReadRowHolder(lastRowIndex + 1, RowTypeEnum.EMPTY,
xlsxReadSheetHolder.getGlobalConfiguration(), new LinkedHashMap<Integer, Cell>()));
xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext);
xlsxReadSheetHolder.setColumnIndex(null);
xlsxReadSheetHolder.setCellMap(new LinkedHashMap<Integer, Cell>());
lastRowIndex++;
}
}
xlsxReadSheetHolder.setRowIndex(rowIndex);
}
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
xlsxReadContext.readRowHolder(new ReadRowHolder(xlsxReadSheetHolder.getRowIndex(), RowTypeEnum.DATA,
xlsxReadSheetHolder.getGlobalConfiguration(), xlsxReadSheetHolder.getCellMap()));
xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext);
xlsxReadSheetHolder.setColumnIndex(null);
xlsxReadSheetHolder.setCellMap(new LinkedHashMap<Integer, Cell>());
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
/**
* Tag handler
*
* @author Dan Zheng
*/
public interface XlsxTagHandler {
/**
* Whether to support
*
* @param xlsxReadContext
* @return
*/
boolean support(XlsxReadContext xlsxReadContext);
/**
* Start handle
*
* @param xlsxReadContext
* xlsxReadContext
* @param name
* Tag name
* @param attributes
* Tag attributes
*/
void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes);
/**
* End handle
*
* @param xlsxReadContext
* xlsxReadContext
* @param name
* Tag name
*/
void endElement(XlsxReadContext xlsxReadContext, String name);
/**
* Read data
*
* @param xlsxReadContext
* @param ch
* @param start
* @param length
*/
void characters(XlsxReadContext xlsxReadContext, char[] ch, int start, int length);
}
package com.alibaba.excel.analysis.v07;
package com.alibaba.excel.analysis.v07.handlers.sax;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
......
package com.alibaba.excel.analysis.v07.handlers.sax;
import java.util.HashMap;
import java.util.Map;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import com.alibaba.excel.analysis.v07.handlers.CellFormulaTagHandler;
import com.alibaba.excel.analysis.v07.handlers.CellInlineStringValueTagHandler;
import com.alibaba.excel.analysis.v07.handlers.CellTagHandler;
import com.alibaba.excel.analysis.v07.handlers.CellValueTagHandler;
import com.alibaba.excel.analysis.v07.handlers.CountTagHandler;
import com.alibaba.excel.analysis.v07.handlers.HyperlinkTagHandler;
import com.alibaba.excel.analysis.v07.handlers.MergeCellTagHandler;
import com.alibaba.excel.analysis.v07.handlers.RowTagHandler;
import com.alibaba.excel.analysis.v07.handlers.XlsxTagHandler;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
/**
* @author jipengfei
*/
public class XlsxRowHandler extends DefaultHandler {
private XlsxReadContext xlsxReadContext;
private static final Map<String, XlsxTagHandler> XLSX_CELL_HANDLER_MAP = new HashMap<String, XlsxTagHandler>(32);
static {
CellFormulaTagHandler cellFormulaTagHandler = new CellFormulaTagHandler();
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_FORMULA_TAG, cellFormulaTagHandler);
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_FORMULA_TAG, cellFormulaTagHandler);
CellInlineStringValueTagHandler cellInlineStringValueTagHandler = new CellInlineStringValueTagHandler();
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler);
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_INLINE_STRING_VALUE_TAG, cellInlineStringValueTagHandler);
CellTagHandler cellTagHandler = new CellTagHandler();
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_TAG, cellTagHandler);
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_TAG, cellTagHandler);
CellValueTagHandler cellValueTagHandler = new CellValueTagHandler();
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_VALUE_TAG, cellValueTagHandler);
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_CELL_VALUE_TAG, cellValueTagHandler);
CountTagHandler countTagHandler = new CountTagHandler();
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.DIMENSION_TAG, countTagHandler);
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_DIMENSION_TAG, countTagHandler);
HyperlinkTagHandler hyperlinkTagHandler = new HyperlinkTagHandler();
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.HYPERLINK_TAG, hyperlinkTagHandler);
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_HYPERLINK_TAG, hyperlinkTagHandler);
MergeCellTagHandler mergeCellTagHandler = new MergeCellTagHandler();
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.MERGE_CELL_TAG, mergeCellTagHandler);
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_MERGE_CELL_TAG, mergeCellTagHandler);
RowTagHandler rowTagHandler = new RowTagHandler();
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.ROW_TAG, rowTagHandler);
XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.X_ROW_TAG, rowTagHandler);
}
public XlsxRowHandler(XlsxReadContext xlsxReadContext) {
this.xlsxReadContext = xlsxReadContext;
}
@Override
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
XlsxTagHandler handler = XLSX_CELL_HANDLER_MAP.get(name);
if (handler == null || !handler.support(xlsxReadContext)) {
return;
}
xlsxReadContext.xlsxReadSheetHolder().getTagDeque().push(name);
handler.startElement(xlsxReadContext, name, attributes);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String currentTag = xlsxReadContext.xlsxReadSheetHolder().getTagDeque().peek();
if (currentTag == null) {
return;
}
XlsxTagHandler handler = XLSX_CELL_HANDLER_MAP.get(currentTag);
if (handler == null || !handler.support(xlsxReadContext)) {
return;
}
handler.characters(xlsxReadContext, ch, start, length);
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
XlsxTagHandler handler = XLSX_CELL_HANDLER_MAP.get(name);
if (handler == null || !handler.support(xlsxReadContext)) {
return;
}
handler.endElement(xlsxReadContext, name);
xlsxReadContext.xlsxReadSheetHolder().getTagDeque().pop();
}
}
package com.alibaba.excel.annotation.write.style;
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 org.apache.poi.common.usermodel.fonts.FontCharset;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
/**
* Custom content styles.
*
* @author Jiaju Zhuang
*/
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ContentFontStyle {
/**
* The name for the font (i.e. Arial)
*/
String fontName() default "";
/**
* Height in the familiar unit of measure - points
*/
short fontHeightInPoints() default -1;
/**
* Whether to use italics or not
*/
boolean italic() default false;
/**
* Whether to use a strikeout horizontal line through the text or not
*/
boolean strikeout() default false;
/**
* The color for the font
*
* @see Font#COLOR_NORMAL
* @see Font#COLOR_RED
* @see HSSFPalette#getColor(short)
* @see IndexedColors
*/
short color() default -1;
/**
* Set normal,super or subscript.
*
* @see Font#SS_NONE
* @see Font#SS_SUPER
* @see Font#SS_SUB
*/
short typeOffset() default -1;
/**
* set type of text underlining to use
*
* @see Font#U_NONE
* @see Font#U_SINGLE
* @see Font#U_DOUBLE
* @see Font#U_SINGLE_ACCOUNTING
* @see Font#U_DOUBLE_ACCOUNTING
*/
byte underline() default -1;
/**
* Set character-set to use.
*
* @see FontCharset
* @see Font#ANSI_CHARSET
* @see Font#DEFAULT_CHARSET
* @see Font#SYMBOL_CHARSET
*/
int charset() default -1;
/**
* Bold
*/
boolean bold() default false;
}
package com.alibaba.excel.annotation.write.style;
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;
/**
* The regions of the loop merge
*
* @author Jiaju Zhuang
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ContentLoopMerge {
/**
* Each row
*
* @return
*/
int eachRow() default -1;
/**
* Extend column
*
* @return
*/
int columnExtend() default 1;
}
package com.alibaba.excel.annotation.write.style;
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 org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IgnoredErrorType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
/**
* Custom content styles
*
* @author Jiaju Zhuang
*/
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ContentStyle {
/**
* Set the data format (must be a valid format). Built in formats are defined at {@link BuiltinFormats}.
*/
short dataFormat() default -1;
/**
* Set the cell's using this style to be hidden
*/
boolean hidden() default false;
/**
* Set the cell's using this style to be locked
*/
boolean locked() default false;
/**
* Turn on or off "Quote Prefix" or "123 Prefix" for the style, which is used to tell Excel that the thing which
* looks like a number or a formula shouldn't be treated as on. Turning this on is somewhat (but not completely, see
* {@link IgnoredErrorType}) like prefixing the cell value with a ' in Excel
*/
boolean quotePrefix() default false;
/**
* Set the type of horizontal alignment for the cell
*/
HorizontalAlignment horizontalAlignment() default HorizontalAlignment.GENERAL;
/**
* Set whether the text should be wrapped. Setting this flag to <code>true</code> make all content visible within a
* cell by displaying it on multiple lines
*
*/
boolean wrapped() default false;
/**
* Set the type of vertical alignment for the cell
*/
VerticalAlignment verticalAlignment() default VerticalAlignment.CENTER;
/**
* Set the degree of rotation for the text in the cell.
*
* Note: HSSF uses values from -90 to 90 degrees, whereas XSSF uses values from 0 to 180 degrees. The
* implementations of this method will map between these two value-ranges accordingly, however the corresponding
* getter is returning values in the range mandated by the current type of Excel file-format that this CellStyle is
* applied to.
*/
short rotation() default -1;
/**
* Set the number of spaces to indent the text in the cell
*/
short indent() default -1;
/**
* Set the type of border to use for the left border of the cell
*/
BorderStyle borderLeft() default BorderStyle.NONE;
/**
* Set the type of border to use for the right border of the cell
*/
BorderStyle borderRight() default BorderStyle.NONE;
/**
* Set the type of border to use for the top border of the cell
*/
BorderStyle borderTop() default BorderStyle.NONE;
/**
* Set the type of border to use for the bottom border of the cell
*/
BorderStyle borderBottom() default BorderStyle.NONE;
/**
* Set the color to use for the left border
*
* @see IndexedColors
*/
short leftBorderColor() default -1;
/**
* Set the color to use for the right border
*
* @see IndexedColors
*
*/
short rightBorderColor() default -1;
/**
* Set the color to use for the top border
*
* @see IndexedColors
*
*/
short topBorderColor() default -1;
/**
* Set the color to use for the bottom border
*
* @see IndexedColors
*
*/
short bottomBorderColor() default -1;
/**
* Setting to one fills the cell with the foreground color... No idea about other values
*
* @see FillPatternType#SOLID_FOREGROUND
*/
FillPatternType fillPatternType() default FillPatternType.NO_FILL;
/**
* Set the background fill color.
*
* @see IndexedColors
*
*/
short fillBackgroundColor() default -1;
/**
* Set the foreground fill color <i>Note: Ensure Foreground color is set prior to background color.</i>
*
* @see IndexedColors
*
*/
short fillForegroundColor() default -1;
/**
* Controls if the Cell should be auto-sized to shrink to fit if the text is too long
*/
boolean shrinkToFit() default false;
}
package com.alibaba.excel.annotation.write.style;
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 org.apache.poi.common.usermodel.fonts.FontCharset;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.IndexedColors;
/**
* Custom header styles.
*
* @author Jiaju Zhuang
*/
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface HeadFontStyle {
/**
* The name for the font (i.e. Arial)
*/
String fontName() default "宋体";
/**
* Height in the familiar unit of measure - points
*/
short fontHeightInPoints() default 14;
/**
* Whether to use italics or not
*/
boolean italic() default false;
/**
* Whether to use a strikeout horizontal line through the text or not
*/
boolean strikeout() default false;
/**
* The color for the font
*
* @see Font#COLOR_NORMAL
* @see Font#COLOR_RED
* @see HSSFPalette#getColor(short)
* @see IndexedColors
*/
short color() default -1;
/**
* Set normal,super or subscript.
*
* @see Font#SS_NONE
* @see Font#SS_SUPER
* @see Font#SS_SUB
*/
short typeOffset() default -1;
/**
* set type of text underlining to use
*
* @see Font#U_NONE
* @see Font#U_SINGLE
* @see Font#U_DOUBLE
* @see Font#U_SINGLE_ACCOUNTING
* @see Font#U_DOUBLE_ACCOUNTING
*/
byte underline() default -1;
/**
* Set character-set to use.
*
* @see FontCharset
* @see Font#ANSI_CHARSET
* @see Font#DEFAULT_CHARSET
* @see Font#SYMBOL_CHARSET
*/
int charset() default -1;
/**
* Bold
*/
boolean bold() default true;
}
package com.alibaba.excel.annotation.write.style;
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 org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IgnoredErrorType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.VerticalAlignment;
/**
* Custom header styles
*
* @author Jiaju Zhuang
*/
@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface HeadStyle {
/**
* Set the data format (must be a valid format). Built in formats are defined at {@link BuiltinFormats}.
*/
short dataFormat() default -1;
/**
* Set the cell's using this style to be hidden
*/
boolean hidden() default false;
/**
* Set the cell's using this style to be locked
*/
boolean locked() default true;
/**
* Turn on or off "Quote Prefix" or "123 Prefix" for the style, which is used to tell Excel that the thing which
* looks like a number or a formula shouldn't be treated as on. Turning this on is somewhat (but not completely, see
* {@link IgnoredErrorType}) like prefixing the cell value with a ' in Excel
*/
boolean quotePrefix() default false;
/**
* Set the type of horizontal alignment for the cell
*/
HorizontalAlignment horizontalAlignment() default HorizontalAlignment.CENTER;
/**
* Set whether the text should be wrapped. Setting this flag to <code>true</code> make all content visible within a
* cell by displaying it on multiple lines
*
*/
boolean wrapped() default true;
/**
* Set the type of vertical alignment for the cell
*/
VerticalAlignment verticalAlignment() default VerticalAlignment.CENTER;
/**
* Set the degree of rotation for the text in the cell.
*
* Note: HSSF uses values from -90 to 90 degrees, whereas XSSF uses values from 0 to 180 degrees. The
* implementations of this method will map between these two value-ranges accordingly, however the corresponding
* getter is returning values in the range mandated by the current type of Excel file-format that this CellStyle is
* applied to.
*/
short rotation() default -1;
/**
* Set the number of spaces to indent the text in the cell
*/
short indent() default -1;
/**
* Set the type of border to use for the left border of the cell
*/
BorderStyle borderLeft() default BorderStyle.THIN;
/**
* Set the type of border to use for the right border of the cell
*/
BorderStyle borderRight() default BorderStyle.THIN;
/**
* Set the type of border to use for the top border of the cell
*/
BorderStyle borderTop() default BorderStyle.THIN;
/**
* Set the type of border to use for the bottom border of the cell
*/
BorderStyle borderBottom() default BorderStyle.THIN;
/**
* Set the color to use for the left border
*
* @see IndexedColors
*/
short leftBorderColor() default -1;
/**
* Set the color to use for the right border
*
* @see IndexedColors
*
*/
short rightBorderColor() default -1;
/**
* Set the color to use for the top border
*
* @see IndexedColors
*
*/
short topBorderColor() default -1;
/**
* Set the color to use for the bottom border
*
* @see IndexedColors
*
*/
short bottomBorderColor() default -1;
/**
* Setting to one fills the cell with the foreground color... No idea about other values
*
* @see FillPatternType#SOLID_FOREGROUND
*/
FillPatternType fillPatternType() default FillPatternType.SOLID_FOREGROUND;
/**
* Set the background fill color.
*
* @see IndexedColors
*
*/
short fillBackgroundColor() default -1;
/**
* Set the foreground fill color <i>Note: Ensure Foreground color is set prior to background color.</i>
*
* @see IndexedColors
*
*/
short fillForegroundColor() default -1;
/**
* Controls if the Cell should be auto-sized to shrink to fit if the text is too long
*/
boolean shrinkToFit() default false;
}
package com.alibaba.excel.annotation.write.style;
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;
/**
* Merge the cells once
*
* @author Jiaju Zhuang
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnceAbsoluteMerge {
/**
* First row
*
* @return
*/
int firstRowIndex() default -1;
/**
* Last row
*
* @return
*/
int lastRowIndex() default -1;
/**
* First column
*
* @return
*/
int firstColumnIndex() default -1;
/**
* Last row
*
* @return
*/
int lastColumnIndex() default -1;
}
package com.alibaba.excel.cache;
import org.apache.poi.hssf.record.SSTRecord;
import com.alibaba.excel.context.AnalysisContext;
/**
*
* Use SSTRecord.
*
* @author Jiaju Zhuang
*/
public class XlsCache implements ReadCache {
private SSTRecord sstRecord;
public XlsCache(SSTRecord sstRecord) {
this.sstRecord = sstRecord;
}
@Override
public void init(AnalysisContext analysisContext) {}
@Override
public void put(String value) {}
@Override
public String get(Integer key) {
return sstRecord.getString(key).toString();
}
@Override
public void putFinished() {}
@Override
public void destroy() {}
}
package com.alibaba.excel.constant;
import java.util.Locale;
/**
* Excel's built-in format conversion.Currently only supports Chinese.
*
* <p>
* If it is not Chinese, it is recommended to directly modify the builtinFormats, which will better support
* internationalization in the future.
*
* <p>
* Specific correspondence please see:
* https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.numberingformat?view=openxml-2.8.1
*
* @author Jiaju Zhuang
**/
public class BuiltinFormats {
private static final String[] BUILTIN_FORMATS_CN = {
// 0
"General",
// 1
"0",
// 2
"0.00",
// 3
"#,##0",
// 4
"#,##0.00",
// 5
"\"¥\"#,##0_);(\"¥\"#,##0)",
// 6
"\"¥\"#,##0_);[Red](\"¥\"#,##0)",
// 7
"\"¥\"#,##0.00_);(\"¥\"#,##0.00)",
// 8
"\"¥\"#,##0.00_);[Red](\"¥\"#,##0.00)",
// 9
"0%",
// 10
"0.00%",
// 11
"0.00E+00",
// 12
"# ?/?",
// 13
"# ??/??",
// 14
// The official documentation shows "m/d/yy", but the actual test is "yyyy/m/d".
"yyyy/m/d",
// 15
"d-mmm-yy",
// 16
"d-mmm",
// 17
"mmm-yy",
// 18
"h:mm AM/PM",
// 19
"h:mm:ss AM/PM",
// 20
"h:mm",
// 21
"h:mm:ss",
// 22
// The official documentation shows "m/d/yy h:mm", but the actual test is "yyyy-m-d h:mm".
"yyyy-m-d h:mm",
// 23-26 No specific correspondence found in the official documentation.
// 23
null,
// 24
null,
// 25
null,
// 26
null,
// 27
"yyyy\"年\"m\"月\"",
// 28
"m\"月\"d\"日\"",
// 29
"m\"月\"d\"日\"",
// 30
"m-d-yy",
// 31
"yyyy\"年\"m\"月\"d\"日\"",
// 32
"h\"时\"mm\"分\"",
// 33
"h\"时\"mm\"分\"ss\"秒\"",
// 34
"上午/下午h\"时\"mm\"分\"",
// 35
"上午/下午h\"时\"mm\"分\"ss\"秒\"",
// 36
"yyyy\"年\"m\"月\"",
// 37
"#,##0_);(#,##0)",
// 38
"#,##0_);[Red](#,##0)",
// 39
"#,##0.00_);(#,##0.00)",
// 40
"#,##0.00_);[Red](#,##0.00)",
// 41
"_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)",
// 42
"_(\"¥\"* #,##0_);_(\"¥\"* (#,##0);_(\"¥\"* \"-\"_);_(@_)",
// 43
"_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)",
// 44
"_(\"¥\"* #,##0.00_);_(\"¥\"* (#,##0.00);_(\"¥\"* \"-\"??_);_(@_)",
// 45
"mm:ss",
// 46
"[h]:mm:ss",
// 47
"mm:ss.0",
// 48
"##0.0E+0",
// 49
"@",
// 50
"yyyy\"年\"m\"月\"",
// 51
"m\"月\"d\"日\"",
// 52
"yyyy\"年\"m\"月\"",
// 53
"m\"月\"d\"日\"",
// 54
"m\"月\"d\"日\"",
// 55
"上午/下午h\"时\"mm\"分\"",
// 56
"上午/下午h\"时\"mm\"分\"ss\"秒\"",
// 57
"yyyy\"年\"m\"月\"",
// 58
"m\"月\"d\"日\"",
// 59
"t0",
// 60
"t0.00",
// 61
"t#,##0",
// 62
"t#,##0.00",
// 63-66 No specific correspondence found in the official documentation.
// 63
null,
// 64
null,
// 65
null,
// 66
null,
// 67
"t0%",
// 68
"t0.00%",
// 69
"t# ?/?",
// 70
"t# ??/??",
// 71
"ว/ด/ปปปป",
// 72
"ว-ดดด-ปป",
// 73
"ว-ดดด",
// 74
"ดดด-ปป",
// 75
"ช:นน",
// 76
"ช:นน:ทท",
// 77
"ว/ด/ปปปป ช:นน",
// 78
"นน:ทท",
// 79
"[ช]:นน:ทท",
// 80
"นน:ทท.0",
// 81
"d/m/bb",
// end
};
private static final String[] BUILTIN_FORMATS_US = {
// 0
"General",
// 1
"0",
// 2
"0.00",
// 3
"#,##0",
// 4
"#,##0.00",
// 5
"\"$\"#,##0_);(\"$\"#,##0)",
// 6
"\"$\"#,##0_);[Red](\"$\"#,##0)",
// 7
"\"$\"#,##0.00_);(\"$\"#,##0.00)",
// 8
"\"$\"#,##0.00_);[Red](\"$\"#,##0.00)",
// 9
"0%",
// 10
"0.00%",
// 11
"0.00E+00",
// 12
"# ?/?",
// 13
"# ??/??",
// 14
// The official documentation shows "m/d/yy", but the actual test is "yyyy/m/d".
"yyyy/m/d",
// 15
"d-mmm-yy",
// 16
"d-mmm",
// 17
"mmm-yy",
// 18
"h:mm AM/PM",
// 19
"h:mm:ss AM/PM",
// 20
"h:mm",
// 21
"h:mm:ss",
// 22
// The official documentation shows "m/d/yy h:mm", but the actual test is "yyyy-m-d h:mm".
"yyyy-m-d h:mm",
// 23-26 No specific correspondence found in the official documentation.
// 23
null,
// 24
null,
// 25
null,
// 26
null,
// 27
"yyyy\"年\"m\"月\"",
// 28
"m\"月\"d\"日\"",
// 29
"m\"月\"d\"日\"",
// 30
"m-d-yy",
// 31
"yyyy\"年\"m\"月\"d\"日\"",
// 32
"h\"时\"mm\"分\"",
// 33
"h\"时\"mm\"分\"ss\"秒\"",
// 34
"上午/下午h\"时\"mm\"分\"",
// 35
"上午/下午h\"时\"mm\"分\"ss\"秒\"",
// 36
"yyyy\"年\"m\"月\"",
// 37
"#,##0_);(#,##0)",
// 38
"#,##0_);[Red](#,##0)",
// 39
"#,##0.00_);(#,##0.00)",
// 40
"#,##0.00_);[Red](#,##0.00)",
// 41
"_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)",
// 42
"_(\"$\"* #,##0_);_(\"$\"* (#,##0);_(\"$\"* \"-\"_);_(@_)",
// 43
"_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)",
// 44
"_(\"$\"* #,##0.00_);_(\"$\"* (#,##0.00);_(\"$\"* \"-\"??_);_(@_)",
// 45
"mm:ss",
// 46
"[h]:mm:ss",
// 47
"mm:ss.0",
// 48
"##0.0E+0",
// 49
"@",
// 50
"yyyy\"年\"m\"月\"",
// 51
"m\"月\"d\"日\"",
// 52
"yyyy\"年\"m\"月\"",
// 53
"m\"月\"d\"日\"",
// 54
"m\"月\"d\"日\"",
// 55
"上午/下午h\"时\"mm\"分\"",
// 56
"上午/下午h\"时\"mm\"分\"ss\"秒\"",
// 57
"yyyy\"年\"m\"月\"",
// 58
"m\"月\"d\"日\"",
// 59
"t0",
// 60
"t0.00",
// 61
"t#,##0",
// 62
"t#,##0.00",
// 63-66 No specific correspondence found in the official documentation.
// 63
null,
// 64
null,
// 65
null,
// 66
null,
// 67
"t0%",
// 68
"t0.00%",
// 69
"t# ?/?",
// 70
"t# ??/??",
// 71
"ว/ด/ปปปป",
// 72
"ว-ดดด-ปป",
// 73
"ว-ดดด",
// 74
"ดดด-ปป",
// 75
"ช:นน",
// 76
"ช:นน:ทท",
// 77
"ว/ด/ปปปป ช:นน",
// 78
"นน:ทท",
// 79
"[ช]:นน:ทท",
// 80
"นน:ทท.0",
// 81
"d/m/bb",
// end
};
public static String getBuiltinFormat(Integer index, String defaultFormat, Locale locale) {
String[] builtinFormat = switchBuiltinFormats(locale);
if (index == null || index < 0 || index >= builtinFormat.length) {
return defaultFormat;
}
return builtinFormat[index];
}
private static String[] switchBuiltinFormats(Locale locale) {
if (locale != null && Locale.US.getCountry().equals(locale.getCountry())) {
return BUILTIN_FORMATS_US;
}
return BUILTIN_FORMATS_CN;
}
}
......@@ -4,22 +4,54 @@ package com.alibaba.excel.constant;
* @author jipengfei
*/
public class ExcelXmlConstants {
public static final String DIMENSION = "dimension";
public static final String DIMENSION_REF = "ref";
public static final String POSITION = "r";
public static final String DIMENSION_TAG = "dimension";
public static final String ROW_TAG = "row";
public static final String CELL_TAG = "c";
public static final String CELL_VALUE_TYPE_TAG = "t";
/**
* Number formatted label
*/
public static final String CELL_DATA_FORMAT_TAG = "s";
public static final String CELL_FORMULA_TAG = "f";
public static final String CELL_VALUE_TAG = "v";
/**
* When the data is "inlineStr" his tag is "t"
*/
public static final String CELL_INLINE_STRING_VALUE_TAG = "t";
public static final String CELL_TAG = "c";
public static final String MERGE_CELL_TAG = "mergeCell";
public static final String HYPERLINK_TAG = "hyperlink";
public static final String X_DIMENSION_TAG = "x:dimension";
public static final String X_ROW_TAG = "x:row";
public static final String X_CELL_FORMULA_TAG = "x:f";
public static final String X_CELL_VALUE_TAG = "x:v";
/**
* When the data is "inlineStr" his tag is "t"
*/
public static final String X_CELL_INLINE_STRING_VALUE_TAG = "x:t";
public static final String X_CELL_TAG = "x:c";
public static final String X_MERGE_CELL_TAG = "x:mergeCell";
public static final String X_HYPERLINK_TAG = "x:hyperlink";
/**
* s attribute
*/
public static final String ATTRIBUTE_S = "s";
/**
* ref attribute
*/
public static final String ATTRIBUTE_REF = "ref";
/**
* r attribute
*/
public static final String ATTRIBUTE_R = "r";
/**
* t attribute
*/
public static final String ATTRIBUTE_T = "t";
/**
* location attribute
*/
public static final String ATTRIBUTE_LOCATION = "location";
/**
* Cell range split
*/
public static final String CELL_RANGE_SPLIT = ":";
}
package com.alibaba.excel.context;
import java.io.InputStream;
import java.util.List;
import com.alibaba.excel.analysis.ExcelReadExecutor;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.read.metadata.ReadSheet;
......@@ -10,6 +10,7 @@ import com.alibaba.excel.read.metadata.holder.ReadHolder;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import com.alibaba.excel.read.processor.AnalysisEventProcessor;
import com.alibaba.excel.support.ExcelTypeEnum;
/**
......@@ -70,6 +71,27 @@ public interface AnalysisContext {
*/
Object getCustom();
/**
* Event processor
*
* @return
*/
AnalysisEventProcessor analysisEventProcessor();
/**
* Data that the customer needs to read
*
* @return
*/
List<ReadSheet> readSheetList();
/**
* Data that the customer needs to read
*
* @param readSheetList
*/
void readSheetList(List<ReadSheet> readSheetList);
/**
* get current sheet
*
......
package com.alibaba.excel.context;
import java.io.InputStream;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -13,6 +14,12 @@ import com.alibaba.excel.read.metadata.holder.ReadHolder;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.read.metadata.holder.ReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder;
import com.alibaba.excel.read.processor.AnalysisEventProcessor;
import com.alibaba.excel.read.processor.DefaultAnalysisEventProcessor;
import com.alibaba.excel.support.ExcelTypeEnum;
/**
......@@ -37,13 +44,27 @@ public class AnalysisContextImpl implements AnalysisContext {
* Configuration of currently operated cell
*/
private ReadHolder currentReadHolder;
/**
* Event processor
*/
private AnalysisEventProcessor analysisEventProcessor;
public AnalysisContextImpl(ReadWorkbook readWorkbook) {
public AnalysisContextImpl(ReadWorkbook readWorkbook, ExcelTypeEnum actualExcelType) {
if (readWorkbook == null) {
throw new IllegalArgumentException("Workbook argument cannot be null");
}
readWorkbookHolder = new ReadWorkbookHolder(readWorkbook);
switch (actualExcelType) {
case XLS:
readWorkbookHolder = new XlsReadWorkbookHolder(readWorkbook);
break;
case XLSX:
readWorkbookHolder = new XlsxReadWorkbookHolder(readWorkbook);
break;
default:
break;
}
currentReadHolder = readWorkbookHolder;
analysisEventProcessor = new DefaultAnalysisEventProcessor();
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Initialization 'AnalysisContextImpl' complete");
}
......@@ -51,7 +72,16 @@ public class AnalysisContextImpl implements AnalysisContext {
@Override
public void currentSheet(ReadSheet readSheet) {
readSheetHolder = new ReadSheetHolder(readSheet, readWorkbookHolder);
switch (readWorkbookHolder.getExcelType()) {
case XLS:
readSheetHolder = new XlsReadSheetHolder(readSheet, readWorkbookHolder);
break;
case XLSX:
readSheetHolder = new XlsxReadSheetHolder(readSheet, readWorkbookHolder);
break;
default:
break;
}
currentReadHolder = readSheetHolder;
if (readWorkbookHolder.getHasReadSheet().contains(readSheetHolder.getSheetNo())) {
throw new ExcelAnalysisException("Cannot read sheet repeatedly.");
......@@ -92,6 +122,21 @@ public class AnalysisContextImpl implements AnalysisContext {
return readWorkbookHolder.getCustomObject();
}
@Override
public AnalysisEventProcessor analysisEventProcessor() {
return analysisEventProcessor;
}
@Override
public List<ReadSheet> readSheetList() {
return null;
}
@Override
public void readSheetList(List<ReadSheet> readSheetList) {
}
@Override
public Sheet getCurrentSheet() {
Sheet sheet = new Sheet(readSheetHolder.getSheetNo() + 1);
......
......@@ -27,7 +27,9 @@ import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.FileUtils;
import com.alibaba.excel.util.NumberDataFormatterUtils;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.util.WriteHandlerUtils;
......@@ -307,7 +309,6 @@ public class WriteContextImpl implements WriteContext {
throwable = t;
}
}
if (!isOutputStreamEncrypt) {
try {
if (writeExcel) {
......@@ -318,7 +319,6 @@ public class WriteContextImpl implements WriteContext {
throwable = t;
}
}
try {
Workbook workbook = writeWorkbookHolder.getWorkbook();
if (workbook instanceof SXSSFWorkbook) {
......@@ -327,7 +327,6 @@ public class WriteContextImpl implements WriteContext {
} catch (Throwable t) {
throwable = t;
}
try {
if (writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getOutputStream() != null) {
writeWorkbookHolder.getOutputStream().close();
......@@ -335,7 +334,6 @@ public class WriteContextImpl implements WriteContext {
} catch (Throwable t) {
throwable = t;
}
if (writeExcel && !isOutputStreamEncrypt) {
try {
doFileEncrypt07();
......@@ -343,7 +341,6 @@ public class WriteContextImpl implements WriteContext {
throwable = t;
}
}
try {
if (writeWorkbookHolder.getTempTemplateInputStream() != null) {
writeWorkbookHolder.getTempTemplateInputStream().close();
......@@ -351,18 +348,21 @@ public class WriteContextImpl implements WriteContext {
} catch (Throwable t) {
throwable = t;
}
clearEncrypt03();
removeThreadLocalCache();
if (throwable != null) {
throw new ExcelGenerateException("Can not close IO.", throwable);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Finished write.");
}
}
private void removeThreadLocalCache() {
NumberDataFormatterUtils.removeThreadLocalCache();
DateUtils.removeThreadLocalCache();
}
@Override
public Sheet getCurrentSheet() {
return writeSheetHolder.getSheet();
......
package com.alibaba.excel.context.xls;
import com.alibaba.excel.context.AnalysisContextImpl;
import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder;
import com.alibaba.excel.support.ExcelTypeEnum;
/**
*
* A context is the main anchorage point of a ls xls reader.
*
* @author Jiaju Zhuang
*/
public class DefaultXlsReadContext extends AnalysisContextImpl implements XlsReadContext {
public DefaultXlsReadContext(ReadWorkbook readWorkbook, ExcelTypeEnum actualExcelType) {
super(readWorkbook, actualExcelType);
}
@Override
public XlsReadWorkbookHolder xlsReadWorkbookHolder() {
return (XlsReadWorkbookHolder)readWorkbookHolder();
}
@Override
public XlsReadSheetHolder xlsReadSheetHolder() {
return (XlsReadSheetHolder)readSheetHolder();
}
}
package com.alibaba.excel.context.xls;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder;
/**
* A context is the main anchorage point of a ls xls reader.
*
* @author Jiaju Zhuang
**/
public interface XlsReadContext extends AnalysisContext {
/**
* All information about the workbook you are currently working on.
*
* @return Current workbook holder
*/
XlsReadWorkbookHolder xlsReadWorkbookHolder();
/**
* All information about the sheet you are currently working on.
*
* @return Current sheet holder
*/
XlsReadSheetHolder xlsReadSheetHolder();
}
package com.alibaba.excel.context.xlsx;
import com.alibaba.excel.context.AnalysisContextImpl;
import com.alibaba.excel.read.metadata.ReadWorkbook;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder;
import com.alibaba.excel.support.ExcelTypeEnum;
/**
*
* A context is the main anchorage point of a ls xls reader.
*
* @author Jiaju Zhuang
*/
public class DefaultXlsxReadContext extends AnalysisContextImpl implements XlsxReadContext {
public DefaultXlsxReadContext(ReadWorkbook readWorkbook, ExcelTypeEnum actualExcelType) {
super(readWorkbook, actualExcelType);
}
@Override
public XlsxReadWorkbookHolder xlsxReadWorkbookHolder() {
return (XlsxReadWorkbookHolder)readWorkbookHolder();
}
@Override
public XlsxReadSheetHolder xlsxReadSheetHolder() {
return (XlsxReadSheetHolder)readSheetHolder();
}
}
package com.alibaba.excel.context.xlsx;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadWorkbookHolder;
/**
* A context is the main anchorage point of a ls xlsx reader.
*
* @author Jiaju Zhuang
**/
public interface XlsxReadContext extends AnalysisContext {
/**
* All information about the workbook you are currently working on.
*
* @return Current workbook holder
*/
XlsxReadWorkbookHolder xlsxReadWorkbookHolder();
/**
* All information about the sheet you are currently working on.
*
* @return Current sheet holder
*/
XlsxReadSheetHolder xlsxReadSheetHolder();
}
......@@ -48,56 +48,12 @@ public class DefaultConverterLoader {
private static Map<String, Converter> defaultWriteConverter;
private static Map<String, Converter> allConverter;
/**
* Load default write converter
*
* @return
*/
public static Map<String, Converter> loadDefaultWriteConverter() {
if (defaultWriteConverter != null) {
return defaultWriteConverter;
}
defaultWriteConverter = new HashMap<String, Converter>(32);
putWriteConverter(new BigDecimalNumberConverter());
putWriteConverter(new BooleanBooleanConverter());
putWriteConverter(new ByteNumberConverter());
putWriteConverter(new DateStringConverter());
putWriteConverter(new DoubleNumberConverter());
putWriteConverter(new FloatNumberConverter());
putWriteConverter(new IntegerNumberConverter());
putWriteConverter(new LongNumberConverter());
putWriteConverter(new ShortNumberConverter());
putWriteConverter(new StringStringConverter());
putWriteConverter(new FileImageConverter());
putWriteConverter(new InputStreamImageConverter());
putWriteConverter(new ByteArrayImageConverter());
putWriteConverter(new BoxingByteArrayImageConverter());
putWriteConverter(new UrlImageConverter());
return defaultWriteConverter;
static {
initDefaultWriteConverter();
initAllConverter();
}
private static void putWriteConverter(Converter converter) {
defaultWriteConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter);
}
/**
* Load default read converter
*
* @return
*/
public static Map<String, Converter> loadDefaultReadConverter() {
return loadAllConverter();
}
/**
* Load all converter
*
* @return
*/
public static Map<String, Converter> loadAllConverter() {
if (allConverter != null) {
return allConverter;
}
private static void initAllConverter() {
allConverter = new HashMap<String, Converter>(64);
putAllConverter(new BigDecimalBooleanConverter());
putAllConverter(new BigDecimalNumberConverter());
......@@ -138,6 +94,55 @@ public class DefaultConverterLoader {
putAllConverter(new StringNumberConverter());
putAllConverter(new StringStringConverter());
putAllConverter(new StringErrorConverter());
}
private static void initDefaultWriteConverter() {
defaultWriteConverter = new HashMap<String, Converter>(32);
putWriteConverter(new BigDecimalNumberConverter());
putWriteConverter(new BooleanBooleanConverter());
putWriteConverter(new ByteNumberConverter());
putWriteConverter(new DateStringConverter());
putWriteConverter(new DoubleNumberConverter());
putWriteConverter(new FloatNumberConverter());
putWriteConverter(new IntegerNumberConverter());
putWriteConverter(new LongNumberConverter());
putWriteConverter(new ShortNumberConverter());
putWriteConverter(new StringStringConverter());
putWriteConverter(new FileImageConverter());
putWriteConverter(new InputStreamImageConverter());
putWriteConverter(new ByteArrayImageConverter());
putWriteConverter(new BoxingByteArrayImageConverter());
putWriteConverter(new UrlImageConverter());
}
/**
* Load default write converter
*
* @return
*/
public static Map<String, Converter> loadDefaultWriteConverter() {
return defaultWriteConverter;
}
private static void putWriteConverter(Converter converter) {
defaultWriteConverter.put(ConverterKeyBuild.buildKey(converter.supportJavaTypeKey()), converter);
}
/**
* Load default read converter
*
* @return
*/
public static Map<String, Converter> loadDefaultReadConverter() {
return loadAllConverter();
}
/**
* Load all converter
*
* @return
*/
public static Map<String, Converter> loadAllConverter() {
return allConverter;
}
......
......@@ -34,7 +34,7 @@ public class ByteNumberConverter implements Converter<Byte> {
@Override
public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
return new CellData(BigDecimal.valueOf(value));
return new CellData(new BigDecimal(Byte.toString(value)));
}
}
......@@ -34,7 +34,7 @@ public class FloatNumberConverter implements Converter<Float> {
@Override
public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
return new CellData(BigDecimal.valueOf(value));
return new CellData(new BigDecimal(Float.toString(value)));
}
}
......@@ -34,7 +34,7 @@ public class IntegerNumberConverter implements Converter<Integer> {
@Override
public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
return new CellData(BigDecimal.valueOf(value));
return new CellData(new BigDecimal(Integer.toString(value)));
}
}
......@@ -34,7 +34,7 @@ public class ShortNumberConverter implements Converter<Short> {
@Override
public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
return new CellData(BigDecimal.valueOf(value));
return new CellData(new BigDecimal(Short.toString(value)));
}
}
......@@ -10,7 +10,9 @@ import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.NumberDataFormatterUtils;
import com.alibaba.excel.util.NumberUtils;
import com.alibaba.excel.util.StringUtils;
/**
* String and number converter
......@@ -44,13 +46,9 @@ public class StringNumberConverter implements Converter<String> {
return NumberUtils.format(cellData.getNumberValue(), contentProperty);
}
// Excel defines formatting
if (cellData.getDataFormat() != null) {
if (DateUtil.isADateFormat(cellData.getDataFormat(), cellData.getDataFormatString())) {
return DateUtils.format(DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(),
globalConfiguration.getUse1904windowing(), null));
} else {
return NumberUtils.format(cellData.getNumberValue(), contentProperty);
}
if (cellData.getDataFormat() != null && !StringUtils.isEmpty(cellData.getDataFormatString())) {
return NumberDataFormatterUtils.format(cellData.getNumberValue().doubleValue(), cellData.getDataFormat(),
cellData.getDataFormatString(), globalConfiguration);
}
// Default conversion number
return NumberUtils.format(cellData.getNumberValue(), contentProperty);
......
package com.alibaba.excel.enums;
/**
* Extra data type
*
* @author Jiaju Zhuang
**/
public enum CellExtraTypeEnum {
/**
* Comment
*/
COMMENT,
/**
* Hyperlink
*/
HYPERLINK,
/**
* Merge
*/
MERGE,;
}
package com.alibaba.excel.enums;
/**
* The types of row
*
* @author Jiaju Zhuang
**/
public enum RowTypeEnum {
/**
* data
*/
DATA,
/**
* empty
*/
EMPTY,;
}
package com.alibaba.excel.event;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.listener.ReadListener;
/**
......@@ -20,6 +21,17 @@ public abstract class AbstractIgnoreExceptionReadListener<T> implements ReadList
@Override
public void onException(Exception exception, AnalysisContext context) {}
/**
* The current method is called when extra information is returned
*
* @param extra
* extra information
* @param context
* analysis context
*/
@Override
public void extra(CellExtra extra, AnalysisContext context) {}
@Override
public boolean hasNext(AnalysisContext context) {
return true;
......
......@@ -4,6 +4,7 @@ import java.util.Map;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ConverterUtils;
......@@ -27,6 +28,17 @@ public abstract class AnalysisEventListener<T> implements ReadListener<T> {
*/
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {}
/**
* The current method is called when extra information is returned
*
* @param extra
* extra information
* @param context
* analysis context
*/
@Override
public void extra(CellExtra extra, AnalysisContext context) {}
/**
* All listeners receive this method when any one Listener does an error report. If an exception is thrown here, the
* entire read will terminate.
......
package com.alibaba.excel.metadata;
/**
* cell
*
* @author Jiaju Zhuang
**/
public class AbstractCell implements Cell {
/**
* Row index
*/
private Integer rowIndex;
/**
* Column index
*/
private Integer columnIndex;
public Integer getRowIndex() {
return rowIndex;
}
public void setRowIndex(Integer rowIndex) {
this.rowIndex = rowIndex;
}
public Integer getColumnIndex() {
return columnIndex;
}
public void setColumnIndex(Integer columnIndex) {
this.columnIndex = columnIndex;
}
}
package com.alibaba.excel.metadata;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import com.alibaba.excel.converters.Converter;
......@@ -27,7 +28,6 @@ public abstract class AbstractHolder implements ConfigurationHolder {
* Some global variables
*/
private GlobalConfiguration globalConfiguration;
/**
* <p>
* Read key:
......@@ -58,6 +58,16 @@ public abstract class AbstractHolder implements ConfigurationHolder {
} else {
globalConfiguration.setAutoTrim(basicParameter.getAutoTrim());
}
if (basicParameter.getLocale() == null) {
if (prentAbstractHolder == null) {
globalConfiguration.setLocale(Locale.getDefault());
} else {
globalConfiguration.setLocale(prentAbstractHolder.getGlobalConfiguration().getLocale());
}
} else {
globalConfiguration.setLocale(basicParameter.getLocale());
}
}
public Boolean getNewInitialization() {
......
package com.alibaba.excel.metadata;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import com.alibaba.excel.converters.Converter;
/**
* ExcelBuilder
*
* @author Jiaju Zhuang
*/
public abstract class AbstractParameterBuilder<T extends AbstractParameterBuilder, C extends BasicParameter> {
/**
* You can only choose one of the {@link #head(List)} and {@link #head(Class)}
*
* @param head
* @return
*/
public T head(List<List<String>> head) {
parameter().setHead(head);
return self();
}
/**
* You can only choose one of the {@link #head(List)} and {@link #head(Class)}
*
* @param clazz
* @return
*/
public T head(Class clazz) {
parameter().setClazz(clazz);
return self();
}
/**
* Custom type conversions override the default.
*
* @param converter
* @return
*/
public T registerConverter(Converter converter) {
if (parameter().getCustomConverterList() == null) {
parameter().setCustomConverterList(new ArrayList<Converter>());
}
parameter().getCustomConverterList().add(converter);
return self();
}
/**
* true if date uses 1904 windowing, or false if using 1900 date windowing.
*
* default is false
*
* @param use1904windowing
* @return
*/
public T use1904windowing(Boolean use1904windowing) {
parameter().setUse1904windowing(use1904windowing);
return self();
}
/**
* A <code>Locale</code> object represents a specific geographical, political, or cultural region. This parameter is
* used when formatting dates and numbers.
*
* @param locale
* @return
*/
public T locale(Locale locale) {
parameter().setLocale(locale);
return self();
}
/**
* Automatic trim includes sheet name and content
*
* @param autoTrim
* @return
*/
public T autoTrim(Boolean autoTrim) {
parameter().setAutoTrim(autoTrim);
return self();
}
@SuppressWarnings("unchecked")
protected T self() {
return (T)this;
}
/**
* Get parameter
*
* @return
*/
protected abstract C parameter();
}
package com.alibaba.excel.metadata;
import java.util.List;
import java.util.Locale;
import com.alibaba.excel.converters.Converter;
......@@ -34,6 +35,11 @@ public class BasicParameter {
* @return
*/
private Boolean use1904windowing;
/**
* A <code>Locale</code> object represents a specific geographical, political, or cultural region. This parameter is
* used when formatting dates and numbers.
*/
private Locale locale;
public List<List<String>> getHead() {
return head;
......@@ -75,4 +81,11 @@ public class BasicParameter {
this.use1904windowing = use1904windowing;
}
public Locale getLocale() {
return locale;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
}
package com.alibaba.excel.metadata;
/**
* Cell
*
* @author Jiaju Zhuang
**/
public interface Cell {
/**
* Row index
*
* @return
*/
Integer getRowIndex();
/**
* Column index
*
* @return
*/
Integer getColumnIndex();
}
......@@ -12,7 +12,7 @@ import com.alibaba.excel.util.StringUtils;
*
* @author Jiaju Zhuang
*/
public class CellData<T> {
public class CellData<T> extends AbstractCell {
private CellDataTypeEnum type;
/**
* {@link CellDataTypeEnum#NUMBER}
......@@ -226,6 +226,42 @@ public class CellData<T> {
}
}
public static CellData newEmptyInstance() {
return newEmptyInstance(null, null);
}
public static CellData newEmptyInstance(Integer rowIndex, Integer columnIndex) {
CellData cellData = new CellData(CellDataTypeEnum.EMPTY);
cellData.setRowIndex(rowIndex);
cellData.setColumnIndex(columnIndex);
return cellData;
}
public static CellData newInstance(Boolean booleanValue) {
return newInstance(booleanValue, null, null);
}
public static CellData newInstance(Boolean booleanValue, Integer rowIndex, Integer columnIndex) {
CellData cellData = new CellData(booleanValue);
cellData.setRowIndex(rowIndex);
cellData.setColumnIndex(columnIndex);
return cellData;
}
public static CellData newInstance(String stringValue, Integer rowIndex, Integer columnIndex) {
CellData cellData = new CellData(stringValue);
cellData.setRowIndex(rowIndex);
cellData.setColumnIndex(columnIndex);
return cellData;
}
public static CellData newInstance(BigDecimal numberValue, Integer rowIndex, Integer columnIndex) {
CellData cellData = new CellData(numberValue);
cellData.setRowIndex(rowIndex);
cellData.setColumnIndex(columnIndex);
return cellData;
}
@Override
public String toString() {
if (type == null) {
......
package com.alibaba.excel.metadata;
import org.apache.poi.ss.util.CellReference;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.enums.CellExtraTypeEnum;
/**
* Cell extra information.
*
* @author Jiaju Zhuang
*/
public class CellExtra extends AbstractCell {
/**
* Cell extra type
*/
private CellExtraTypeEnum type;
/**
* Cell extra data
*/
private String text;
/**
* First row index,if this object is an interval
*/
private Integer firstRowIndex;
/**
* Last row index,if this object is an interval
*/
private Integer lastRowIndex;
/**
* First column index,if this object is an interval
*/
private Integer firstColumnIndex;
/**
* Last column index,if this object is an interval
*/
private Integer lastColumnIndex;
public CellExtra(CellExtraTypeEnum type, String text, String range) {
super();
this.type = type;
this.text = text;
String[] ranges = range.split(ExcelXmlConstants.CELL_RANGE_SPLIT);
CellReference first = new CellReference(ranges[0]);
CellReference last = first;
this.firstRowIndex = first.getRow();
this.firstColumnIndex = (int)first.getCol();
setRowIndex(this.firstRowIndex);
setColumnIndex(this.firstColumnIndex);
if (ranges.length > 1) {
last = new CellReference(ranges[1]);
}
this.lastRowIndex = last.getRow();
this.lastColumnIndex = (int)last.getCol();
}
public CellExtra(CellExtraTypeEnum type, String text, Integer rowIndex, Integer columnIndex) {
this(type, text, rowIndex, rowIndex, columnIndex, columnIndex);
}
public CellExtra(CellExtraTypeEnum type, String text, Integer firstRowIndex, Integer lastRowIndex,
Integer firstColumnIndex, Integer lastColumnIndex) {
super();
setRowIndex(firstRowIndex);
setColumnIndex(firstColumnIndex);
this.type = type;
this.text = text;
this.firstRowIndex = firstRowIndex;
this.firstColumnIndex = firstColumnIndex;
this.lastRowIndex = lastRowIndex;
this.lastColumnIndex = lastColumnIndex;
}
public CellExtraTypeEnum getType() {
return type;
}
public void setType(CellExtraTypeEnum type) {
this.type = type;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Integer getFirstRowIndex() {
return firstRowIndex;
}
public void setFirstRowIndex(Integer firstRowIndex) {
this.firstRowIndex = firstRowIndex;
}
public Integer getFirstColumnIndex() {
return firstColumnIndex;
}
public void setFirstColumnIndex(Integer firstColumnIndex) {
this.firstColumnIndex = firstColumnIndex;
}
public Integer getLastRowIndex() {
return lastRowIndex;
}
public void setLastRowIndex(Integer lastRowIndex) {
this.lastRowIndex = lastRowIndex;
}
public Integer getLastColumnIndex() {
return lastColumnIndex;
}
public void setLastColumnIndex(Integer lastColumnIndex) {
this.lastColumnIndex = lastColumnIndex;
}
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册