diff --git a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java index f8d81fa6..4546c4bb 100644 --- a/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java +++ b/src/main/java/com/alibaba/excel/analysis/ExcelAnalyserImpl.java @@ -110,7 +110,7 @@ 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().setParameterSheetDataList(readSheetList); analysisContext.readWorkbookHolder().setReadAll(readAll); try { excelReadExecutor.execute(); @@ -150,16 +150,16 @@ public class ExcelAnalyserImpl implements ExcelAnalyser { } try { if ((readWorkbookHolder instanceof XlsxReadWorkbookHolder) - && ((XlsxReadWorkbookHolder) readWorkbookHolder).getOpcPackage() != null) { - ((XlsxReadWorkbookHolder) readWorkbookHolder).getOpcPackage().revert(); + && ((XlsxReadWorkbookHolder)readWorkbookHolder).getOpcPackage() != null) { + ((XlsxReadWorkbookHolder)readWorkbookHolder).getOpcPackage().revert(); } } catch (Throwable t) { throwable = t; } try { if ((readWorkbookHolder instanceof XlsReadWorkbookHolder) - && ((XlsReadWorkbookHolder) readWorkbookHolder).getPoifsFileSystem() != null) { - ((XlsReadWorkbookHolder) readWorkbookHolder).getPoifsFileSystem().close(); + && ((XlsReadWorkbookHolder)readWorkbookHolder).getPoifsFileSystem() != null) { + ((XlsReadWorkbookHolder)readWorkbookHolder).getPoifsFileSystem().close(); } } catch (Throwable t) { throwable = t; diff --git a/src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java b/src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java index 31d2db8c..cfdc6bee 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsListSheetListener.java @@ -35,6 +35,7 @@ public class XlsListSheetListener implements HSSFListener { public XlsListSheetListener(XlsReadContext xlsReadContext) { this.xlsReadContext = xlsReadContext; + xlsReadContext.xlsReadWorkbookHolder().setNeedReadSheet(Boolean.FALSE); } @Override diff --git a/src/main/java/com/alibaba/excel/analysis/v03/XlsRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/XlsRecordHandler.java index dea327f5..3b4fa7c2 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/XlsRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsRecordHandler.java @@ -10,6 +10,14 @@ import com.alibaba.excel.context.xls.XlsReadContext; * @author Dan Zheng */ public interface XlsRecordHandler { + /** + * Whether to support + * + * @param xlsReadContext + * @param record + */ + boolean support(XlsReadContext xlsReadContext, Record record); + /** * Processing record * diff --git a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java index c90f6559..a94a7d31 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java @@ -18,9 +18,11 @@ 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; @@ -40,9 +42,11 @@ 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.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; @@ -84,9 +88,11 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { 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()); @@ -117,7 +123,7 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener = new EventWorkbookBuilder.SheetRecordCollectingListener( xlsReadWorkbookHolder.getFormatTrackingHSSFListener()); - xlsReadWorkbookHolder.setHsffWorkbook(workbookBuildingListener.getStubHSSFWorkbook()); + xlsReadWorkbookHolder.setHssfWorkbook(workbookBuildingListener.getStubHSSFWorkbook()); HSSFEventFactory factory = new HSSFEventFactory(); HSSFRequest request = new HSSFRequest(); request.addListenerForAllRecords(xlsReadWorkbookHolder.getFormatTrackingHSSFListener()); @@ -139,10 +145,15 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelReadExecutor { if (handler == null) { return; } - if ((handler instanceof IgnorableXlsRecordHandler) && xlsReadContext.xlsReadSheetHolder().getIgnoreRecord()) { + boolean ignoreRecord = (handler instanceof IgnorableXlsRecordHandler) + && xlsReadContext.xlsReadSheetHolder() != null && xlsReadContext.xlsReadSheetHolder().getIgnoreRecord(); + if (ignoreRecord) { // No need to read the current sheet return; } + if (!handler.support(xlsReadContext, record)) { + return; + } handler.processRecord(xlsReadContext, record); } diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/AbstractXlsRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/AbstractXlsRecordHandler.java new file mode 100644 index 00000000..93b3d1a3 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/AbstractXlsRecordHandler.java @@ -0,0 +1,19 @@ +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; + } +} diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BlankRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BlankRecordHandler.java index 372a44ca..e6290eb5 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BlankRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BlankRecordHandler.java @@ -12,7 +12,7 @@ import com.alibaba.excel.metadata.CellData; * * @author Dan Zheng */ -public class BlankRecordHandler implements IgnorableXlsRecordHandler { +public class BlankRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java index 59870bad..973d83eb 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java @@ -7,11 +7,9 @@ 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.XlsRecordHandler; 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.XlsReadSheetHolder; import com.alibaba.excel.read.metadata.holder.xls.XlsReadWorkbookHolder; import com.alibaba.excel.util.SheetUtils; @@ -20,7 +18,7 @@ import com.alibaba.excel.util.SheetUtils; * * @author Dan Zheng */ -public class BofRecordHandler implements XlsRecordHandler { +public class BofRecordHandler extends AbstractXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { @@ -29,7 +27,6 @@ public class BofRecordHandler implements XlsRecordHandler { return; } XlsReadWorkbookHolder xlsReadWorkbookHolder = xlsReadContext.xlsReadWorkbookHolder(); - XlsReadSheetHolder XlsReadSheetHolder = xlsReadContext.xlsReadSheetHolder(); // Init read sheet Data initReadSheetDataList(xlsReadWorkbookHolder); Integer readSheetIndex = xlsReadWorkbookHolder.getReadSheetIndex(); @@ -43,9 +40,9 @@ public class BofRecordHandler implements XlsRecordHandler { readSheet = SheetUtils.match(readSheet, xlsReadContext); if (readSheet != null) { xlsReadContext.currentSheet(readSheet); - XlsReadSheetHolder.setIgnoreRecord(Boolean.FALSE); + xlsReadContext.xlsReadSheetHolder().setIgnoreRecord(Boolean.FALSE); } else { - XlsReadSheetHolder.setIgnoreRecord(Boolean.TRUE); + xlsReadContext.xlsReadSheetHolder().setIgnoreRecord(Boolean.TRUE); } // Go read the next one xlsReadWorkbookHolder.setReadSheetIndex(xlsReadWorkbookHolder.getReadSheetIndex() + 1); diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoolErrRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoolErrRecordHandler.java index 60e72338..8d435213 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoolErrRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoolErrRecordHandler.java @@ -13,7 +13,7 @@ import com.alibaba.excel.metadata.CellData; * * @author Dan Zheng */ -public class BoolErrRecordHandler implements IgnorableXlsRecordHandler { +public class BoolErrRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoundSheetRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoundSheetRecordHandler.java index 96e7b33c..685dcc65 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoundSheetRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/BoundSheetRecordHandler.java @@ -11,7 +11,7 @@ import com.alibaba.excel.context.xls.XlsReadContext; * * @author Dan Zheng */ -public class BoundSheetRecordHandler implements IgnorableXlsRecordHandler { +public class BoundSheetRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/DummyRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/DummyRecordHandler.java index 15a68dc9..ab41d298 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/DummyRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/DummyRecordHandler.java @@ -18,7 +18,7 @@ import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder; * * @author Dan Zheng */ -public class DummyRecordHandler implements IgnorableXlsRecordHandler { +public class DummyRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { XlsReadSheetHolder xlsReadSheetHolder = xlsReadContext.xlsReadSheetHolder(); @@ -27,7 +27,7 @@ public class DummyRecordHandler implements IgnorableXlsRecordHandler { LastCellOfRowDummyRecord lcrdr = (LastCellOfRowDummyRecord)record; xlsReadSheetHolder.setRowIndex(lcrdr.getRow()); xlsReadContext.readRowHolder(new ReadRowHolder(lcrdr.getRow(), xlsReadSheetHolder.getTempRowType(), - xlsReadContext.readSheetHolder().getGlobalConfiguration())); + xlsReadContext.readSheetHolder().getGlobalConfiguration(), xlsReadSheetHolder.getCellMap())); xlsReadContext.analysisEventProcessor().endRow(xlsReadContext); xlsReadSheetHolder.setCellMap(new LinkedHashMap()); } else if (record instanceof MissingCellDummyRecord) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java index 4b1517b3..0ca7313e 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/EofRecordHandler.java @@ -10,7 +10,7 @@ import com.alibaba.excel.context.xls.XlsReadContext; * * @author Dan Zheng */ -public class EofRecordHandler implements IgnorableXlsRecordHandler { +public class EofRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java index f04cdb77..004d9c67 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java @@ -21,7 +21,7 @@ import com.alibaba.excel.metadata.CellData; * * @author Dan Zheng */ -public class FormulaRecordHandler implements IgnorableXlsRecordHandler { +public class FormulaRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { private static final Logger LOGGER = LoggerFactory.getLogger(FormulaRecordHandler.class); private static final String ERROR = "#VALUE!"; @@ -35,7 +35,7 @@ public class FormulaRecordHandler implements IgnorableXlsRecordHandler { CellType cellType = CellType.forInt(frec.getCachedResultType()); String formulaValue = null; try { - formulaValue = HSSFFormulaParser.toFormulaString(xlsReadContext.xlsReadWorkbookHolder().getHsffWorkbook(), + formulaValue = HSSFFormulaParser.toFormulaString(xlsReadContext.xlsReadWorkbookHolder().getHssfWorkbook(), frec.getParsedExpression()); } catch (Exception e) { LOGGER.debug("Get formula value error.", e); diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/HyperlinkRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/HyperlinkRecordHandler.java new file mode 100644 index 00000000..915abf61 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/HyperlinkRecordHandler.java @@ -0,0 +1,30 @@ +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.getFirstColumn(), hr.getLastRow(), hr.getLastColumn()); + xlsReadContext.xlsReadSheetHolder().setCellExtra(cellExtra); + xlsReadContext.analysisEventProcessor().extra(xlsReadContext); + } +} diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/IndexRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/IndexRecordHandler.java index de21da89..b95812eb 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/IndexRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/IndexRecordHandler.java @@ -11,7 +11,7 @@ import com.alibaba.excel.context.xls.XlsReadContext; * * @author Jiaju Zhuang */ -public class IndexRecordHandler implements IgnorableXlsRecordHandler { +public class IndexRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { if (xlsReadContext.readSheetHolder() == null) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelRecordHandler.java index 1335ada3..4f63ab0c 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelRecordHandler.java @@ -13,7 +13,7 @@ import com.alibaba.excel.metadata.CellData; * * @author Dan Zheng */ -public class LabelRecordHandler implements IgnorableXlsRecordHandler { +public class LabelRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { LabelRecord lrec = (LabelRecord)record; diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelSstRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelSstRecordHandler.java index 7979241e..7fb5cd0d 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelSstRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelSstRecordHandler.java @@ -17,7 +17,7 @@ import com.alibaba.excel.metadata.CellData; * * @author Dan Zheng */ -public class LabelSstRecordHandler implements IgnorableXlsRecordHandler { +public class LabelSstRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/MergeCellsRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/MergeCellsRecordHandler.java new file mode 100644 index 00000000..4689f2b6 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/MergeCellsRecordHandler.java @@ -0,0 +1,35 @@ +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.getFirstColumn(), cellRangeAddress.getLastRow(), cellRangeAddress.getLastColumn()); + xlsReadContext.xlsReadSheetHolder().setCellExtra(cellExtra); + xlsReadContext.analysisEventProcessor().extra(xlsReadContext); + } + } +} diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NoteRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NoteRecordHandler.java index 8c2993dc..6b6d803e 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NoteRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NoteRecordHandler.java @@ -5,7 +5,7 @@ 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.enums.CellExtraTypeEnum; import com.alibaba.excel.metadata.CellExtra; /** @@ -13,17 +13,19 @@ import com.alibaba.excel.metadata.CellExtra; * * @author Dan Zheng */ -public class NoteRecordHandler implements IgnorableXlsRecordHandler { +public class NoteRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { + + @Override + public boolean support(XlsReadContext xlsReadContext, Record record) { + return xlsReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.COMMENT); + } @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { NoteRecord nr = (NoteRecord)record; - String note = xlsReadContext.xlsReadSheetHolder().getObjectCacheMap().get(nr.getShapeId()); - CellExtra cellExtra = new CellExtra(); - cellExtra.setRowIndex(nr.getRow()); - cellExtra.setRowIndex(nr.getColumn()); - cellExtra.setNote(note); - xlsReadContext.xlsReadSheetHolder().getCellMap().put(nr.getColumn(), cellExtra); - xlsReadContext.xlsReadSheetHolder().setTempRowType(RowTypeEnum.EXTRA); + 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); } } diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java index 5e2fbca4..50608095 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java @@ -16,7 +16,7 @@ import com.alibaba.excel.metadata.CellData; * * @author Dan Zheng */ -public class NumberRecordHandler implements IgnorableXlsRecordHandler { +public class NumberRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/ObjRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/ObjRecordHandler.java index e8a0cc1b..97bcd20f 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/ObjRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/ObjRecordHandler.java @@ -13,7 +13,7 @@ import com.alibaba.excel.context.xls.XlsReadContext; * * @author Jiaju Zhuang */ -public class ObjRecordHandler implements IgnorableXlsRecordHandler { +public class ObjRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { ObjRecord or = (ObjRecord)record; diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/RkRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/RkRecordHandler.java index 22ba166b..d8317b37 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/RkRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/RkRecordHandler.java @@ -12,7 +12,7 @@ import com.alibaba.excel.metadata.CellData; * * @author Dan Zheng */ -public class RkRecordHandler implements IgnorableXlsRecordHandler { +public class RkRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/SstRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/SstRecordHandler.java index c11ff4c0..35727b66 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/SstRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/SstRecordHandler.java @@ -12,7 +12,7 @@ import com.alibaba.excel.context.xls.XlsReadContext; * * @author Dan Zheng */ -public class SstRecordHandler implements IgnorableXlsRecordHandler { +public class SstRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { @Override public void processRecord(XlsReadContext xlsReadContext, Record record) { xlsReadContext.readWorkbookHolder().setReadCache(new XlsCache((SSTRecord)record)); diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/StringRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/StringRecordHandler.java index e4c40ecf..3b95cfdb 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/StringRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/StringRecordHandler.java @@ -15,7 +15,7 @@ import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder; * * @author Dan Zheng */ -public class StringRecordHandler implements IgnorableXlsRecordHandler { +public class StringRecordHandler extends AbstractXlsRecordHandler implements IgnorableXlsRecordHandler { private static final Logger LOGGER = LoggerFactory.getLogger(StringRecordHandler.class); @Override diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/TextObjectRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/TextObjectRecordHandler.java index 1ee3543b..949498f0 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/TextObjectRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/TextObjectRecordHandler.java @@ -7,6 +7,7 @@ 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; /** @@ -14,9 +15,14 @@ import com.alibaba.excel.read.metadata.holder.xls.XlsReadSheetHolder; * * @author Jiaju Zhuang */ -public class TextObjectRecordHandler implements IgnorableXlsRecordHandler { +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; diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java deleted file mode 100644 index 1785036a..00000000 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxHandlerFactory.java +++ /dev/null @@ -1,28 +0,0 @@ -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.analysis.v07.handlers.XlsxCellHandler; -import com.alibaba.excel.context.AnalysisContext; - -/** - * Build handler - * - * @author Dan Zheng - */ -public class XlsxHandlerFactory { - public static List buildCellHandlers(AnalysisContext analysisContext, StylesTable stylesTable) { - List result = new ArrayList(); - result.add(new CountRowCellHandler(analysisContext)); - DefaultCellHandler defaultCellHandler = new DefaultCellHandler(analysisContext, stylesTable); - result.add(defaultCellHandler); - result.add(new ProcessResultCellHandler(analysisContext, defaultCellHandler)); - return result; - } -} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowResultHolder.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowResultHolder.java deleted file mode 100644 index d13da731..00000000 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxRowResultHolder.java +++ /dev/null @@ -1,33 +0,0 @@ -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 getCurRowContent(); -} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java index 205b6480..a0a9af0e 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/XlsxSaxAnalyser.java @@ -15,7 +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.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; @@ -29,7 +32,9 @@ 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.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.xlsx.XlsxReadWorkbookHolder; import com.alibaba.excel.util.CollectionUtils; @@ -45,6 +50,10 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { private XlsxReadContext xlsxReadContext; private List sheetList; private Map sheetMap; + /** + * excel comments key: sheetNo value: CommentsTable + */ + private Map commentsTableMap; public XlsxSaxAnalyser(XlsxReadContext xlsxReadContext, InputStream decryptedStream) throws Exception { this.xlsxReadContext = xlsxReadContext; @@ -72,7 +81,8 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { xlsxReadWorkbookHolder.setStylesTable(xssfReader.getStylesTable()); sheetList = new ArrayList(); sheetMap = new HashMap(); - XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator) xssfReader.getSheetsData(); + commentsTableMap = new HashMap(); + XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData(); int index = 0; if (!ite.hasNext()) { throw new ExcelAnalysisException("Can not find any sheet!"); @@ -81,11 +91,18 @@ 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(XlsxReadWorkbookHolder xlsxReadWorkbookHolder, PackagePart sharedStringsTablePackagePart) { + private void defaultReadCache(XlsxReadWorkbookHolder xlsxReadWorkbookHolder, + PackagePart sharedStringsTablePackagePart) { ReadCache readCache = xlsxReadWorkbookHolder.getReadCacheSelector().readCache(sharedStringsTablePackagePart); xlsxReadWorkbookHolder.setReadCache(readCache); readCache.init(xlsxReadContext); @@ -108,7 +125,7 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { } private void analysisSharedStringsTable(InputStream sharedStringsTableInputStream, - XlsxReadWorkbookHolder xlsxReadWorkbookHolder) throws Exception { + XlsxReadWorkbookHolder xlsxReadWorkbookHolder) throws Exception { ContentHandler handler = new SharedStringsTableHandler(xlsxReadWorkbookHolder.getReadCache()); parseXmlSource(sharedStringsTableInputStream, handler); xlsxReadWorkbookHolder.getReadCache().putFinished(); @@ -182,9 +199,28 @@ public class XlsxSaxAnalyser implements ExcelReadExecutor { if (readSheet != null) { xlsxReadContext.currentSheet(readSheet); parseXmlSource(sheetMap.get(readSheet.getSheetNo()), new XlsxRowHandler(xlsxReadContext)); + // Read comments + readComments(readSheet); // The last sheet is read 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 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); + } + } } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java new file mode 100644 index 00000000..0c60d665 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractCellValueTagHandler.java @@ -0,0 +1,64 @@ +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. + */ + protected abstract void setStringValue(XlsxReadContext xlsxReadContext); + +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractXlsxTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractXlsxTagHandler.java new file mode 100644 index 00000000..169fe00e --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/AbstractXlsxTagHandler.java @@ -0,0 +1,32 @@ +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) { + + } +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellFormulaTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellFormulaTagHandler.java new file mode 100644 index 00000000..e153a3b1 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellFormulaTagHandler.java @@ -0,0 +1,32 @@ +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); + } +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java new file mode 100644 index 00000000..277348a7 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellInlineStringValueTagHandler.java @@ -0,0 +1,23 @@ +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()); + } + +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java new file mode 100644 index 00000000..8ef07865 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellTagHandler.java @@ -0,0 +1,53 @@ +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_VALUE_TYPE_TAG; + +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; + +/** + * Cell Handler + * + * @author jipengfei + */ +public class CellTagHandler extends AbstractXlsxTagHandler { + + @Override + public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { + XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder(); + xlsxReadSheetHolder.setColumnIndex(PositionUtils.getCol(attributes.getValue(ExcelXmlConstants.POSITION))); + + // 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)); + xlsxReadSheetHolder.setTempCellData(new CellData(type)); + xlsxReadSheetHolder.setTempData(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 = + xlsxReadContext.xlsxReadWorkbookHolder().getStylesTable().getStyleAt(dateFormatIndexInteger); + int dataFormat = xssfCellStyle.getDataFormat(); + xlsxReadSheetHolder.getTempCellData().setDataFormat(dataFormat); + xlsxReadSheetHolder.getTempCellData().setDataFormatString(BuiltinFormats.getBuiltinFormat(dataFormat, + xssfCellStyle.getDataFormatString(), xlsxReadSheetHolder.getGlobalConfiguration().getLocale())); + } + } + +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java new file mode 100644 index 00000000..09c9264e --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CellValueTagHandler.java @@ -0,0 +1,34 @@ +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: + } + } + +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountTagHandler.java similarity index 68% rename from src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java rename to src/main/java/com/alibaba/excel/analysis/v07/handlers/CountTagHandler.java index dbc0a7e4..c1eb3233 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/CountTagHandler.java @@ -11,19 +11,14 @@ import com.alibaba.excel.context.xlsx.XlsxReadContext; * * @author jipengfei */ -public class CountRowCellHandler implements XlsxCellHandler { - +public class CountTagHandler extends AbstractXlsxTagHandler { @Override - public void startHandle(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { + public void startElement(XlsxReadContext xlsxReadContext, 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]", ""); xlsxReadContext.readSheetHolder().setApproximateTotalRowNumber(Integer.parseInt(c)); } - @Override - public void endHandle(XlsxReadContext xlsxReadContext, String name) { - } - } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java deleted file mode 100644 index baa3990d..00000000 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java +++ /dev/null @@ -1,169 +0,0 @@ -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.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; -import org.xml.sax.Attributes; - -import com.alibaba.excel.analysis.v07.XlsxRowResultHolder; -import com.alibaba.excel.constant.BuiltinFormats; -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 currentTagDeque = new LinkedList(); - private int curCol; - private Map curRowContent = new LinkedHashMap(); - private CellData currentCellData; - private StringBuilder dataStringBuilder; - private StringBuilder formulaStringBuilder; - - @Override - public void clearResult() { - curRowContent = new LinkedHashMap(); - } - - @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)); - - // 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(); - currentCellData.setDataFormat(dataFormat); - currentCellData.setDataFormatString( - BuiltinFormats.getBuiltinFormat(dataFormat, xssfCellStyle.getDataFormatString(), - analysisContext.readSheetHolder().getGlobalConfiguration().getLocale())); - } - } - // 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 getCurRowContent() { - return curRowContent; - } - -} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/HyperlinkTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/HyperlinkTagHandler.java new file mode 100644 index 00000000..ee0154e7 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/HyperlinkTagHandler.java @@ -0,0 +1,35 @@ +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); + } + +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/MergeCellTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/MergeCellTagHandler.java new file mode 100644 index 00000000..8b0fa041 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/MergeCellTagHandler.java @@ -0,0 +1,34 @@ +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); + } + +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java deleted file mode 100644 index 51a71231..00000000 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -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.RowTypeEnum; -import com.alibaba.excel.read.metadata.holder.ReadRowHolder; -import com.alibaba.excel.util.PositionUtils; - -/** - * Cell Handler - * - * @author jipengfei - */ -public class ProcessResultCellHandler implements XlsxCellHandler { - - @Override - public void startHandle(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { - xlsxReadContext.readRowHolder( - new ReadRowHolder(PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.POSITION)), RowTypeEnum.DATA, - xlsxReadContext.readSheetHolder().getGlobalConfiguration())); - } - - @Override - public void endHandle(XlsxReadContext xlsxReadContext, String name) { - xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext); - } - -} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java new file mode 100644 index 00000000..372a0a7d --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/RowTagHandler.java @@ -0,0 +1,35 @@ +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.util.PositionUtils; + +/** + * Cell Handler + * + * @author jipengfei + */ +public class RowTagHandler extends AbstractXlsxTagHandler { + + @Override + public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) { + xlsxReadContext.readRowHolder( + new ReadRowHolder(PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.POSITION)), + RowTypeEnum.DATA, xlsxReadContext.readSheetHolder().getGlobalConfiguration(), null)); + } + + @Override + public void endElement(XlsxReadContext xlsxReadContext, String name) { + xlsxReadContext.readRowHolder().setCellMap(xlsxReadContext.xlsxReadSheetHolder().getCellMap()); + xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext); + xlsxReadContext.xlsxReadSheetHolder().setCellMap(new LinkedHashMap()); + } + +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/XlsxCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/XlsxCellHandler.java deleted file mode 100644 index 3ec2fd85..00000000 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/XlsxCellHandler.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.alibaba.excel.analysis.v07.handlers; - -import org.xml.sax.Attributes; - -import com.alibaba.excel.context.xlsx.XlsxReadContext; - -/** - * Cell handler - * - * @author Dan Zheng - */ -public interface XlsxCellHandler { - /** - * Start handle - * - * @param xlsxReadContext xlsxReadContext - * @param name Tag name - * @param attributes Tag attributes - */ - void startHandle(XlsxReadContext xlsxReadContext, String name, Attributes attributes); - - /** - * End handle - * - * @param xlsxReadContext xlsxReadContext - * @param name Tag name - */ - void endHandle(XlsxReadContext xlsxReadContext, String name); -} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/XlsxTagHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/XlsxTagHandler.java new file mode 100644 index 00000000..3bd353a7 --- /dev/null +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/XlsxTagHandler.java @@ -0,0 +1,53 @@ +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 + */ + 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); + +} diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java index 90e760a6..0a4adb4e 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/sax/XlsxRowHandler.java @@ -7,9 +7,15 @@ import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -import com.alibaba.excel.analysis.v07.handlers.CountRowCellHandler; -import com.alibaba.excel.analysis.v07.handlers.ProcessResultCellHandler; -import com.alibaba.excel.analysis.v07.handlers.XlsxCellHandler; +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; @@ -18,11 +24,18 @@ import com.alibaba.excel.context.xlsx.XlsxReadContext; */ public class XlsxRowHandler extends DefaultHandler { private XlsxReadContext xlsxReadContext; - private static final Map XLSX_CELL_HANDLER_MAP = new HashMap(16); + private static final Map XLSX_CELL_HANDLER_MAP = new HashMap(16); static { - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.DIMENSION, new CountRowCellHandler()); - XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.ROW_TAG, new ProcessResultCellHandler()); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_FORMULA_TAG, new CellFormulaTagHandler()); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_INLINE_STRING_VALUE_TAG, + new CellInlineStringValueTagHandler()); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_TAG, new CellTagHandler()); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.CELL_VALUE_TAG, new CellValueTagHandler()); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.DIMENSION, new CountTagHandler()); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.HYPERLINK_TAG, new HyperlinkTagHandler()); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.MERGE_CELL_TAG, new MergeCellTagHandler()); + XLSX_CELL_HANDLER_MAP.put(ExcelXmlConstants.ROW_TAG, new RowTagHandler()); } public XlsxRowHandler(XlsxReadContext xlsxReadContext) { @@ -31,28 +44,35 @@ public class XlsxRowHandler extends DefaultHandler { @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { - XlsxCellHandler handler = XLSX_CELL_HANDLER_MAP.get(name); + XlsxTagHandler handler = XLSX_CELL_HANDLER_MAP.get(name); if (handler == null) { return; } - handler.startHandle(xlsxReadContext, name, attributes); + xlsxReadContext.xlsxReadSheetHolder().getTagDeque().push(name); + handler.startElement(xlsxReadContext, name, attributes); } @Override public void characters(char[] ch, int start, int length) throws SAXException { - if (rowResultHolder != null) { - rowResultHolder.appendCurrentCellValue(ch, start, length); + String currentTag = xlsxReadContext.xlsxReadSheetHolder().getTagDeque().peek(); + if (currentTag == null) { + return; } + XlsxTagHandler handler = XLSX_CELL_HANDLER_MAP.get(currentTag); + if (handler == null) { + return; + } + handler.characters(xlsxReadContext, ch, start, length); } @Override public void endElement(String uri, String localName, String name) throws SAXException { - XlsxCellHandler handler = XLSX_CELL_HANDLER_MAP.get(name); + XlsxTagHandler handler = XLSX_CELL_HANDLER_MAP.get(name); if (handler == null) { return; } - handler.endHandle(xlsxReadContext, name); + handler.endElement(xlsxReadContext, name); + xlsxReadContext.xlsxReadSheetHolder().getTagDeque().pop(); } - } diff --git a/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java index f01a33b3..5cb6662a 100644 --- a/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java +++ b/src/main/java/com/alibaba/excel/constant/ExcelXmlConstants.java @@ -22,4 +22,19 @@ public class ExcelXmlConstants { */ public static final String CELL_INLINE_STRING_VALUE_TAG = "t"; + public static final String MERGE_CELL_TAG = "mergeCell"; + public static final String HYPERLINK_TAG = "hyperlink"; + + /** + * Cell range split + */ + public static final String CELL_RANGE_SPLIT = ":"; + /** + * ref attribute + */ + public static final String ATTRIBUTE_REF = "ref"; + /** + * location attribute + */ + public static final String ATTRIBUTE_LOCATION = "location"; } diff --git a/src/main/java/com/alibaba/excel/context/AnalysisContext.java b/src/main/java/com/alibaba/excel/context/AnalysisContext.java index b4414598..684fb6e0 100644 --- a/src/main/java/com/alibaba/excel/context/AnalysisContext.java +++ b/src/main/java/com/alibaba/excel/context/AnalysisContext.java @@ -92,20 +92,6 @@ public interface AnalysisContext { */ void readSheetList(List readSheetList); - /** - * Read all sheets - * - * @return - */ - Boolean readAll(); - - /** - * Read all sheets - * - * @return - */ - void readAll(Boolean readAll); - /** * get current sheet * diff --git a/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java b/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java index 2b5a766e..ab27e87e 100644 --- a/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java +++ b/src/main/java/com/alibaba/excel/context/AnalysisContextImpl.java @@ -137,16 +137,6 @@ public class AnalysisContextImpl implements AnalysisContext { } - @Override - public Boolean readAll() { - return null; - } - - @Override - public void readAll(Boolean readAll) { - - } - @Override public Sheet getCurrentSheet() { Sheet sheet = new Sheet(readSheetHolder.getSheetNo() + 1); diff --git a/src/main/java/com/alibaba/excel/enums/CellExtraTypeEnum.java b/src/main/java/com/alibaba/excel/enums/CellExtraTypeEnum.java new file mode 100644 index 00000000..1c13b7c0 --- /dev/null +++ b/src/main/java/com/alibaba/excel/enums/CellExtraTypeEnum.java @@ -0,0 +1,21 @@ +package com.alibaba.excel.enums; + +/** + * Extra data type + * + * @author Jiaju Zhuang + **/ +public enum CellExtraTypeEnum { + /** + * Comment + */ + COMMENT, + /** + * Hyperlink + */ + HYPERLINK, + /** + * Merge + */ + MERGE,; +} diff --git a/src/main/java/com/alibaba/excel/enums/ExtraReadEnum.java b/src/main/java/com/alibaba/excel/enums/ExtraReadEnum.java deleted file mode 100644 index 2dee2bfe..00000000 --- a/src/main/java/com/alibaba/excel/enums/ExtraReadEnum.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.alibaba.excel.enums; - -/** - * Read some extra data - * - * @author Jiaju Zhuang - **/ -public enum ExtraReadEnum { - /** - * Read the comment - */ - COMMENT,; -} diff --git a/src/main/java/com/alibaba/excel/enums/RowTypeEnum.java b/src/main/java/com/alibaba/excel/enums/RowTypeEnum.java index 75dfc673..e371cbdc 100644 --- a/src/main/java/com/alibaba/excel/enums/RowTypeEnum.java +++ b/src/main/java/com/alibaba/excel/enums/RowTypeEnum.java @@ -10,10 +10,6 @@ public enum RowTypeEnum { * data */ DATA, - /** - * extra - */ - EXTRA, /** * empty */ diff --git a/src/main/java/com/alibaba/excel/event/AbstractIgnoreExceptionReadListener.java b/src/main/java/com/alibaba/excel/event/AbstractIgnoreExceptionReadListener.java index 22a95f03..1e93397e 100644 --- a/src/main/java/com/alibaba/excel/event/AbstractIgnoreExceptionReadListener.java +++ b/src/main/java/com/alibaba/excel/event/AbstractIgnoreExceptionReadListener.java @@ -1,6 +1,7 @@ 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 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; diff --git a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java index 176bd798..4b1b802a 100644 --- a/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java +++ b/src/main/java/com/alibaba/excel/event/AnalysisEventListener.java @@ -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 implements ReadListener { */ public void invokeHeadMap(Map 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. diff --git a/src/main/java/com/alibaba/excel/metadata/CellExtra.java b/src/main/java/com/alibaba/excel/metadata/CellExtra.java index 3570eb96..3a9c2b3b 100644 --- a/src/main/java/com/alibaba/excel/metadata/CellExtra.java +++ b/src/main/java/com/alibaba/excel/metadata/CellExtra.java @@ -1,18 +1,121 @@ 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 { - private String note; + /** + * Cell extra type + */ + private CellExtraTypeEnum type; + /** + * Cell extra data + */ + private String text; + /** + * First row index,if this object is an interval + */ + private Integer firstRowIndex; + /** + * First column index,if this object is an interval + */ + private Integer firstColumnIndex; + /** + * Last row index,if this object is an interval + */ + private Integer lastRowIndex; + /** + * 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, columnIndex, rowIndex, columnIndex); + } + + public CellExtra(CellExtraTypeEnum type, String text, Integer firstRowIndex, Integer firstColumnIndex, + Integer lastRowIndex, 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 String getNote() { - return note; + public Integer getLastColumnIndex() { + return lastColumnIndex; } - public void setNote(String note) { - this.note = note; + public void setLastColumnIndex(Integer lastColumnIndex) { + this.lastColumnIndex = lastColumnIndex; } } diff --git a/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java index ae3b79c1..342d9433 100644 --- a/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java +++ b/src/main/java/com/alibaba/excel/read/builder/ExcelReaderBuilder.java @@ -2,6 +2,8 @@ package com.alibaba.excel.read.builder; import java.io.File; import java.io.InputStream; +import java.util.HashSet; +import java.util.List; import javax.xml.parsers.SAXParserFactory; @@ -9,9 +11,10 @@ import com.alibaba.excel.ExcelReader; import com.alibaba.excel.cache.ReadCache; import com.alibaba.excel.cache.selector.ReadCacheSelector; import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.enums.CellExtraTypeEnum; import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.event.SyncReadListener; import com.alibaba.excel.read.listener.ModelBuildEventListener; -import com.alibaba.excel.read.listener.ReadListener; import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.support.ExcelTypeEnum; @@ -158,6 +161,21 @@ public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder()); + } + readWorkbook.getExtraReadSet().add(extraType); + return this; + } + /** * Whether to use the default listener, which is used by default. *

@@ -175,11 +193,24 @@ public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder List doReadAllSync() { ExcelReader excelReader = build(); + SyncReadListener syncReadListener = new SyncReadListener(); + registerReadListener(syncReadListener); excelReader.readAll(); excelReader.finish(); - return excelReader; + return (List)syncReadListener.getList(); } public ExcelReaderSheetBuilder sheet() { diff --git a/src/main/java/com/alibaba/excel/read/listener/ReadListener.java b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java index 142c531b..f1d341f5 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ReadListener.java +++ b/src/main/java/com/alibaba/excel/read/listener/ReadListener.java @@ -5,6 +5,7 @@ import java.util.Map; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.Listener; import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.CellExtra; /** * Interface to listen for read results @@ -40,6 +41,16 @@ public interface ReadListener extends Listener { */ void invoke(T data, AnalysisContext context); + /** + * The current method is called when extra information is returned + * + * @param extra + * extra information + * @param context + * analysis context + */ + void extra(CellExtra extra, AnalysisContext context); + /** * if have something to do after all analysis * diff --git a/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java b/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java index c08ab18e..c9e4db93 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java +++ b/src/main/java/com/alibaba/excel/read/metadata/ReadWorkbook.java @@ -9,7 +9,7 @@ import javax.xml.parsers.SAXParserFactory; import com.alibaba.excel.cache.ReadCache; import com.alibaba.excel.cache.selector.ReadCacheSelector; import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.enums.ExtraReadEnum; +import com.alibaba.excel.enums.CellExtraTypeEnum; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.read.listener.ModelBuildEventListener; import com.alibaba.excel.support.ExcelTypeEnum; @@ -88,9 +88,9 @@ public class ReadWorkbook extends ReadBasicParameter { /** * Read some additional fields. None are read by default. * - * @see ExtraReadEnum + * @see CellExtraTypeEnum */ - private Set extraReadSet; + private Set extraReadSet; /** * The default is all excel objects.Default is true. *

@@ -221,11 +221,11 @@ public class ReadWorkbook extends ReadBasicParameter { this.useDefaultListener = useDefaultListener; } - public Set getExtraReadSet() { + public Set getExtraReadSet() { return extraReadSet; } - public void setExtraReadSet(Set extraReadSet) { + public void setExtraReadSet(Set extraReadSet) { this.extraReadSet = extraReadSet; } } diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadRowHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadRowHolder.java index da745096..d81df87c 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadRowHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadRowHolder.java @@ -35,10 +35,12 @@ public class ReadRowHolder implements Holder { */ private GlobalConfiguration globalConfiguration; - public ReadRowHolder(Integer rowIndex, RowTypeEnum rowType, GlobalConfiguration globalConfiguration) { + public ReadRowHolder(Integer rowIndex, RowTypeEnum rowType, GlobalConfiguration globalConfiguration, + Map cellMap) { this.rowIndex = rowIndex; this.rowType = rowType; this.globalConfiguration = globalConfiguration; + this.cellMap = cellMap; } public GlobalConfiguration getGlobalConfiguration() { diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java index 84dd4c4a..87185dc2 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadSheetHolder.java @@ -1,6 +1,12 @@ package com.alibaba.excel.read.metadata.holder; +import java.util.LinkedHashMap; +import java.util.Map; + import com.alibaba.excel.enums.HolderEnum; +import com.alibaba.excel.metadata.Cell; +import com.alibaba.excel.metadata.CellData; +import com.alibaba.excel.metadata.CellExtra; import com.alibaba.excel.read.metadata.ReadSheet; /** @@ -29,6 +35,22 @@ public class ReadSheetHolder extends AbstractReadHolder { * Gets the total number of rows , data may be inaccurate */ private Integer approximateTotalRowNumber; + /** + * Data storage of the current row. + */ + private Map cellMap; + /** + * Data storage of the current extra cell. + */ + private CellExtra cellExtra; + /** + * Index of the current row. + */ + private Integer rowIndex; + /** + * Current CellData + */ + private CellData tempCellData; public ReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { super(readSheet, readWorkbookHolder, readWorkbookHolder.getReadWorkbook().getConvertAllFiled()); @@ -36,6 +58,7 @@ public class ReadSheetHolder extends AbstractReadHolder { this.parentReadWorkbookHolder = readWorkbookHolder; this.sheetNo = readSheet.getSheetNo(); this.sheetName = readSheet.getSheetName(); + this.cellMap = new LinkedHashMap(); } public ReadSheet getReadSheet() { @@ -71,7 +94,6 @@ public class ReadSheetHolder extends AbstractReadHolder { } /** - * * Approximate total number of rows * * @return @@ -95,6 +117,38 @@ public class ReadSheetHolder extends AbstractReadHolder { this.approximateTotalRowNumber = approximateTotalRowNumber; } + public Map getCellMap() { + return cellMap; + } + + public void setCellMap(Map cellMap) { + this.cellMap = cellMap; + } + + public Integer getRowIndex() { + return rowIndex; + } + + public void setRowIndex(Integer rowIndex) { + this.rowIndex = rowIndex; + } + + public CellData getTempCellData() { + return tempCellData; + } + + public void setTempCellData(CellData tempCellData) { + this.tempCellData = tempCellData; + } + + public CellExtra getCellExtra() { + return cellExtra; + } + + public void setCellExtra(CellExtra cellExtra) { + this.cellExtra = cellExtra; + } + @Override public HolderEnum holderType() { return HolderEnum.SHEET; diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java index 1c1b2420..7ad89726 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/ReadWorkbookHolder.java @@ -7,17 +7,12 @@ import java.util.HashSet; import java.util.List; import java.util.Set; -import javax.xml.parsers.SAXParserFactory; - -import org.apache.poi.openxml4j.opc.OPCPackage; -import org.apache.poi.poifs.filesystem.POIFSFileSystem; - import com.alibaba.excel.cache.ReadCache; import com.alibaba.excel.cache.selector.EternalReadCacheSelector; import com.alibaba.excel.cache.selector.ReadCacheSelector; import com.alibaba.excel.cache.selector.SimpleReadCacheSelector; import com.alibaba.excel.context.AnalysisContext; -import com.alibaba.excel.enums.ExtraReadEnum; +import com.alibaba.excel.enums.CellExtraTypeEnum; import com.alibaba.excel.enums.HolderEnum; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelAnalysisException; @@ -91,9 +86,9 @@ public class ReadWorkbookHolder extends AbstractReadHolder { /** * Read some additional fields. None are read by default. * - * @see ExtraReadEnum + * @see CellExtraTypeEnum */ - private Set extraReadSet; + private Set extraReadSet; /** * Actual sheet data */ @@ -101,7 +96,7 @@ public class ReadWorkbookHolder extends AbstractReadHolder { /** * Parameter sheet data */ - private List parametersheetDataList; + private List parameterSheetDataList; /** * Read all */ @@ -152,11 +147,6 @@ public class ReadWorkbookHolder extends AbstractReadHolder { this.autoCloseStream = readWorkbook.getAutoCloseStream(); } - this.excelType = readWorkbook.getExcelType(); - - if (ExcelTypeEnum.XLS == excelType && getGlobalConfiguration().getUse1904windowing() == null) { - getGlobalConfiguration().setUse1904windowing(Boolean.FALSE); - } this.customObject = readWorkbook.getCustomObject(); if (readWorkbook.getIgnoreEmptyRow() == null) { this.ignoreEmptyRow = Boolean.TRUE; @@ -181,7 +171,7 @@ public class ReadWorkbookHolder extends AbstractReadHolder { this.defaultReturnMap = readWorkbook.getDefaultReturnMap(); } if (readWorkbook.getExtraReadSet() == null) { - this.extraReadSet = new HashSet(); + this.extraReadSet = new HashSet(); } else { this.extraReadSet = readWorkbook.getExtraReadSet(); } @@ -309,11 +299,11 @@ public class ReadWorkbookHolder extends AbstractReadHolder { this.password = password; } - public Set getExtraReadSet() { + public Set getExtraReadSet() { return extraReadSet; } - public void setExtraReadSet(Set extraReadSet) { + public void setExtraReadSet(Set extraReadSet) { this.extraReadSet = extraReadSet; } @@ -325,12 +315,12 @@ public class ReadWorkbookHolder extends AbstractReadHolder { this.actualSheetDataList = actualSheetDataList; } - public List getParametersheetDataList() { - return parametersheetDataList; + public List getParameterSheetDataList() { + return parameterSheetDataList; } - public void setParametersheetDataList(List parametersheetDataList) { - this.parametersheetDataList = parametersheetDataList; + public void setParameterSheetDataList(List parameterSheetDataList) { + this.parameterSheetDataList = parameterSheetDataList; } public Boolean getReadAll() { diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadSheetHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadSheetHolder.java index a77a8d38..d0171ffc 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadSheetHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadSheetHolder.java @@ -1,12 +1,9 @@ package com.alibaba.excel.read.metadata.holder.xls; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.Map; import com.alibaba.excel.enums.RowTypeEnum; -import com.alibaba.excel.metadata.Cell; -import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; @@ -21,22 +18,10 @@ public class XlsReadSheetHolder extends ReadSheetHolder { * Row type.Temporary storage, last set in ReadRowHolder. */ private RowTypeEnum tempRowType; - /** - * Data storage of the current row. - */ - private Map cellMap; - /** - * Index of the current row. - */ - private Integer rowIndex; /** * Ignore record. */ private Boolean ignoreRecord; - /** - * Temp Cell Data. - */ - private CellData tempCellData; /** * Temp object index. */ @@ -48,7 +33,6 @@ public class XlsReadSheetHolder extends ReadSheetHolder { public XlsReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { super(readSheet, readWorkbookHolder); - cellMap = new LinkedHashMap(); ignoreRecord = Boolean.FALSE; tempRowType = RowTypeEnum.EMPTY; objectCacheMap = new HashMap(16); @@ -62,22 +46,6 @@ public class XlsReadSheetHolder extends ReadSheetHolder { this.tempRowType = tempRowType; } - public Map getCellMap() { - return cellMap; - } - - public void setCellMap(Map cellMap) { - this.cellMap = cellMap; - } - - public Integer getRowIndex() { - return rowIndex; - } - - public void setRowIndex(Integer rowIndex) { - this.rowIndex = rowIndex; - } - public Boolean getIgnoreRecord() { return ignoreRecord; } @@ -86,14 +54,6 @@ public class XlsReadSheetHolder extends ReadSheetHolder { this.ignoreRecord = ignoreRecord; } - public CellData getTempCellData() { - return tempCellData; - } - - public void setTempCellData(CellData tempCellData) { - this.tempCellData = tempCellData; - } - public Integer getTempObjectIndex() { return tempObjectIndex; } diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java index c4b698cb..70c1c03a 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/xls/XlsReadWorkbookHolder.java @@ -1,5 +1,6 @@ package com.alibaba.excel.read.metadata.holder.xls; +import java.util.ArrayList; import java.util.List; import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; @@ -9,6 +10,7 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem; import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; +import com.alibaba.excel.support.ExcelTypeEnum; /** * Workbook holder @@ -27,7 +29,7 @@ public class XlsReadWorkbookHolder extends ReadWorkbookHolder { /** * HSSFWorkbook */ - private HSSFWorkbook hsffWorkbook; + private HSSFWorkbook hssfWorkbook; /** * Bound sheet record list. */ @@ -43,6 +45,12 @@ public class XlsReadWorkbookHolder extends ReadWorkbookHolder { public XlsReadWorkbookHolder(ReadWorkbook readWorkbook) { super(readWorkbook); + this.boundSheetRecordList = new ArrayList(); + this.needReadSheet = Boolean.TRUE; + setExcelType(ExcelTypeEnum.XLS); + if (getGlobalConfiguration().getUse1904windowing() == null) { + getGlobalConfiguration().setUse1904windowing(Boolean.FALSE); + } } public POIFSFileSystem getPoifsFileSystem() { @@ -61,12 +69,12 @@ public class XlsReadWorkbookHolder extends ReadWorkbookHolder { this.formatTrackingHSSFListener = formatTrackingHSSFListener; } - public HSSFWorkbook getHsffWorkbook() { - return hsffWorkbook; + public HSSFWorkbook getHssfWorkbook() { + return hssfWorkbook; } - public void setHsffWorkbook(HSSFWorkbook hsffWorkbook) { - this.hsffWorkbook = hsffWorkbook; + public void setHssfWorkbook(HSSFWorkbook hssfWorkbook) { + this.hssfWorkbook = hssfWorkbook; } public List getBoundSheetRecordList() { diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java index 2e1174d7..46b92818 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadSheetHolder.java @@ -1,5 +1,8 @@ package com.alibaba.excel.read.metadata.holder.xlsx; +import java.util.Deque; +import java.util.LinkedList; + import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.holder.ReadSheetHolder; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; @@ -10,10 +13,57 @@ import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; * @author Jiaju Zhuang */ public class XlsxReadSheetHolder extends ReadSheetHolder { - - + /** + * Record the label of the current operation to prevent NPE. + */ + private Deque tagDeque; + /** + * Current Column + */ + private Integer columnIndex; + /** + * Data for current label. + */ + private StringBuilder tempData; + /** + * Formula for current label. + */ + private StringBuilder tempFormula; public XlsxReadSheetHolder(ReadSheet readSheet, ReadWorkbookHolder readWorkbookHolder) { super(readSheet, readWorkbookHolder); + this.tagDeque = new LinkedList(); + } + + public Deque getTagDeque() { + return tagDeque; + } + + public void setTagDeque(Deque tagDeque) { + this.tagDeque = tagDeque; + } + + public Integer getColumnIndex() { + return columnIndex; + } + + public void setColumnIndex(Integer columnIndex) { + this.columnIndex = columnIndex; + } + + public StringBuilder getTempData() { + return tempData; + } + + public void setTempData(StringBuilder tempData) { + this.tempData = tempData; + } + + public StringBuilder getTempFormula() { + return tempFormula; + } + + public void setTempFormula(StringBuilder tempFormula) { + this.tempFormula = tempFormula; } } diff --git a/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java b/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java index 9542366c..066131d3 100644 --- a/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java +++ b/src/main/java/com/alibaba/excel/read/metadata/holder/xlsx/XlsxReadWorkbookHolder.java @@ -7,6 +7,7 @@ import org.apache.poi.xssf.model.StylesTable; import com.alibaba.excel.read.metadata.ReadWorkbook; import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; +import com.alibaba.excel.support.ExcelTypeEnum; /** * Workbook holder @@ -37,6 +38,7 @@ public class XlsxReadWorkbookHolder extends ReadWorkbookHolder { public XlsxReadWorkbookHolder(ReadWorkbook readWorkbook) { super(readWorkbook); this.saxParserFactoryName = readWorkbook.getXlsxSAXParserFactoryName(); + setExcelType(ExcelTypeEnum.XLSX); } public OPCPackage getOpcPackage() { diff --git a/src/main/java/com/alibaba/excel/read/processor/AnalysisEventProcessor.java b/src/main/java/com/alibaba/excel/read/processor/AnalysisEventProcessor.java index cd485382..360ae97d 100644 --- a/src/main/java/com/alibaba/excel/read/processor/AnalysisEventProcessor.java +++ b/src/main/java/com/alibaba/excel/read/processor/AnalysisEventProcessor.java @@ -9,6 +9,13 @@ import com.alibaba.excel.context.AnalysisContext; * @author jipengfei */ public interface AnalysisEventProcessor { + /** + * Read extra information + * + * @param analysisContext + */ + void extra(AnalysisContext analysisContext); + /** * End row * diff --git a/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java b/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java index 6b5b0af8..ddd19504 100644 --- a/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java +++ b/src/main/java/com/alibaba/excel/read/processor/DefaultAnalysisEventProcessor.java @@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.enums.HeadKindEnum; +import com.alibaba.excel.enums.RowTypeEnum; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelAnalysisStopException; import com.alibaba.excel.metadata.CellData; @@ -28,29 +29,22 @@ import com.alibaba.excel.util.StringUtils; public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAnalysisEventProcessor.class); + @Override + public void extra(AnalysisContext analysisContext) { + dealExtra(analysisContext); + } + @Override public void endRow(AnalysisContext analysisContext) { - switch (analysisContext.readRowHolder().getRowType()) { - case EMPTY: - if (LOGGER.isDebugEnabled()) { - LOGGER.warn("Empty row!"); - } - if (analysisContext.readWorkbookHolder().getIgnoreEmptyRow()) { - return; - } - // Need to continue to notify invoke. - dealData(analysisContext); - break; - case DATA: - dealData(analysisContext); - break; - case EXTRA: - dealExtra(analysisContext); - break; - default: - throw new ExcelAnalysisException("Wrong row type."); + if (RowTypeEnum.EMPTY.equals(analysisContext.readRowHolder().getRowType())) { + if (LOGGER.isDebugEnabled()) { + LOGGER.warn("Empty row!"); + } + if (analysisContext.readWorkbookHolder().getIgnoreEmptyRow()) { + return; + } } - + dealData(analysisContext); } @Override @@ -61,13 +55,34 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { } private void dealExtra(AnalysisContext analysisContext) { + for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) { + try { + readListener.extra(analysisContext.readSheetHolder().getCellExtra(), analysisContext); + } catch (Exception e) { + onException(analysisContext, e); + break; + } + if (!readListener.hasNext(analysisContext)) { + throw new ExcelAnalysisStopException(); + } + } + } - + private void onException(AnalysisContext analysisContext, Exception e) { + for (ReadListener readListenerException : analysisContext.currentReadHolder().readListenerList()) { + try { + readListenerException.onException(e, analysisContext); + } catch (RuntimeException re) { + throw re; + } catch (Exception e1) { + throw new ExcelAnalysisException(e1.getMessage(), e1); + } + } } private void dealData(AnalysisContext analysisContext) { ReadRowHolder readRowHolder = analysisContext.readRowHolder(); - Map cellDataMap = (Map) readRowHolder.getCellMap(); + Map cellDataMap = (Map)readRowHolder.getCellMap(); readRowHolder.setCurrentRowAnalysisResult(cellDataMap); int rowIndex = readRowHolder.getRowIndex(); int currentHeadRowNumber = analysisContext.readSheetHolder().getHeadRowNumber(); @@ -78,7 +93,6 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { if (!isData && currentHeadRowNumber == rowIndex + 1) { buildHead(analysisContext, cellDataMap); } - // Now is data for (ReadListener readListener : analysisContext.currentReadHolder().readListenerList()) { try { @@ -88,15 +102,7 @@ public class DefaultAnalysisEventProcessor implements AnalysisEventProcessor { readListener.invokeHead(cellDataMap, analysisContext); } } catch (Exception e) { - for (ReadListener readListenerException : analysisContext.currentReadHolder().readListenerList()) { - try { - readListenerException.onException(e, analysisContext); - } catch (RuntimeException re) { - throw re; - } catch (Exception e1) { - throw new ExcelAnalysisException(e1.getMessage(), e1); - } - } + onException(analysisContext, e); break; } if (!readListener.hasNext(analysisContext)) { diff --git a/src/main/java/com/alibaba/excel/util/SheetUtils.java b/src/main/java/com/alibaba/excel/util/SheetUtils.java index fb2c59e5..c2c727c7 100644 --- a/src/main/java/com/alibaba/excel/util/SheetUtils.java +++ b/src/main/java/com/alibaba/excel/util/SheetUtils.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.read.metadata.ReadSheet; +import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder; /** * Sheet utils @@ -14,21 +15,22 @@ import com.alibaba.excel.read.metadata.ReadSheet; public class SheetUtils { private static final Logger LOGGER = LoggerFactory.getLogger(SheetUtils.class); - private SheetUtils() { - } + private SheetUtils() {} /** * Match the parameters to the actual sheet * - * @param readSheet actual sheet + * @param readSheet + * actual sheet * @param analysisContext * @return */ public static ReadSheet match(ReadSheet readSheet, AnalysisContext analysisContext) { - if (analysisContext.readAll()) { + ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder(); + if (readWorkbookHolder.getReadAll()) { return readSheet; } - for (ReadSheet parameterReadSheet : analysisContext.readSheetList()) { + for (ReadSheet parameterReadSheet : readWorkbookHolder.getParameterSheetDataList()) { if (parameterReadSheet == null) { continue; } @@ -45,7 +47,7 @@ public class SheetUtils { if (!StringUtils.isEmpty(parameterSheetName)) { boolean autoTrim = (parameterReadSheet.getAutoTrim() != null && parameterReadSheet.getAutoTrim()) || (parameterReadSheet.getAutoTrim() == null - && analysisContext.readWorkbookHolder().getGlobalConfiguration().getAutoTrim()); + && analysisContext.readWorkbookHolder().getGlobalConfiguration().getAutoTrim()); if (autoTrim) { parameterSheetName = parameterSheetName.trim(); } diff --git a/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraData.java b/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraData.java new file mode 100644 index 00000000..61822fa8 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraData.java @@ -0,0 +1,14 @@ +package com.alibaba.easyexcel.test.core.extra; + +import lombok.Data; + +/** + * @author Jiaju Zhuang + */ +@Data +public class ExtraData { + + private String row1; + + private String row2; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataListener.java b/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataListener.java new file mode 100644 index 00000000..9039ab06 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataListener.java @@ -0,0 +1,55 @@ +package com.alibaba.easyexcel.test.core.extra; + +import org.junit.Assert; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.metadata.CellExtra; +import com.alibaba.fastjson.JSON; + +/** + * @author Jiaju Zhuang + */ +public class ExtraDataListener extends AnalysisEventListener { + private static final Logger LOGGER = LoggerFactory.getLogger(ExtraData.class); + + @Override + public void invoke(ExtraData data, AnalysisContext context) {} + + @Override + public void doAfterAllAnalysed(AnalysisContext context) {} + + @Override + public void extra(CellExtra extra, AnalysisContext context) { + LOGGER.info("extra data:{}", JSON.toJSONString(extra)); + switch (extra.getType()) { + case COMMENT: + Assert.assertEquals("批注的内容", extra.getText()); + Assert.assertEquals(4, (int)extra.getRowIndex()); + Assert.assertEquals(0, (int)extra.getColumnIndex()); + break; + case HYPERLINK: + if ("Sheet1!A1".equals(extra.getText())) { + Assert.assertEquals(1, (int)extra.getRowIndex()); + Assert.assertEquals(0, (int)extra.getColumnIndex()); + } else if ("Sheet2!A1".equals(extra.getText())) { + Assert.assertEquals(2, (int)extra.getFirstRowIndex()); + Assert.assertEquals(0, (int)extra.getFirstColumnIndex()); + Assert.assertEquals(3, (int)extra.getLastRowIndex()); + Assert.assertEquals(1, (int)extra.getLastColumnIndex()); + } else { + Assert.fail("Unknown hyperlink!"); + } + break; + case MERGE: + Assert.assertEquals(5, (int)extra.getFirstRowIndex()); + Assert.assertEquals(0, (int)extra.getFirstColumnIndex()); + Assert.assertEquals(6, (int)extra.getLastRowIndex()); + Assert.assertEquals(1, (int)extra.getLastColumnIndex()); + break; + default: + } + } +} diff --git a/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java b/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java new file mode 100644 index 00000000..cf7418d5 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/core/extra/ExtraDataTest.java @@ -0,0 +1,44 @@ +package com.alibaba.easyexcel.test.core.extra; + +import java.io.File; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.easyexcel.test.util.TestFileUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.enums.CellExtraTypeEnum; + +/** + * + * @author Jiaju Zhuang + */ +public class ExtraDataTest { + private static final Logger LOGGER = LoggerFactory.getLogger(ExtraDataTest.class); + private static File file03; + private static File file07; + + @BeforeClass + public static void init() { + file03 = TestFileUtil.readFile("extra" + File.separator + "extra.xls"); + file07 = TestFileUtil.readFile("extra" + File.separator + "extra.xlsx"); + } + + @Test + public void t01Read07() { + read(file07); + } + + @Test + public void t02Read03() { + read(file03); + } + + private void read(File file) { + EasyExcel.read(file, ExtraData.class, new ExtraDataListener()).extraRead(CellExtraTypeEnum.COMMENT) + .extraRead(CellExtraTypeEnum.HYPERLINK).extraRead(CellExtraTypeEnum.MERGE).sheet().doRead(); + } + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java index ece5aa0e..30325d14 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/Lock2Test.java @@ -3,6 +3,7 @@ package com.alibaba.easyexcel.test.temp; import java.io.File; import java.util.List; +import org.apache.poi.hssf.util.CellReference; import org.junit.Ignore; import org.junit.Test; import org.slf4j.Logger; @@ -31,6 +32,11 @@ public class Lock2Test { } } + @Test + public void testc() throws Exception { + LOGGER.info("reslut:{}", JSON.toJSONString(new CellReference("B3"))); + } + @Test public void simpleRead() { // 写法1: diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java index bcb1d999..21e0d9c3 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/read/CommentTest.java @@ -25,7 +25,7 @@ public class CommentTest { @Test public void comment() throws Exception { File file = new File("D:\\test\\comment.xls"); - List> datas = EasyExcel.read(file).sheet(0).doReadSync(); + List> datas = EasyExcel.read(file).doReadAllSync(); for (Map data : datas) { LOGGER.info("数据:{}", JSON.toJSONString(data.get(0))); } diff --git a/src/test/resources/demo/demo.xlsx b/src/test/resources/demo/demo.xlsx index 48d3f87a..662bb971 100644 Binary files a/src/test/resources/demo/demo.xlsx and b/src/test/resources/demo/demo.xlsx differ diff --git a/src/test/resources/extra/extra.xls b/src/test/resources/extra/extra.xls new file mode 100644 index 00000000..89f389be Binary files /dev/null and b/src/test/resources/extra/extra.xls differ diff --git a/src/test/resources/extra/extra.xlsx b/src/test/resources/extra/extra.xlsx new file mode 100644 index 00000000..4936b05a Binary files /dev/null and b/src/test/resources/extra/extra.xlsx differ diff --git a/update.md b/update.md index 8f2c4774..5cdab9b4 100644 --- a/update.md +++ b/update.md @@ -1,10 +1,12 @@ # 2.2.0-beta1 +* 重写主流程,代码更加优雅 * 修复用String接收日期、数字和excel显示不一致的bug(不是完美修复,但是大部分情况已经兼容) * 降低Ehcache版本 3.7.1(jkd7) -> 3.4.0(jdk6) * 修复xls 用Map接收时多次接收会是同一个对象的bug * 修复浮点型数据导入到excel 会丢失精度的bug -* 新增支持接收批注 +* 新增支持读取批注、超链接、合并单元格 * 如果是`RuntimeException`则不再封装对象 +* 新增`CellData`可以获取行列号 # 2.1.4