/** * string formula specific exception handling. Can't really create * a formula (as it will look for a cell of that name, so just * create a STRING record containing the contents * * @return the bodged data */ public override byte[] handleFormulaException() { byte[] expressiondata = null; byte[] celldata = base.getCellData(); // Generate an appropriate dummy formula WritableWorkbookImpl w = getSheet().getWorkbook(); FormulaParser parser = new FormulaParser("\"" + getContents() + "\"", w, w, w.getSettings()); // Get the bytes for the dummy formula try { parser.parse(); } catch (FormulaException e2) { //logger.warn(e2.Message); parser = new FormulaParser("\"ERROR\"", w, w, w.getSettings()); try { parser.parse(); } catch (FormulaException e3) { Assert.verify(false); } } byte[] formulaBytes = parser.getBytes(); expressiondata = new byte[formulaBytes.Length + 16]; IntegerHelper.getTwoBytes(formulaBytes.Length, expressiondata, 14); System.Array.Copy(formulaBytes, 0, expressiondata, 16, formulaBytes.Length); // Set the recalculate on load bit expressiondata[8] |= 0x02; byte[] data = new byte[celldata.Length + expressiondata.Length]; System.Array.Copy(celldata, 0, data, 0, celldata.Length); System.Array.Copy(expressiondata, 0, data, celldata.Length, expressiondata.Length); // Set the type bits to indicate a string formula data[6] = 0; unchecked { data[12] = (byte)-1; data[13] = (byte)-1; } return data; }
/** * Called when a column is inserted on the specified sheet. Notifies all * RCIR cells of this change. The default implementation here does nothing * * @param s the sheet on which the column was inserted * @param sheetIndex the sheet index on which the column was inserted * @param col the column number which was inserted */ public override void columnInserted(Sheet s, int sheetIndex, int col) { 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, getSheet().getWorkbook(), getSheet().getWorkbook(), getSheet().getWorkbookSettings()); parser.parse(); } parser.columnInserted(sheetIndex, col, s == getSheet()); } catch (FormulaException e) { //logger.warn("cannot insert column within formula: " + e.Message); } }
/** * 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; } }
/** * Gets the raw bytes for the formula. This will include the * parsed tokens array. Used when copying spreadsheets * * @return the raw record data * @exception FormulaException */ public override byte[] getFormulaData() { if (!getSheet().getWorkbookBof().isBiff8()) { throw new FormulaException(FormulaException.BIFF8_SUPPORTED); } // Get the tokens, taking into account the mapping from shared // formula specific values into normal values FormulaParser fp = new FormulaParser (getTokens(),this, getExternalSheet(),getNameTable(), getSheet().getWorkbook().getSettings()); fp.parse(); byte[] rpnTokens = fp.getBytes(); byte[] data = new byte[rpnTokens.Length + 22]; // Set the standard info for this cell IntegerHelper.getTwoBytes(getRow(),data,0); IntegerHelper.getTwoBytes(getColumn(),data,2); IntegerHelper.getTwoBytes(getXFIndex(),data,4); // Set the two most significant bytes of the value to be 0xff in // order to identify this as a string data[6] = 0; data[12] = (byte)0xff; data[13] = (byte)0xff; // Now copy in the parsed tokens System.Array.Copy(rpnTokens,0,data,22,rpnTokens.Length); IntegerHelper.getTwoBytes(rpnTokens.Length,data,20); // Lop off the standard information byte[] d = new byte[data.Length - 6]; System.Array.Copy(data,6,d,0,data.Length - 6); return d; }
/** * Gets the formula as an excel string * * @return the formula as an excel string * @exception FormulaException */ public string getFormula() { if (formulaString == null) { byte[] tokens = new byte[data.Length - 22]; System.Array.Copy(data,22,tokens,0,tokens.Length); FormulaParser fp = new FormulaParser (tokens,this,externalSheet,nameTable, getSheet().getWorkbook().getSettings()); fp.parse(); formulaString = fp.getFormula(); } return formulaString; }
/** * Error formula specific exception handling. Can't really create * a formula (as it will look for a cell of that name, so just * create a STRING record containing the contents * * @return the bodged data */ public override byte[] handleFormulaException() { byte[] expressiondata = null; byte[] celldata = base.getCellData(); // Generate an appropriate dummy formula WritableWorkbookImpl w = getSheet().getWorkbook(); FormulaParser parser = new FormulaParser(getValue().ToString(), w, w, w.getSettings()); // Get the bytes for the dummy formula try { parser.parse(); } catch (FormulaException e2) { //logger.warn(e2.Message); } byte[] formulaBytes = parser.getBytes(); expressiondata = new byte[formulaBytes.Length + 16]; IntegerHelper.getTwoBytes(formulaBytes.Length, expressiondata, 14); System.Array.Copy(formulaBytes, 0, expressiondata, 16, formulaBytes.Length); // Set the recalculate on load bit expressiondata[8] |= 0x02; byte[] data = new byte[celldata.Length + expressiondata.Length]; System.Array.Copy(celldata, 0, data, 0, celldata.Length); System.Array.Copy(expressiondata, 0, data, celldata.Length, expressiondata.Length); // Store the value in the formula DoubleHelper.getIEEEBytes(getValue(), data, 6); return data; }
/** * Error formula specific exception handling. Can't really create * a formula (as it will look for a cell of that name, so just * create a STRING record containing the contents * * @return the bodged data */ public override byte[] handleFormulaException() { byte[] expressiondata = null; byte[] celldata = base.getCellData(); int errorCode = getErrorCode(); string formulaString = null; if (errorCode == FormulaErrorCode.DIV0.getCode()) formulaString = "1/0"; else if (errorCode == FormulaErrorCode.VALUE.getCode()) formulaString = "\"\"/0"; else if (errorCode == FormulaErrorCode.REF.getCode()) formulaString = "\"#REF!\""; else formulaString = "\"ERROR\""; // Generate an appropriate dummy formula WritableWorkbookImpl w = getSheet().getWorkbook(); FormulaParser parser = new FormulaParser(formulaString, w, w, w.getSettings()); // Get the bytes for the dummy formula try { parser.parse(); } catch (FormulaException e2) { //logger.warn(e2.Message); } byte[] formulaBytes = parser.getBytes(); expressiondata = new byte[formulaBytes.Length + 16]; IntegerHelper.getTwoBytes(formulaBytes.Length, expressiondata, 14); System.Array.Copy(formulaBytes, 0, expressiondata, 16,formulaBytes.Length); // Set the recalculate on load bit expressiondata[8] |= 0x02; byte[] data = new byte[celldata.Length + expressiondata.Length]; System.Array.Copy(celldata, 0, data, 0, celldata.Length); System.Array.Copy(expressiondata, 0, data,celldata.Length, expressiondata.Length); // Set the type bits to indicate an error data[6] = 2; data[12] = (byte)0xff; data[13] = (byte)0xff; // Set the error code data[8] = (byte)errorCode; return data; }
/** * 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(); } }
/** * 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)); } }