169 lines
5.5 KiB
Java
169 lines
5.5 KiB
Java
package jxl.write.biff;
|
|
|
|
import common.Assert;
|
|
import common.Logger;
|
|
import jxl.Cell;
|
|
import jxl.CellReferenceHelper;
|
|
import jxl.CellType;
|
|
import jxl.Sheet;
|
|
import jxl.WorkbookSettings;
|
|
import jxl.biff.FormattingRecords;
|
|
import jxl.biff.FormulaData;
|
|
import jxl.biff.IntegerHelper;
|
|
import jxl.biff.Type;
|
|
import jxl.biff.WorkbookMethods;
|
|
import jxl.biff.formula.ExternalSheet;
|
|
import jxl.biff.formula.FormulaException;
|
|
import jxl.biff.formula.FormulaParser;
|
|
import jxl.format.CellFormat;
|
|
import jxl.write.WritableCell;
|
|
|
|
public class FormulaRecord extends CellValue implements FormulaData {
|
|
private static Logger logger = Logger.getLogger(FormulaRecord.class);
|
|
|
|
private String formulaToParse;
|
|
|
|
private FormulaParser parser;
|
|
|
|
private String formulaString;
|
|
|
|
private byte[] formulaBytes;
|
|
|
|
private CellValue copiedFrom;
|
|
|
|
public FormulaRecord(int c, int r, String f) {
|
|
super(Type.FORMULA2, c, r);
|
|
this.formulaToParse = f;
|
|
this.copiedFrom = null;
|
|
}
|
|
|
|
public FormulaRecord(int c, int r, String f, CellFormat st) {
|
|
super(Type.FORMULA, c, r, st);
|
|
this.formulaToParse = f;
|
|
this.copiedFrom = null;
|
|
}
|
|
|
|
protected FormulaRecord(int c, int r, FormulaRecord fr) {
|
|
super(Type.FORMULA, c, r, fr);
|
|
this.copiedFrom = fr;
|
|
this.formulaBytes = new byte[fr.formulaBytes.length];
|
|
System.arraycopy(fr.formulaBytes, 0, this.formulaBytes, 0, this.formulaBytes.length);
|
|
}
|
|
|
|
protected FormulaRecord(int c, int r, ReadFormulaRecord rfr) {
|
|
super(Type.FORMULA, c, r, rfr);
|
|
try {
|
|
this.copiedFrom = rfr;
|
|
byte[] readFormulaData = rfr.getFormulaData();
|
|
this.formulaBytes = new byte[readFormulaData.length - 16];
|
|
System.arraycopy(readFormulaData, 16, this.formulaBytes, 0, this.formulaBytes.length);
|
|
} catch (FormulaException e) {
|
|
logger.error("", (Throwable)e);
|
|
}
|
|
}
|
|
|
|
private void initialize(WorkbookSettings ws, ExternalSheet es, WorkbookMethods nt) {
|
|
if (this.copiedFrom != null) {
|
|
initializeCopiedFormula(ws, es, nt);
|
|
return;
|
|
}
|
|
this.parser = new FormulaParser(this.formulaToParse, es, nt, ws);
|
|
try {
|
|
this.parser.parse();
|
|
this.formulaString = this.parser.getFormula();
|
|
this.formulaBytes = this.parser.getBytes();
|
|
} catch (FormulaException e) {
|
|
logger.warn(e.getMessage() + " when parsing formula " + this.formulaToParse + " in cell " + getSheet().getName() + "!" + CellReferenceHelper.getCellReference(getColumn(), getRow()));
|
|
try {
|
|
this.formulaToParse = "ERROR(1)";
|
|
this.parser = new FormulaParser(this.formulaToParse, es, nt, ws);
|
|
this.parser.parse();
|
|
this.formulaString = this.parser.getFormula();
|
|
this.formulaBytes = this.parser.getBytes();
|
|
} catch (FormulaException e2) {
|
|
logger.error("", (Throwable)e2);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void initializeCopiedFormula(WorkbookSettings ws, ExternalSheet es, WorkbookMethods nt) {
|
|
try {
|
|
this.parser = new FormulaParser(this.formulaBytes, (Cell)this, es, nt, ws);
|
|
this.parser.parse();
|
|
this.parser.adjustRelativeCellReferences(getColumn() - this.copiedFrom.getColumn(), getRow() - this.copiedFrom.getRow());
|
|
this.formulaString = this.parser.getFormula();
|
|
this.formulaBytes = this.parser.getBytes();
|
|
} catch (FormulaException e) {
|
|
try {
|
|
this.formulaToParse = "ERROR(1)";
|
|
this.parser = new FormulaParser(this.formulaToParse, es, nt, ws);
|
|
this.parser.parse();
|
|
this.formulaString = this.parser.getFormula();
|
|
this.formulaBytes = this.parser.getBytes();
|
|
} catch (FormulaException e2) {
|
|
logger.error("", (Throwable)e2);
|
|
}
|
|
}
|
|
}
|
|
|
|
void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) {
|
|
super.setCellDetails(fr, ss, s);
|
|
initialize(s.getWorkbookSettings(), s.getWorkbook(), s.getWorkbook());
|
|
s.getWorkbook().addRCIRCell(this);
|
|
}
|
|
|
|
public byte[] getData() {
|
|
byte[] celldata = super.getData();
|
|
byte[] formulaData = getFormulaData();
|
|
byte[] data = new byte[formulaData.length + celldata.length];
|
|
System.arraycopy(celldata, 0, data, 0, celldata.length);
|
|
System.arraycopy(formulaData, 0, data, celldata.length, formulaData.length);
|
|
return data;
|
|
}
|
|
|
|
public CellType getType() {
|
|
return CellType.ERROR;
|
|
}
|
|
|
|
public String getContents() {
|
|
return this.formulaString;
|
|
}
|
|
|
|
public byte[] getFormulaData() {
|
|
byte[] data = new byte[this.formulaBytes.length + 16];
|
|
System.arraycopy(this.formulaBytes, 0, data, 16, this.formulaBytes.length);
|
|
data[6] = 16;
|
|
data[7] = 64;
|
|
data[12] = -32;
|
|
data[13] = -4;
|
|
data[8] = (byte)(data[8] | 0x2);
|
|
IntegerHelper.getTwoBytes(this.formulaBytes.length, data, 14);
|
|
return data;
|
|
}
|
|
|
|
public WritableCell copyTo(int col, int row) {
|
|
Assert.verify(false);
|
|
return null;
|
|
}
|
|
|
|
void columnInserted(Sheet s, int sheetIndex, int col) {
|
|
this.parser.columnInserted(sheetIndex, col, (s == getSheet()));
|
|
this.formulaBytes = this.parser.getBytes();
|
|
}
|
|
|
|
void columnRemoved(Sheet s, int sheetIndex, int col) {
|
|
this.parser.columnRemoved(sheetIndex, col, (s == getSheet()));
|
|
this.formulaBytes = this.parser.getBytes();
|
|
}
|
|
|
|
void rowInserted(Sheet s, int sheetIndex, int row) {
|
|
this.parser.rowInserted(sheetIndex, row, (s == getSheet()));
|
|
this.formulaBytes = this.parser.getBytes();
|
|
}
|
|
|
|
void rowRemoved(Sheet s, int sheetIndex, int row) {
|
|
this.parser.rowRemoved(sheetIndex, row, (s == getSheet()));
|
|
this.formulaBytes = this.parser.getBytes();
|
|
}
|
|
}
|