You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
4.4 KiB

package com.alibaba.excel.analysis.v03.handlers;
import java.math.BigDecimal;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.context.XlsReadContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
/**
* Record handler
*
* @author Dan Zheng
*/
public class FormulaRecordHandler extends AbstractXlsRecordHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(FormulaRecordHandler.class);
private static final String ERROR = "#VALUE!";
private int nextRow;
private int nextColumn;
private boolean outputNextStringRecord;
private CellData tempCellData;
private FormatTrackingHSSFListener formatListener;
private HSSFWorkbook stubWorkbook;
public FormulaRecordHandler(XlsReadContext analysisContext, HSSFWorkbook stubWorkbook,
FormatTrackingHSSFListener formatListener) {
super(analysisContext);
this.stubWorkbook = stubWorkbook;
this.formatListener = formatListener;
}
@Override
public boolean support(Record record) {
return FormulaRecord.sid == record.getSid() || StringRecord.sid == record.getSid();
}
@Override
public void processRecord(Record record) {
if (record.getSid() == FormulaRecord.sid) {
FormulaRecord frec = (FormulaRecord)record;
this.row = frec.getRow();
this.column = frec.getColumn();
CellType cellType = CellType.forInt(frec.getCachedResultType());
String formulaValue = null;
try {
formulaValue = HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression());
} catch (Exception e) {
LOGGER.warn("Get formula value error.{}", e.getMessage());
}
switch (cellType) {
case STRING:
// Formula result is a string
// This is stored in the next record
outputNextStringRecord = true;
nextRow = frec.getRow();
nextColumn = frec.getColumn();
tempCellData = new CellData(CellDataTypeEnum.STRING);
tempCellData.setFormula(Boolean.TRUE);
tempCellData.setFormulaValue(formulaValue);
break;
case NUMERIC:
this.cellData = new CellData(BigDecimal.valueOf(frec.getValue()));
this.cellData.setFormula(Boolean.TRUE);
this.cellData.setFormulaValue(formulaValue);
break;
case ERROR:
this.cellData = new CellData(CellDataTypeEnum.ERROR);
this.cellData.setStringValue(ERROR);
this.cellData.setFormula(Boolean.TRUE);
this.cellData.setFormulaValue(formulaValue);
break;
case BOOLEAN:
this.cellData = new CellData(frec.getCachedBooleanValue());
this.cellData.setFormula(Boolean.TRUE);
this.cellData.setFormulaValue(formulaValue);
break;
default:
this.cellData = new CellData(CellDataTypeEnum.EMPTY);
this.cellData.setFormula(Boolean.TRUE);
this.cellData.setFormulaValue(formulaValue);
break;
}
} else if (record.getSid() == StringRecord.sid) {
if (outputNextStringRecord) {
// String for formula
StringRecord srec = (StringRecord)record;
this.cellData = tempCellData;
this.cellData.setStringValue(srec.getString());
this.row = nextRow;
this.column = nextColumn;
outputNextStringRecord = false;
tempCellData = null;
}
}
}
@Override
public void init() {
this.nextRow = 0;
this.nextColumn = 0;
}
@Override
public int getOrder() {
return 0;
}
}