/** * If this formula was on an imported sheet, check that * cell references to another sheet are warned appropriately * * @return TRUE if this formula was able to be imported, FALSE otherwise */ public bool handleImportedCellReferences(ExternalSheet es, WorkbookMethods mt, WorkbookSettings ws) { try { if (parser == null) { byte[] formulaData = formula.getFormulaData(); byte[] formulaBytes = new byte[formulaData.Length - 16]; System.Array.Copy(formulaData, 16, formulaBytes, 0, formulaBytes.Length); parser = new FormulaParser(formulaBytes, this, es, mt, ws); parser.parse(); } return(parser.handleImportedCellReferences()); } catch (FormulaException e) { //logger.warn("cannot import formula: " + e.Message); return(false); } }
/** * Called by the cell value when the cell features are added to the sheet */ public void setCell(int col, int row, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws) { // If this is part of an extended cells validation, then do nothing // as this will already have been called and parsed when the top left // cell was added if (hasExtendedCellsValidation) { return; } row1 = row; row2 = row; column1 = col; column2 = col; formula1 = new FormulaParser(formula1String, es, nt, ws, ParseContext.DATA_VALIDATION); formula1.parse(); if (formula2String != null) { formula2 = new FormulaParser(formula2String, es, nt, ws, ParseContext.DATA_VALIDATION); formula2.parse(); } }
/** * This formula was copied from a formula already present in the writable * workbook. Requires special handling to sort out the cell references * * @param ws the workbook settings * @param es the external sheet * @param nt the name table */ private void initializeCopiedFormula(WorkbookSettings ws, ExternalSheet es, WorkbookMethods nt) { try { parser = new FormulaParser(formulaBytes, this, es, nt, ws); parser.parse(); parser.adjustRelativeCellReferences (getColumn() - copiedFrom.getColumn(), getRow() - copiedFrom.getRow()); formulaString = parser.getFormula(); formulaBytes = parser.getBytes(); } catch (FormulaException e) { try { // try again, with an error formula formulaToParse = "ERROR(1)"; parser = new FormulaParser(formulaToParse, es, nt, ws); parser.parse(); formulaString = parser.getFormula(); formulaBytes = parser.getBytes(); } catch (FormulaException e2) { // fail silently //logger.error(string.Empty, e2); } } }
/// <summary> Constructor</summary> /// <param name="">f /// </param> /// <param name="">ws /// </param> public StringFormulaParser(string f, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws) { formula = f; settings = ws; externalSheet = es; nameTable = nt; }
/** * Constructor which creates the parse tree out of the string * * @param form the formula string * @param es the external sheet handle * @param nt the name table * @param ws the workbook settings * @param pc the context of the parse */ public FormulaParser(string form, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws, ParseContext pc) { parser = new StringFormulaParser(form, es, nt, ws, pc); }
/** * Constructs this object from the raw data * * @param t the basic number formula record * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param nf flag indicating whether the 1904 date system is in use * @param si the sheet */ public DateFormulaRecord(NumberFormulaRecord t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, bool nf, SheetImpl si) : base(t, t.getXFIndex(), fr, nf, si) { externalSheet = es; nameTable = nt; data = t.getFormulaData(); }
/// <summary> Constructs this object from the raw data /// /// </summary> /// <param name="t">the raw data /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="es">the external sheet /// </param> /// <param name="nt">the name table /// </param> /// <param name="si">the sheet /// </param> public ErrorFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, si) { externalSheet = es; nameTable = nt; data = getRecord().Data; Assert.verify(data[6] == 2); errorCode = data[8]; }
/// <summary> Constructor which creates the parse tree out of tokens /// /// </summary> /// <param name="tokens">the list of parsed tokens /// </param> /// <param name="rt">the cell containing the formula /// </param> /// <param name="es">a handle to the external sheet /// </param> /// <param name="nt">a handle to the name table /// </param> /// <param name="ws">the workbook settings /// </param> /// <exception cref=""> FormulaException /// </exception> public FormulaParser(sbyte[] tokens, Cell rt, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws) { // A null workbook bof means that it is a writable workbook and therefore // must be biff8 if (es.WorkbookBof != null && !es.WorkbookBof.isBiff8()) { throw new FormulaException(FormulaException.biff8Supported); } parser = new TokenFormulaParser(tokens, rt, es, nt, ws); }
/// <summary> Constructor</summary> /// <param name="w">the workbook /// </param> /// <param name="es">the external sheet /// </param> /// <param name="s1">the sheet of the top left cell of the range /// </param> /// <param name="c1">the column number of the top left cell of the range /// </param> /// <param name="r1">the row number of the top left cell of the range /// </param> /// <param name="s2">the sheet of the bottom right cell /// </param> /// <param name="c2">the column number of the bottom right cell of the range /// </param> /// <param name="r2">the row number of the bottomr right cell of the range /// </param> public RangeImpl(WorkbookMethods w, int s1, int c1, int r1, int s2, int c2, int r2) { workbook = w; sheet1 = s1; sheet2 = s2; row1 = r1; row2 = r2; column1 = c1; column2 = c2; }
/// <summary> Constructor</summary> public TokenFormulaParser(sbyte[] data, Cell c, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws) { tokenData = data; pos = 0; relativeTo = c; workbook = es; nameTable = nt; tokenStack = new Stack(); settings = ws; }
/** * Constructs this number * * @param t the data * @param excelFile the excel biff data * @param v the errorCode * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public SharedErrorFormulaRecord(Record t, File excelFile, int ec, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, es, nt, si, excelFile.getPos()) { errorCode = ec; }
/** * Constructs this number * * @param t the data * @param excelFile the excel biff data * @param v the errorCode * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public SharedErrorFormulaRecord(Record t, File excelFile, int ec, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t,fr,es,nt,si,excelFile.getPos()) { errorCode = ec; }
/** * Constructor */ public DataValiditySettingsRecord(Record t, ExternalSheet es, WorkbookMethods wm, WorkbookSettings ws) : base(t) { data = t.getData(); externalSheet = es; workbook = wm; workbookSettings = ws; }
/** * Constructs this number * * @param t the data * @param excelFile the excel biff data * @param v the value * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public SharedBooleanFormulaRecord(Record t, File excelFile, bool v, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, es, nt, si, excelFile.getPos()) { value = v; }
/** * Constructs this string formula * * @param t the record * @param excelFile the excel file * @param fr the formatting record * @param es the external sheet * @param nt the workbook * @param si the sheet * @param dummy the overload indicator */ public SharedStringFormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, EmptyString dummy) : base(t, fr, es, nt, si, excelFile.getPos()) { value = string.Empty; }
/** * Constructs this number * * @param t the data * @param excelFile the excel biff data * @param v the value * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public SharedBooleanFormulaRecord(Record t, File excelFile, bool v, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t,fr,es,nt,si,excelFile.getPos()) { value = v; }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public ErrorFormulaRecord(Record t,FormattingRecords fr,ExternalSheet es, WorkbookMethods nt,SheetImpl si) : base(t,fr,si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); Assert.verify(data[6] == 2); errorCode = data[8]; }
/** * Constructs this number * * @param t the record * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet * @param pos the position of the next record in the file */ public BaseSharedFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, int pos) : base(t, fr, si) { externalSheet = es; nameTable = nt; filePos = pos; }
/** * Constructor used to create writable data validations */ public DataValidation(uint objId, ExternalSheet es, WorkbookMethods wm, WorkbookSettings ws) { workbook = wm; externalSheet = es; workbookSettings = ws; validitySettings = new ArrayList(); comboBoxObjectId = objId; copied = false; }
/// <summary> Constructs this object from the raw data /// /// </summary> /// <param name="t">the raw data /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="si">the sheet /// </param> /// <param name="es">the sheet /// </param> /// <param name="nt">the name table /// </param> public BooleanFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, si) { externalSheet = es; nameTable = nt; _Value = false; data = getRecord().Data; Assert.verify(data[6] != 2); _Value = data[8] == 1?true:false; }
/** * Constructs this number * * @param t the data * @param excelFile the excel biff data * @param v the value * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public SharedNumberFormulaRecord(Record t, File excelFile, double v, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t,fr,es,nt,si,excelFile.getPos()) { value = v; format = defaultFormat; // format is set up later from the // SharedFormulaRecord }
/** * Constructs this number * * @param t the data * @param excelFile the excel biff data * @param v the value * @param fr the formatting records * @param es the external sheet * @param nt the name table * @param si the sheet */ public SharedNumberFormulaRecord(Record t, File excelFile, double v, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, es, nt, si, excelFile.getPos()) { value = v; format = defaultFormat; // format is set up later from the // SharedFormulaRecord }
/** * Constructor when parsing a string via the api * * @param nm the name string * @param nt the name table */ public NameRange(string nm,WorkbookMethods nt) { name = nm; nameTable = nt; int? nameIndex = nameTable.getNameIndex(name); if (nameIndex == null || (int)nameIndex < 0) throw new FormulaException(FormulaException.CELL_NAME_NOT_FOUND,name); index = (int)nameIndex; index += 1; // indexes are 1-based }
/** * Constructs this object from the raw data. Used when reading in formula * strings which evaluate to null (in the case of some IF statements) * * @param t the raw data * @param fr the formatting records * @param es the external sheet records * @param nt the workbook * @param si the sheet impl * @param ws the workbook settings */ public StringFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); value = string.Empty; }
/// <summary> Constructor when parsing a string via the api /// /// </summary> /// <param name="nm">the name string /// </param> /// <param name="nt">the name table /// </param> public NameRange(string nm, WorkbookMethods nt) { name = nm; nameTable = nt; index = nameTable.getNameIndex(name); if (index < 0) { throw new FormulaException(FormulaException.cellNameNotFound, name); } index += 1; // indexes are 1-based }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param si the sheet * @param es the sheet * @param nt the name table */ public BooleanFormulaRecord(Record t,FormattingRecords fr, ExternalSheet es,WorkbookMethods nt, SheetImpl si) : base(t,fr,si) { externalSheet = es; nameTable = nt; value = false; data = getRecord().getData(); Assert.verify(data[6] != 2); value = data[8] == 1 ? true : false; }
/** * Constructor when parsing a string via the api * * @param nm the name string * @param nt the name table */ public NameRange(string nm, WorkbookMethods nt) { name = nm; nameTable = nt; int?nameIndex = nameTable.getNameIndex(name); if (nameIndex == null || (int)nameIndex < 0) { throw new FormulaException(FormulaException.CELL_NAME_NOT_FOUND, name); } index = (int)nameIndex; index += 1; // indexes are 1-based }
/** * Constructor used when copying sheets * * @param dvsr the record copied from a writable sheet */ public DataValiditySettingsRecord(DataValiditySettingsRecord dvsr, ExternalSheet es, WorkbookMethods w, WorkbookSettings ws) : base(Type.DV) { workbook = w; externalSheet = es; workbookSettings = ws; Assert.verify(w != null); Assert.verify(es != null); data = new byte[dvsr.data.Length]; System.Array.Copy(dvsr.data, 0, data, 0, data.Length); }
/** * Constructor which creates the parse tree out of tokens * * @param tokens the list of parsed tokens * @param rt the cell containing the formula * @param es a handle to the external sheet * @param nt a handle to the name table * @param ws the workbook settings * @param pc the parse context * @exception FormulaException */ public FormulaParser(byte[] tokens, Cell rt, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws) { // A null workbook bof means that it is a writable workbook and therefore // must be biff8 if (es.getWorkbookBof() != null && !es.getWorkbookBof().isBiff8()) { throw new FormulaException(FormulaException.BIFF8_SUPPORTED); } Assert.verify(nt != null); parser = new TokenFormulaParser(tokens,rt,es,nt,ws, ParseContext.DEFAULT); }
/** * Constructor which creates the parse tree out of tokens * * @param tokens the list of parsed tokens * @param rt the cell containing the formula * @param es a handle to the external sheet * @param nt a handle to the name table * @param ws the workbook settings * @param pc the parse context * @exception FormulaException */ public FormulaParser(byte[] tokens, Cell rt, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws, ParseContext pc) { // A null workbook bof means that it is a writable workbook and therefore // must be biff8 if (es.getWorkbookBof() != null && !es.getWorkbookBof().isBiff8()) { throw new FormulaException(FormulaException.BIFF8_SUPPORTED); } Assert.verify(nt != null); parser = new TokenFormulaParser(tokens, rt, es, nt, ws, pc); }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting record * @param es the external sheet * @param nt the name table * @param si the sheet */ public NumberFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); format = fr.getNumberFormat(getXFIndex()); if (format == null) { format = defaultFormat; } value = DoubleHelper.getIEEEDouble(data, 6); }
/** * Constructor */ public TokenFormulaParser(byte[] data, Cell c, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws, ParseContext pc) { tokenData = data; pos = 0; relativeTo = c; workbook = es; nameTable = nt; tokenStack = new Stack <ParseItem>(); settings = ws; parseContext = pc; Assert.verify(nameTable != null); }
/** * Copy constructor used to copy from read to write */ public DataValidation(DataValidation dv, ExternalSheet es, WorkbookMethods wm, WorkbookSettings ws) { workbook = wm; externalSheet = es; workbookSettings = ws; copied = true; validityList = new DataValidityListRecord(dv.getDataValidityList()); validitySettings = new ArrayList(); DataValiditySettingsRecord[] settings = dv.getDataValiditySettings(); for (int i = 0; i < settings.Length; i++) { validitySettings.Add(new DataValiditySettingsRecord(settings[i], externalSheet, workbook, workbookSettings)); } }
/** * Constructs this object from the raw data. We need to use the excelFile * to retrieve the string record which follows this formula record * * @param t the raw data * @param excelFile the excel file * @param fr the formatting records * @param es the external sheet records * @param nt the workbook * @param si the sheet impl * @param ws the workbook settings */ public StringFormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, WorkbookSettings ws) : base(t, fr, si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); int pos = excelFile.getPos(); // Look for the string record in one of the records after the // formula. Put a cap on it to prevent looping Record nextRecord = excelFile.next(); int count = 0; while (nextRecord.getType() != Type.STRING && count < 4) { nextRecord = excelFile.next(); count++; } Assert.verify(count < 4, " @ " + pos); byte[] stringData = nextRecord.getData(); // Read in any continuation records nextRecord = excelFile.peek(); while (nextRecord.getType() == Type.CONTINUE) { nextRecord = excelFile.next(); // move the pointer within the data byte[] d = new byte[stringData.Length + nextRecord.getLength() - 1]; System.Array.Copy(stringData, 0, d, 0, stringData.Length); System.Array.Copy(nextRecord.getData(), 1, d, stringData.Length, nextRecord.getLength() - 1); stringData = d; nextRecord = excelFile.peek(); } readString(stringData, ws); }
/// <summary> Constructs this object from the raw data /// /// </summary> /// <param name="t">the raw data /// </param> /// <param name="fr">the formatting record /// </param> /// <param name="es">the external sheet /// </param> /// <param name="nt">the name table /// </param> /// <param name="si">the sheet /// </param> public NumberFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, si) { externalSheet = es; nameTable = nt; data = getRecord().Data; format = fr.getNumberFormat(XFIndex); if (format == null) { format = defaultFormat; } int num1 = IntegerHelper.getInt(data[6], data[7], data[8], data[9]); int num2 = IntegerHelper.getInt(data[10], data[11], data[12], data[13]); // bitwise ors don't work with longs, so we have to simulate this // functionality the long way round by concatenating two binary // strings, and then parsing the binary string into a long. // This is very clunky and inefficient, and I hope to // find a better way string s1 = System.Convert.ToString(num1, 2); while (s1.Length < 32) { s1 = "0" + s1; // fill out with leading zeros as necessary } // Long.parseLong doesn't like the sign bit, so have to extract this // information and put it in at the end. (thanks // to Ruben for pointing this out) bool negative = ((((long)num2) & 0x80000000) != 0); string s = System.Convert.ToString(num2 & 0x7fffffff, 2) + s1; long val = System.Convert.ToInt64(s, 2); _Value = BitConverter.Int64BitsToDouble(val); if (negative) { _Value = -_Value; } }
/// <summary> Constructs this object from the raw data. Creates either a /// NumberFormulaRecord or a StringFormulaRecord depending on whether /// this formula represents a numerical calculation or not /// /// </summary> /// <param name="t">the raw data /// </param> /// <param name="fr">the base shared formula /// </param> /// <param name="es">the workbook, which contains the external sheet references /// </param> /// <param name="nt">the workbook /// </param> /// <param name="si">the sheet /// </param> public SharedFormulaRecord(Record t, BaseSharedFormulaRecord fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) { externalSheet = es; nameTable = nt; sheet = si; sbyte[] data = t.Data; firstRow = IntegerHelper.getInt(data[0], data[1]); lastRow = IntegerHelper.getInt(data[2], data[3]); firstCol = (int)(data[4] & 0xff); lastCol = (int)(data[5] & 0xff); formulas = new ArrayList(); templateFormula = fr; tokens = new sbyte[data.Length - 10]; Array.Copy(data, 10, tokens, 0, tokens.Length); }
/** * Constructs this object from the raw data. Creates either a * NumberFormulaRecord or a StringFormulaRecord depending on whether * this formula represents a numerical calculation or not * * @param t the raw data * @param fr the base shared formula * @param es the workbook, which contains the external sheet references * @param nt the workbook * @param si the sheet */ public SharedFormulaRecord(Record t, BaseSharedFormulaRecord fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) { sheet = si; byte[] data = t.getData(); firstRow = IntegerHelper.getInt(data[0], data[1]); lastRow = IntegerHelper.getInt(data[2], data[3]); firstCol = data[4] & 0xff; lastCol = data[5] & 0xff; formulas = new ArrayList(); templateFormula = fr; tokens = new byte[data.Length - 10]; System.Array.Copy(data, 10, tokens, 0, tokens.Length); }
/** * Called by the cell value when the cell features are added to the sheet */ public void setCell(int col, int row, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws) { // If this is part of an extended cells validation, then do nothing // as this will already have been called and parsed when the top left // cell was added if (hasExtendedCellsValidation) { return; } row1 = row; row2 = row; column1 = col; column2 = col; formula1 = new FormulaParser(formula1String, es,nt,ws, ParseContext.DATA_VALIDATION); formula1.parse(); if (formula2String != null) { formula2 = new FormulaParser(formula2String, es,nt,ws, ParseContext.DATA_VALIDATION); formula2.parse(); } }
/** * Constructs this object from the raw data. Creates either a * NumberFormulaRecord or a StringFormulaRecord depending on whether * this formula represents a numerical calculation or not * * @param t the raw data * @param fr the base shared formula * @param es the workbook, which contains the external sheet references * @param nt the workbook * @param si the sheet */ public SharedFormulaRecord(Record t,BaseSharedFormulaRecord fr, ExternalSheet es,WorkbookMethods nt, SheetImpl si) { sheet = si; byte[] data = t.getData(); firstRow = IntegerHelper.getInt(data[0],data[1]); lastRow = IntegerHelper.getInt(data[2],data[3]); firstCol = data[4] & 0xff; lastCol = data[5] & 0xff; formulas = new ArrayList(); templateFormula = fr; tokens = new byte[data.Length - 10]; System.Array.Copy(data,10,tokens,0,tokens.Length); }
/** * Constructor */ public TokenFormulaParser(byte[] data, Cell c, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws, ParseContext pc) { tokenData = data; pos = 0; relativeTo = c; workbook = es; nameTable = nt; tokenStack = new Stack<ParseItem>(); settings = ws; parseContext = pc; Assert.verify(nameTable != null); }
/** * If this formula was on an imported sheet, check that * cell references to another sheet are warned appropriately * * @return TRUE if this formula was able to be imported, FALSE otherwise */ public bool handleImportedCellReferences(ExternalSheet es, WorkbookMethods mt, WorkbookSettings ws) { try { if (parser == null) { byte[] formulaData = formula.getFormulaData(); byte[] formulaBytes = new byte[formulaData.Length - 16]; System.Array.Copy(formulaData, 16, formulaBytes, 0, formulaBytes.Length); parser = new FormulaParser(formulaBytes, this, es, mt, ws); parser.parse(); } return parser.handleImportedCellReferences(); } catch (FormulaException e) { //logger.warn("cannot import formula: " + e.Message); return false; } }
/** * Constructor * @param f * @param ws */ public StringFormulaParser(string f,ExternalSheet es,WorkbookMethods nt,WorkbookSettings ws,ParseContext pc) { formula = f; settings = ws; externalSheet = es; nameTable = nt; parseContext = pc; }
/** * Copy constructor used to copy from read to write */ public DataValidation(DataValidation dv, ExternalSheet es, WorkbookMethods wm, WorkbookSettings ws) { workbook = wm; externalSheet = es; workbookSettings = ws; copied = true; validityList = new DataValidityListRecord(dv.getDataValidityList()); validitySettings = new ArrayList(); DataValiditySettingsRecord[] settings = dv.getDataValiditySettings(); for (int i = 0; i < settings.Length; i++) validitySettings.Add(new DataValiditySettingsRecord(settings[i],externalSheet,workbook,workbookSettings)); }
/** * Constructor used when copying sheets * * @param dvsr the record copied from a writable sheet */ public DataValiditySettingsRecord(DataValiditySettingsRecord dvsr, ExternalSheet es, WorkbookMethods w, WorkbookSettings ws) : base(Type.DV) { workbook = w; externalSheet = es; workbookSettings = ws; Assert.verify(w != null); Assert.verify(es != null); data = new byte[dvsr.data.Length]; System.Array.Copy(dvsr.data,0,data,0,data.Length); }
/** * Constructs this object from the raw data. Creates either a * NumberFormulaRecord or a StringFormulaRecord depending on whether * this formula represents a numerical calculation or not * * @param t the raw data * @param excelFile the excel file * @param fr the formatting records * @param es the workbook, which contains the external sheet references * @param nt the name table * @param si the sheet * @param ws the workbook settings */ public FormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, WorkbookSettings ws) : base(t,fr,si) { byte[] data = getRecord().getData(); shared = false; // Check to see if this forms part of a shared formula int grbit = IntegerHelper.getInt(data[14],data[15]); if ((grbit & 0x08) != 0) { shared = true; if (data[6] == 0 && data[12] == 0xff && data[13] == 0xff) { // It is a shared string formula formula = new SharedStringFormulaRecord(t,excelFile,fr,es,nt,si,ws); } else if (data[6] == 3 && data[12] == 0xff && data[13] == 0xff) { // We have a string which evaluates to null formula = new SharedStringFormulaRecord(t,excelFile,fr,es,nt,si,SharedStringFormulaRecord.EMPTY_STRING); } else if (data[6] == 2 && data[12] == 0xff && data[13] == 0xff) { // The cell is in error int errorCode = data[8]; formula = new SharedErrorFormulaRecord(t,excelFile,errorCode, fr,es,nt,si); } else if (data[6] == 1 && data[12] == 0xff && data[13] == 0xff) { bool value = data[8] == 1 ? true : false; formula = new SharedBooleanFormulaRecord (t,excelFile,value,fr,es,nt,si); } else { // It is a numerical formula double value = DoubleHelper.getIEEEDouble(data,6); SharedNumberFormulaRecord snfr = new SharedNumberFormulaRecord (t,excelFile,value,fr,es,nt,si); snfr.setNumberFormat(fr.getNumberFormat(getXFIndex())); formula = snfr; } return; } // microsoft and their goddam magic values determine whether this // is a string or a number value if (data[6] == 0 && data[12] == 0xff && data[13] == 0xff) { // we have a string formula = new StringFormulaRecord(t,excelFile,fr,es,nt,si,ws); } else if (data[6] == 1 && data[12] == 0xff && data[13] == 0xff) { // We have a bool formula // multiple values. Thanks to Frank for spotting this formula = new BooleanFormulaRecord(t,fr,es,nt,si); } else if (data[6] == 2 && data[12] == 0xff && data[13] == 0xff) { // The cell is in error formula = new ErrorFormulaRecord(t,fr,es,nt,si); } else if (data[6] == 3 && data[12] == 0xff && data[13] == 0xff) { // we have a string which evaluates to null formula = new StringFormulaRecord(t,fr,es,nt,si); } else { // it is most assuredly a number formula = new NumberFormulaRecord(t,fr,es,nt,si); } }
/** * Constructor */ public DVParser(byte[] data, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws) { Assert.verify(nt != null); wasCopied = false; int options = IntegerHelper.getInt(data[0],data[1],data[2],data[3]); int typeVal = options & 0xf; type = DVType.getType(typeVal); int errorStyleVal = (options & 0x70) >> 4; errorStyle = ErrorStyle.getErrorStyle(errorStyleVal); int conditionVal = (options & 0xf00000) >> 20; condition = Condition.getCondition(conditionVal); stringListGiven = (options & STRING_LIST_GIVEN_MASK) != 0; emptyCellsAllowed = (options & EMPTY_CELLS_ALLOWED_MASK) != 0; suppressArrow = (options & SUPPRESS_ARROW_MASK) != 0; showPrompt = (options & SHOW_PROMPT_MASK) != 0; showError = (options & SHOW_ERROR_MASK) != 0; int pos = 4; int length = IntegerHelper.getInt(data[pos],data[pos + 1]); if (length > 0 && data[pos + 2] == 0) { promptTitle = StringHelper.getString(data,length,pos + 3,ws); pos += length + 3; } else if (length > 0) { promptTitle = StringHelper.getUnicodeString(data,length,pos + 3); pos += length * 2 + 3; } else { pos += 3; } length = IntegerHelper.getInt(data[pos],data[pos + 1]); if (length > 0 && data[pos + 2] == 0) { errorTitle = StringHelper.getString(data,length,pos + 3,ws); pos += length + 3; } else if (length > 0) { errorTitle = StringHelper.getUnicodeString(data,length,pos + 3); pos += length * 2 + 3; } else { pos += 3; } length = IntegerHelper.getInt(data[pos],data[pos + 1]); if (length > 0 && data[pos + 2] == 0) { promptText = StringHelper.getString(data,length,pos + 3,ws); pos += length + 3; } else if (length > 0) { promptText = StringHelper.getUnicodeString(data,length,pos + 3); pos += length * 2 + 3; } else { pos += 3; } length = IntegerHelper.getInt(data[pos],data[pos + 1]); if (length > 0 && data[pos + 2] == 0) { errorText = StringHelper.getString(data,length,pos + 3,ws); pos += length + 3; } else if (length > 0) { errorText = StringHelper.getUnicodeString(data,length,pos + 3); pos += length * 2 + 3; } else { pos += 3; } int formula1Length = IntegerHelper.getInt(data[pos],data[pos + 1]); pos += 4; int formula1Pos = pos; pos += formula1Length; int formula2Length = IntegerHelper.getInt(data[pos],data[pos + 1]); pos += 4; int formula2Pos = pos; pos += formula2Length; pos += 2; row1 = IntegerHelper.getInt(data[pos],data[pos + 1]); pos += 2; row2 = IntegerHelper.getInt(data[pos],data[pos + 1]); pos += 2; column1 = IntegerHelper.getInt(data[pos],data[pos + 1]); pos += 2; column2 = IntegerHelper.getInt(data[pos],data[pos + 1]); pos += 2; hasExtendedCellsValidation = (row1 == row2 && column1 == column2) ? false : true; // Do the formulas try { // First, create a temporary blank cell for any formula relative // references EmptyCell tmprt = new EmptyCell(column1,row1); if (formula1Length != 0) { byte[] tokens = new byte[formula1Length]; System.Array.Copy(data,formula1Pos,tokens,0,formula1Length); formula1 = new FormulaParser(tokens,tmprt,es,nt,ws, ParseContext.DATA_VALIDATION); formula1.parse(); } if (formula2Length != 0) { byte[] tokens = new byte[formula2Length]; System.Array.Copy(data,formula2Pos,tokens,0,formula2Length); formula2 = new FormulaParser(tokens,tmprt,es,nt,ws, ParseContext.DATA_VALIDATION); formula2.parse(); } } catch (FormulaException e) { //logger.warn(e.Message + " for cells " + // CellReferenceHelper.getCellReference(column1,row1) + "-" + // CellReferenceHelper.getCellReference(column2,row2)); } }
/** * Constructs this object from the raw data. We need to use the excelFile * to retrieve the string record which follows this formula record * * @param t the raw data * @param excelFile the excel file * @param fr the formatting records * @param es the external sheet records * @param nt the workbook * @param si the sheet impl * @param ws the workbook settings */ public StringFormulaRecord(Record t,File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, WorkbookSettings ws) : base(t,fr,si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); int pos = excelFile.getPos(); // Look for the string record in one of the records after the // formula. Put a cap on it to prevent looping Record nextRecord = excelFile.next(); int count = 0; while (nextRecord.getType() != Type.STRING && count < 4) { nextRecord = excelFile.next(); count++; } Assert.verify(count < 4," @ " + pos); byte[] stringData = nextRecord.getData(); // Read in any continuation records nextRecord = excelFile.peek(); while (nextRecord.getType() == Type.CONTINUE) { nextRecord = excelFile.next(); // move the pointer within the data byte[] d = new byte[stringData.Length + nextRecord.getLength() - 1]; System.Array.Copy(stringData,0,d,0,stringData.Length); System.Array.Copy(nextRecord.getData(),1,d, stringData.Length,nextRecord.getLength() - 1); stringData = d; nextRecord = excelFile.peek(); } readString(stringData,ws); }
/** * Constructs this object from the raw data. Used when reading in formula * strings which evaluate to null (in the case of some IF statements) * * @param t the raw data * @param fr the formatting records * @param es the external sheet records * @param nt the workbook * @param si the sheet impl * @param ws the workbook settings */ public StringFormulaRecord(Record t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t,fr,si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); value = string.Empty; }
/** * Constructs this object from the raw data. Creates either a * NumberFormulaRecord or a StringFormulaRecord depending on whether * this formula represents a numerical calculation or not * * @param t the raw data * @param excelFile the excel file * @param fr the formatting records * @param es the workbook, which contains the external sheet references * @param nt the name table * @param i a dummy override to indicate that we don't want to do * any shared formula processing * @param si the sheet impl * @param ws the workbook settings */ public FormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, IgnoreSharedFormula i, SheetImpl si, WorkbookSettings ws) : base(t,fr,si) { byte[] data = getRecord().getData(); shared = false; // microsoft and their magic values determine whether this // is a string or a number value if (data[6] == 0 && data[12] == 0xff && data[13] == 0xff) { // we have a string formula = new StringFormulaRecord(t,excelFile,fr,es,nt,si,ws); } else if (data[6] == 1 && data[12] == 0xff && data[13] == 0xff) { // We have a bool formula // multiple values. Thanks to Frank for spotting this formula = new BooleanFormulaRecord(t,fr,es,nt,si); } else if (data[6] == 2 && data[12] == 0xff && data[13] == 0xff) { // The cell is in error formula = new ErrorFormulaRecord(t,fr,es,nt,si); } else { // it is most assuredly a number formula = new NumberFormulaRecord(t,fr,es,nt,si); } }
/** * Constructs this string formula * * @param t the record * @param excelFile the excel file * @param fr the formatting record * @param es the external sheet * @param nt the workbook * @param si the sheet * @param dummy the overload indicator */ public SharedStringFormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, EmptyString dummy) : base(t,fr,es,nt,si,excelFile.getPos()) { value = string.Empty; }
/** * Constructs this string formula * * @param t the record * @param excelFile the excel file * @param fr the formatting record * @param es the external sheet * @param nt the workbook * @param si the sheet * @param ws the workbook settings */ public SharedStringFormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, WorkbookSettings ws) : base(t,fr,es,nt,si,excelFile.getPos()) { int pos = excelFile.getPos(); // Save the position in the excel file int filepos = excelFile.getPos(); // Look for the string record in one of the records after the // formula. Put a cap on it to prevent ednas Record nextRecord = excelFile.next(); int count = 0; while (nextRecord.getType() != Type.STRING && count < 4) { nextRecord = excelFile.next(); count++; } Assert.verify(count < 4," @ " + pos); byte[] stringData = nextRecord.getData(); // Read in any continuation records nextRecord = excelFile.peek(); while (nextRecord.getType() == Type.CONTINUE) { nextRecord = excelFile.next(); // move the pointer within the data byte[] d = new byte[stringData.Length + nextRecord.getLength() - 1]; System.Array.Copy(stringData,0,d,0,stringData.Length); System.Array.Copy(nextRecord.getData(),1,d, stringData.Length,nextRecord.getLength() - 1); stringData = d; nextRecord = excelFile.peek(); } int chars = IntegerHelper.getInt(stringData[0],stringData[1]); bool unicode = false; int startpos = 3; if (stringData.Length == chars + 2) { // string might only consist of a one byte length indicator, instead // of the more normal 2 startpos = 2; unicode = false; } else if (stringData[2] == 0x1) { // unicode string, two byte length indicator startpos = 3; unicode = true; } else { // ascii string, two byte length indicator startpos = 3; unicode = false; } if (!unicode) { value = StringHelper.getString(stringData,chars,startpos,ws); } else { value = StringHelper.getUnicodeString(stringData,chars,startpos); } // Restore the position in the excel file, to enable the SHRFMLA // record to be picked up excelFile.setPos(filepos); }
public void setNameTable(WorkbookMethods nt) { nameTable = nt; }
/** * Constructor * @param w the workbook * @param es the external sheet * @param s1 the sheet of the top left cell of the range * @param c1 the column number of the top left cell of the range * @param r1 the row number of the top left cell of the range * @param s2 the sheet of the bottom right cell * @param c2 the column number of the bottom right cell of the range * @param r2 the row number of the bottomr right cell of the range */ public RangeImpl(WorkbookMethods w, int s1,int c1,int r1, int s2,int c2,int r2) { workbook = w; sheet1 = s1; sheet2 = s2; row1 = r1; row2 = r2; column1 = c1; column2 = c2; }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting record * @param es the external sheet * @param nt the name table * @param si the sheet */ public NumberFormulaRecord(Record t,FormattingRecords fr, ExternalSheet es,WorkbookMethods nt, SheetImpl si) : base(t,fr,si) { externalSheet = es; nameTable = nt; data = getRecord().getData(); format = fr.getNumberFormat(getXFIndex()); if (format == null) { format = defaultFormat; } value = DoubleHelper.getIEEEDouble(data,6); }
/** * Constructor */ public NameRange(WorkbookMethods nt) { nameTable = nt; Assert.verify(nameTable != null); }
/** * Constructor which creates the parse tree out of the string * * @param form the formula string * @param es the external sheet handle * @param nt the name table * @param ws the workbook settings * @param pc the context of the parse */ public FormulaParser(string form, ExternalSheet es, WorkbookMethods nt, WorkbookSettings ws, ParseContext pc) { parser = new StringFormulaParser(form,es,nt,ws,pc); }