提交 e6319097 编写于 作者: 庄家钜's avatar 庄家钜

完成新增支持读取批注、超链接、合并单元格

上级 13ca08e1
......@@ -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;
......
......@@ -35,6 +35,7 @@ public class XlsListSheetListener implements HSSFListener {
public XlsListSheetListener(XlsReadContext xlsReadContext) {
this.xlsReadContext = xlsReadContext;
xlsReadContext.xlsReadWorkbookHolder().setNeedReadSheet(Boolean.FALSE);
}
@Override
......
......@@ -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
*
......
......@@ -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);
}
......
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;
}
}
......@@ -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) {
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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) {
......
......@@ -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<Integer, Cell>());
} else if (record instanceof MissingCellDummyRecord) {
......
......@@ -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) {
......
......@@ -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);
......
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);
}
}
......@@ -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) {
......
......@@ -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;
......
......@@ -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) {
......
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);
}
}
}
......@@ -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);
}
}
......@@ -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) {
......
......@@ -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;
......
......@@ -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) {
......
......@@ -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));
......
......@@ -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
......
......@@ -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;
......
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<XlsxCellHandler> buildCellHandlers(AnalysisContext analysisContext, StylesTable stylesTable) {
List<XlsxCellHandler> result = new ArrayList<XlsxCellHandler>();
result.add(new CountRowCellHandler(analysisContext));
DefaultCellHandler defaultCellHandler = new DefaultCellHandler(analysisContext, stylesTable);
result.add(defaultCellHandler);
result.add(new ProcessResultCellHandler(analysisContext, defaultCellHandler));
return result;
}
}
package com.alibaba.excel.analysis.v07;
import java.util.Map;
import com.alibaba.excel.metadata.CellData;
/**
* Result holder
*
* @author jipengfei
*/
public interface XlsxRowResultHolder {
/**
* Clear Result
*/
void clearResult();
/**
* Append current 'cellValue'
*
* @param ch
* @param start
* @param length
*/
void appendCurrentCellValue(char[] ch, int start, int length);
/**
* Get row content
*
* @return
*/
Map<Integer, CellData> getCurRowContent();
}
......@@ -15,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<ReadSheet> sheetList;
private Map<Integer, InputStream> sheetMap;
/**
* excel comments key: sheetNo value: CommentsTable
*/
private Map<Integer, CommentsTable> 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<ReadSheet>();
sheetMap = new HashMap<Integer, InputStream>();
XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
commentsTableMap = new HashMap<Integer, CommentsTable>();
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<CellAddress, XSSFComment> cellComments = commentsTable.getCellComments();
for (XSSFComment xssfComment : cellComments.values()) {
CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.COMMENT, xssfComment.getString().toString(),
xssfComment.getRow(), xssfComment.getColumn());
xlsxReadContext.readSheetHolder().setCellExtra(cellExtra);
xlsxReadContext.analysisEventProcessor().extra(xlsxReadContext);
}
}
}
package com.alibaba.excel.analysis.v07.handlers;
import java.math.BigDecimal;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
import com.alibaba.excel.util.BooleanUtils;
/**
* Cell Value Handler
*
* @author jipengfei
*/
public abstract class AbstractCellValueTagHandler extends AbstractXlsxTagHandler {
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
CellData tempCellData = xlsxReadSheetHolder.getTempCellData();
StringBuilder tempData = xlsxReadSheetHolder.getTempData();
CellDataTypeEnum oldType = tempCellData.getType();
switch (oldType) {
case DIRECT_STRING:
case STRING:
case ERROR:
tempCellData.setStringValue(tempData.toString());
break;
case BOOLEAN:
tempCellData.setBooleanValue(BooleanUtils.valueOf(tempData.toString()));
break;
case NUMBER:
case EMPTY:
tempCellData.setType(CellDataTypeEnum.NUMBER);
tempCellData.setNumberValue(new BigDecimal(tempData.toString()));
break;
default:
throw new IllegalStateException("Cannot set values now");
}
// set string value
setStringValue(xlsxReadContext);
if (tempCellData.getStringValue() != null
&& xlsxReadContext.currentReadHolder().globalConfiguration().getAutoTrim()) {
tempCellData.setStringValue(tempCellData.getStringValue());
}
tempCellData.checkEmpty();
xlsxReadSheetHolder.getCellMap().put(xlsxReadSheetHolder.getColumnIndex(), tempCellData);
}
@Override
public void characters(XlsxReadContext xlsxReadContext, char[] ch, int start, int length) {
xlsxReadContext.xlsxReadSheetHolder().getTempData().append(ch, start, length);
}
/**
* Set string value.
*/
protected abstract void setStringValue(XlsxReadContext xlsxReadContext);
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
/**
* Abstract tag handler
*
* @author Jiaju Zhuang
*/
public abstract class AbstractXlsxTagHandler implements XlsxTagHandler {
@Override
public boolean support(XlsxReadContext xlsxReadContext) {
return true;
}
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
}
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
}
@Override
public void characters(XlsxReadContext xlsxReadContext, char[] ch, int start, int length) {
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.read.metadata.holder.xlsx.XlsxReadSheetHolder;
/**
* Cell Handler
*
* @author jipengfei
*/
public class CellFormulaTagHandler extends AbstractXlsxTagHandler {
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
xlsxReadSheetHolder.getTempCellData().setFormula(Boolean.TRUE);
xlsxReadSheetHolder.setTempFormula(new StringBuilder());
}
@Override
public void endElement(XlsxReadContext xlsxReadContext, String name) {
XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder();
xlsxReadSheetHolder.getTempCellData().setFormulaValue(xlsxReadSheetHolder.getTempFormula().toString());
}
@Override
public void characters(XlsxReadContext xlsxReadContext, char[] ch, int start, int length) {
xlsxReadContext.xlsxReadSheetHolder().getTempFormula().append(ch, start, length);
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.metadata.CellData;
/**
* Cell inline string value handler
*
* @author jipengfei
*/
public class CellInlineStringValueTagHandler extends AbstractCellValueTagHandler {
@Override
protected void setStringValue(XlsxReadContext xlsxReadContext) {
// This is a special form of string
CellData tempCellData = xlsxReadContext.xlsxReadSheetHolder().getTempCellData();
XSSFRichTextString richTextString = new XSSFRichTextString(tempCellData.getStringValue());
tempCellData.setStringValue(richTextString.toString());
}
}
package com.alibaba.excel.analysis.v07.handlers;
import 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()));
}
}
}
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:
}
}
}
......@@ -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) {
}
}
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<String> currentTagDeque = new LinkedList<String>();
private int curCol;
private Map<Integer, CellData> curRowContent = new LinkedHashMap<Integer, CellData>();
private CellData currentCellData;
private StringBuilder dataStringBuilder;
private StringBuilder formulaStringBuilder;
@Override
public void clearResult() {
curRowContent = new LinkedHashMap<Integer, CellData>();
}
@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<Integer, CellData> getCurRowContent() {
return curRowContent;
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.util.StringUtils;
/**
* Cell Handler
*
* @author Jiaju Zhuang
*/
public class HyperlinkTagHandler extends AbstractXlsxTagHandler {
@Override
public boolean support(XlsxReadContext xlsxReadContext) {
return xlsxReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.HYPERLINK);
}
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
String ref = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_REF);
String location = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_LOCATION);
if (StringUtils.isEmpty(ref)) {
return;
}
CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.HYPERLINK, location, ref);
xlsxReadContext.readSheetHolder().setCellExtra(cellExtra);
xlsxReadContext.analysisEventProcessor().extra(xlsxReadContext);
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.constant.ExcelXmlConstants;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.util.StringUtils;
/**
* Cell Handler
*
* @author Jiaju Zhuang
*/
public class MergeCellTagHandler extends AbstractXlsxTagHandler {
@Override
public boolean support(XlsxReadContext xlsxReadContext) {
return xlsxReadContext.readWorkbookHolder().getExtraReadSet().contains(CellExtraTypeEnum.MERGE);
}
@Override
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
String ref = attributes.getValue(ExcelXmlConstants.ATTRIBUTE_REF);
if (StringUtils.isEmpty(ref)) {
return;
}
CellExtra cellExtra = new CellExtra(CellExtraTypeEnum.MERGE, null, ref);
xlsxReadContext.readSheetHolder().setCellExtra(cellExtra);
xlsxReadContext.analysisEventProcessor().extra(xlsxReadContext);
}
}
package com.alibaba.excel.analysis.v07.handlers;
import 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;
......@@ -13,18 +16,20 @@ import com.alibaba.excel.util.PositionUtils;
*
* @author jipengfei
*/
public class ProcessResultCellHandler implements XlsxCellHandler {
public class RowTagHandler extends AbstractXlsxTagHandler {
@Override
public void startHandle(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
public void startElement(XlsxReadContext xlsxReadContext, String name, Attributes attributes) {
xlsxReadContext.readRowHolder(
new ReadRowHolder(PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.POSITION)), RowTypeEnum.DATA,
xlsxReadContext.readSheetHolder().getGlobalConfiguration()));
new ReadRowHolder(PositionUtils.getRowByRowTagt(attributes.getValue(ExcelXmlConstants.POSITION)),
RowTypeEnum.DATA, xlsxReadContext.readSheetHolder().getGlobalConfiguration(), null));
}
@Override
public void endHandle(XlsxReadContext xlsxReadContext, String name) {
public void endElement(XlsxReadContext xlsxReadContext, String name) {
xlsxReadContext.readRowHolder().setCellMap(xlsxReadContext.xlsxReadSheetHolder().getCellMap());
xlsxReadContext.analysisEventProcessor().endRow(xlsxReadContext);
xlsxReadContext.xlsxReadSheetHolder().setCellMap(new LinkedHashMap<Integer, Cell>());
}
}
package com.alibaba.excel.analysis.v07.handlers;
import org.xml.sax.Attributes;
import com.alibaba.excel.context.xlsx.XlsxReadContext;
/**
* 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);
}
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);
}
......@@ -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<String, XlsxCellHandler> XLSX_CELL_HANDLER_MAP = new HashMap<String, XlsxCellHandler>(16);
private static final Map<String, XlsxTagHandler> XLSX_CELL_HANDLER_MAP = new HashMap<String, XlsxTagHandler>(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();
}
}
......@@ -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";
}
......@@ -92,20 +92,6 @@ public interface AnalysisContext {
*/
void readSheetList(List<ReadSheet> readSheetList);
/**
* Read all sheets
*
* @return
*/
Boolean readAll();
/**
* Read all sheets
*
* @return
*/
void readAll(Boolean readAll);
/**
* get current sheet
*
......
......@@ -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);
......
package com.alibaba.excel.enums;
/**
* Read some extra data
* Extra data type
*
* @author Jiaju Zhuang
**/
public enum ExtraReadEnum {
public enum CellExtraTypeEnum {
/**
* Read the comment
* Comment
*/
COMMENT,;
COMMENT,
/**
* Hyperlink
*/
HYPERLINK,
/**
* Merge
*/
MERGE,;
}
......@@ -10,10 +10,6 @@ public enum RowTypeEnum {
* data
*/
DATA,
/**
* extra
*/
EXTRA,
/**
* empty
*/
......
package com.alibaba.excel.event;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.listener.ReadListener;
/**
......@@ -20,6 +21,17 @@ public abstract class AbstractIgnoreExceptionReadListener<T> implements ReadList
@Override
public void onException(Exception exception, AnalysisContext context) {}
/**
* The current method is called when extra information is returned
*
* @param extra
* extra information
* @param context
* analysis context
*/
@Override
public void extra(CellExtra extra, AnalysisContext context) {}
@Override
public boolean hasNext(AnalysisContext context) {
return true;
......
......@@ -4,6 +4,7 @@ import java.util.Map;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.CellExtra;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ConverterUtils;
......@@ -27,6 +28,17 @@ public abstract class AnalysisEventListener<T> implements ReadListener<T> {
*/
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {}
/**
* The current method is called when extra information is returned
*
* @param extra
* extra information
* @param context
* analysis context
*/
@Override
public void extra(CellExtra extra, AnalysisContext context) {}
/**
* All listeners receive this method when any one Listener does an error report. If an exception is thrown here, the
* entire read will terminate.
......
package com.alibaba.excel.metadata;
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;
}
}
......@@ -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<Exce
return this;
}
/**
* Read some extra information, not by default
*
* @param extraType
* extra information type
* @return
*/
public ExcelReaderBuilder extraRead(CellExtraTypeEnum extraType) {
if (readWorkbook.getExtraReadSet() == null) {
readWorkbook.setExtraReadSet(new HashSet<CellExtraTypeEnum>());
}
readWorkbook.getExtraReadSet().add(extraType);
return this;
}
/**
* Whether to use the default listener, which is used by default.
* <p>
......@@ -175,11 +193,24 @@ public class ExcelReaderBuilder extends AbstractExcelReaderParameterBuilder<Exce
return new ExcelReader(readWorkbook);
}
public ExcelReader doReadAll() {
public void doReadAll() {
ExcelReader excelReader = build();
excelReader.readAll();
excelReader.finish();
}
/**
* Synchronous reads return results
*
* @return
*/
public <T> List<T> doReadAllSync() {
ExcelReader excelReader = build();
SyncReadListener syncReadListener = new SyncReadListener();
registerReadListener(syncReadListener);
excelReader.readAll();
excelReader.finish();
return excelReader;
return (List<T>)syncReadListener.getList();
}
public ExcelReaderSheetBuilder sheet() {
......
......@@ -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<T> 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
*
......
......@@ -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<ExtraReadEnum> extraReadSet;
private Set<CellExtraTypeEnum> extraReadSet;
/**
* The default is all excel objects.Default is true.
* <p>
......@@ -221,11 +221,11 @@ public class ReadWorkbook extends ReadBasicParameter {
this.useDefaultListener = useDefaultListener;
}
public Set<ExtraReadEnum> getExtraReadSet() {
public Set<CellExtraTypeEnum> getExtraReadSet() {
return extraReadSet;
}
public void setExtraReadSet(Set<ExtraReadEnum> extraReadSet) {
public void setExtraReadSet(Set<CellExtraTypeEnum> extraReadSet) {
this.extraReadSet = extraReadSet;
}
}
......@@ -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<Integer, Cell> cellMap) {
this.rowIndex = rowIndex;
this.rowType = rowType;
this.globalConfiguration = globalConfiguration;
this.cellMap = cellMap;
}
public GlobalConfiguration getGlobalConfiguration() {
......
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<Integer, Cell> 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<Integer, Cell>();
}
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<Integer, Cell> getCellMap() {
return cellMap;
}
public void setCellMap(Map<Integer, Cell> 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;
......
......@@ -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<ExtraReadEnum> extraReadSet;
private Set<CellExtraTypeEnum> extraReadSet;
/**
* Actual sheet data
*/
......@@ -101,7 +96,7 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
/**
* Parameter sheet data
*/
private List<ReadSheet> parametersheetDataList;
private List<ReadSheet> 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<ExtraReadEnum>();
this.extraReadSet = new HashSet<CellExtraTypeEnum>();
} else {
this.extraReadSet = readWorkbook.getExtraReadSet();
}
......@@ -309,11 +299,11 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
this.password = password;
}
public Set<ExtraReadEnum> getExtraReadSet() {
public Set<CellExtraTypeEnum> getExtraReadSet() {
return extraReadSet;
}
public void setExtraReadSet(Set<ExtraReadEnum> extraReadSet) {
public void setExtraReadSet(Set<CellExtraTypeEnum> extraReadSet) {
this.extraReadSet = extraReadSet;
}
......@@ -325,12 +315,12 @@ public class ReadWorkbookHolder extends AbstractReadHolder {
this.actualSheetDataList = actualSheetDataList;
}
public List<ReadSheet> getParametersheetDataList() {
return parametersheetDataList;
public List<ReadSheet> getParameterSheetDataList() {
return parameterSheetDataList;
}
public void setParametersheetDataList(List<ReadSheet> parametersheetDataList) {
this.parametersheetDataList = parametersheetDataList;
public void setParameterSheetDataList(List<ReadSheet> parameterSheetDataList) {
this.parameterSheetDataList = parameterSheetDataList;
}
public Boolean getReadAll() {
......
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 <code>ReadRowHolder</code>.
*/
private RowTypeEnum tempRowType;
/**
* Data storage of the current row.
*/
private Map<Integer, Cell> 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<Integer, Cell>();
ignoreRecord = Boolean.FALSE;
tempRowType = RowTypeEnum.EMPTY;
objectCacheMap = new HashMap<Integer, String>(16);
......@@ -62,22 +46,6 @@ public class XlsReadSheetHolder extends ReadSheetHolder {
this.tempRowType = tempRowType;
}
public Map<Integer, Cell> getCellMap() {
return cellMap;
}
public void setCellMap(Map<Integer, Cell> 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;
}
......
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<BoundSheetRecord>();
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<BoundSheetRecord> getBoundSheetRecordList() {
......
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<String> 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<String>();
}
public Deque<String> getTagDeque() {
return tagDeque;
}
public void setTagDeque(Deque<String> 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;
}
}
......@@ -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() {
......
......@@ -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
*
......
......@@ -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<Integer, CellData> cellDataMap = (Map) readRowHolder.getCellMap();
Map<Integer, CellData> 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)) {
......
......@@ -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();
}
......
package com.alibaba.easyexcel.test.core.extra;
import lombok.Data;
/**
* @author Jiaju Zhuang
*/
@Data
public class ExtraData {
private String row1;
private String row2;
}
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<ExtraData> {
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:
}
}
}
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();
}
}
......@@ -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:
......
......@@ -25,7 +25,7 @@ public class CommentTest {
@Test
public void comment() throws Exception {
File file = new File("D:\\test\\comment.xls");
List<Map<Integer, CellData>> datas = EasyExcel.read(file).sheet(0).doReadSync();
List<Map<Integer, CellData>> datas = EasyExcel.read(file).doReadAllSync();
for (Map<Integer, CellData> data : datas) {
LOGGER.info("数据:{}", JSON.toJSONString(data.get(0)));
}
......
# 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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册