/// <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="excelFile">the excel file /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="es">the workbook, which contains the external sheet references /// </param> /// <param name="nt">the name table /// </param> /// <param name="i">a dummy override to indicate that we don't want to do /// any shared formula processing /// </param> /// <param name="si">the sheet impl /// </param> /// <param name="ws">the workbook settings /// </param> public FormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, IgnoreSharedFormula i, SheetImpl si, WorkbookSettings ws) : base(t, fr, si) { sbyte[] data = getRecord().Data; shared = false; // microsoft and their magic values determine whether this // is a string or a number value if (data[6] == 0 && data[12] == -1 && data[13] == -1) { // we have a string formula = new StringFormulaRecord(t, excelFile, fr, es, nt, si, ws); } else if (data[6] == 1 && data[12] == -1 && data[13] == -1) { // We have a boolean formula // multiple values. Thanks to Frank for spotting this formula = new BooleanFormulaRecord(t, fr, es, nt, si); } else if (data[6] == 2 && data[12] == -1 && data[13] == -1) { // 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 object * * @param t the raw data * @param fr the formatting records * @param si the sheet */ public ErrorRecord(Record t,FormattingRecords fr,SheetImpl si) : base(t,fr,si) { byte[] data = getRecord().getData(); errorCode = data[6]; }
/** * Manufactures individual cell formulas out the whole shared formula * debacle * * @param fr the formatting records * @param nf flag indicating whether this uses the 1904 date system * @return an array of formulas to be added to the sheet */ public Cell[] getFormulas(FormattingRecords fr, bool nf) { Cell[] sfs = new Cell[formulas.Count + 1]; // This can happen if there are many identical formulas in the // sheet and excel has not sliced and diced them exclusively if (templateFormula == null) { //logger.warn("Shared formula template formula is null"); return(new Cell[0]); } templateFormula.setTokens(tokens); NumberFormat templateNumberFormat = null; // See if the template formula evaluates to date if (templateFormula.getType() == CellType.NUMBER_FORMULA) { SharedNumberFormulaRecord snfr = (SharedNumberFormulaRecord) templateFormula; templateNumberFormat = snfr.getNumberFormat(); if (fr.isDate(templateFormula.getXFIndex())) { templateFormula = new SharedDateFormulaRecord(snfr, fr, nf, sheet, snfr.getFilePos()); templateFormula.setTokens(snfr.getTokens()); } } sfs[0] = templateFormula; BaseSharedFormulaRecord f = null; for (int i = 0; i < formulas.Count; i++) { f = (BaseSharedFormulaRecord)formulas[i]; // See if the formula evaluates to date if (f.getType() == CellType.NUMBER_FORMULA) { SharedNumberFormulaRecord snfr = (SharedNumberFormulaRecord)f; if (fr.isDate(f.getXFIndex())) { f = new SharedDateFormulaRecord(snfr, fr, nf, sheet, snfr.getFilePos()); } else { ; // snfr.setNumberFormat(templateNumberFormat); } } f.setTokens(tokens); sfs[i + 1] = f; } return(sfs); }
/// <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="ws">the workbook settings /// </param> /// <param name="dummy">dummy overload to indicate a biff 7 workbook /// </param> public LabelRecord(Record t, FormattingRecords fr, SheetImpl si, WorkbookSettings ws, Biff7 dummy) : base(t, fr, si) { sbyte[] data = getRecord().Data; length = IntegerHelper.getInt(data[6], data[7]); _Value = StringHelper.getString(data, length, 8, ws); }
/** * Constructs this object * * @param t the raw data * @param fr the formatting records * @param si the sheet */ public ErrorRecord(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { byte[] data = getRecord().getData(); errorCode = data[6]; }
/** * Constructor. Retrieves the index from the raw data and looks it up * in the shared string table * * @param stringTable the shared string table * @param t the raw data * @param fr the formatting records * @param si the sheet */ public LabelSSTRecord(Record t, SSTRecord stringTable, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { byte[] data = getRecord().getData(); index = IntegerHelper.getInt(data[6], data[7], data[8], data[9]); description = stringTable.getString(index); }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param si the sheet * @param ws the workbook settings * @param dummy dummy overload to indicate a biff 7 workbook */ public RStringRecord(Record t, FormattingRecords fr, SheetImpl si, WorkbookSettings ws, Biff7 dummy) : base(t, fr, si) { byte[] data = getRecord().getData(); length = IntegerHelper.getInt(data[6], data[7]); description = StringHelper.getString(data, length, 8, ws); }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param si the sheet * @param ws the workbook settings * @param dummy dummy overload to indicate a biff 7 workbook */ public RStringRecord(Record t,FormattingRecords fr,SheetImpl si,WorkbookSettings ws,Biff7 dummy) : base(t,fr,si) { byte[] data = getRecord().getData(); length = IntegerHelper.getInt(data[6],data[7]); description = StringHelper.getString(data,length,8,ws); }
/** * Constructs this object from the raw data * * @param num the numerical representation of this * @param xfi the java equivalent of the excel date format * @param fr the formatting records * @param nf flag indicating whether we are using the 1904 date system * @param si the sheet */ public DateRecord(NumberCell num, int xfi, FormattingRecords fr, bool nf, SheetImpl si) { row = num.getRow(); column = num.getColumn(); xfIndex = xfi; formattingRecords = fr; sheet = si; initialized = false; format = formattingRecords.getDateFormat(xfIndex); // This value represents the number of days since 01 Jan 1900 double numValue = num.getValue(); if (Math.Abs(numValue) < 1) { if (format == null) { format = timeFormat; } time = true; } else { if (format == null) { format = dateFormat; } time = false; } // Work round a bug in excel. Excel seems to think there is a date // called the 29th Feb, 1900 - but in actual fact this was not a leap year. // Therefore for values less than 61 in the 1900 date system, // add one to the numeric value if (!nf && !time && numValue < nonLeapDay) { numValue += 1; } // Get rid of any timezone adjustments - we are not interested // in automatic adjustments // TODO: CML -- don't know what to do here.... // format.setTimeZone(gmtZone); // Convert this to the number of days since 01 Jan 1970 int offsetDays = nf ? utcOffsetDays1904 : utcOffsetDays; double utcDays = numValue - offsetDays; // Convert this into utc by multiplying by the number of milliseconds // in a day. Use the round function prior to ms conversion due // to a rounding feature of Excel (contributed by Jurgen) long utcValue = (long)Math.Round(utcDays * secondsInADay) * msInASecond; date = new System.DateTime(ticksTo1970 + (utcValue * msTicks)); }
/// <summary> Constructs this string formula /// /// </summary> /// <param name="t">the record /// </param> /// <param name="excelFile">the excel file /// </param> /// <param name="fr">the formatting record /// </param> /// <param name="es">the external sheet /// </param> /// <param name="nt">the workbook /// </param> /// <param name="si">the sheet /// </param> /// <param name="ws">the workbook settings /// </param> public SharedStringFormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, WorkbookSettings ws) : base(t, fr, es, nt, si, excelFile.Pos) { int pos = excelFile.Pos; // Save the position in the excel file int filepos = excelFile.Pos; // 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.Type != NExcel.Biff.Type.STRING && count < 4) { nextRecord = excelFile.next(); count++; } Assert.verify(count < 4, " @ " + pos); sbyte[] stringData = nextRecord.Data; 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.Pos = filepos; }
/** * 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 cell /// /// </summary> /// <param name="r">the zero based row /// </param> /// <param name="c">the zero base column /// </param> /// <param name="xfi">the xf index /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="si">the sheet /// </param> public MulBlankCell(int r, int c, int xfi, FormattingRecords fr, SheetImpl si) { row = r; column = c; xfIndex = xfi; formattingRecords = fr; sheet = si; initialized = false; }
/** * Called when the cell is added to the worksheet in order to indicate * that this object is already added to the worksheet * This method also verifies that the associated formats and formats * have been initialized correctly * * @param fr the formatting records * @param ss the shared strings used within the workbook * @param s the sheet this is being added to */ public virtual void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) { referenced = true; sheet = s; formattingRecords = fr; addCellFormat(); addCellFeatures(); }
/// <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> Constructs this object from the raw cell data /// /// </summary> /// <param name="t">the raw cell data /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="si">the sheet containing this cell /// </param> protected internal CellValue(Record t, FormattingRecords fr, SheetImpl si) : base(t) { sbyte[] data = getRecord().Data; row = IntegerHelper.getInt(data[0], data[1]); column = IntegerHelper.getInt(data[2], data[3]); xfIndex = IntegerHelper.getInt(data[4], data[5]); sheet = si; formattingRecords = fr; initialized = false; }
/// <summary> Constructs this number /// /// </summary> /// <param name="r">the zero based row /// </param> /// <param name="c">the zero base column /// </param> /// <param name="val">the value /// </param> /// <param name="xfi">the xf index /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="si">the sheet /// </param> public NumberValue(int r, int c, double val, int xfi, FormattingRecords fr, SheetImpl si) { row = r; column = c; _Value = val; format = defaultFormat; xfIndex = xfi; formattingRecords = fr; sheet = si; initialized = false; }
/** * 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 object from the raw data * * @param t the raw data * @param fr the formatting records * @param si the sheet * @param ws the workbook settings */ public LabelRecord(Record t,FormattingRecords fr,SheetImpl si,WorkbookSettings ws) : base(t,fr,si) { byte[] data = getRecord().getData(); length = IntegerHelper.getInt(data[6],data[7]); if (data[8] == 0x0) description = StringHelper.getString(data,length,9,ws); else description = StringHelper.getUnicodeString(data,length,9); }
/** * 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 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 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 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; }
/// <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 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 object from the raw data * * @param t the raw data * @param fr the available formats * @param si the sheet */ public NumberRecord(Record t,FormattingRecords fr,SheetImpl si) : base(t,fr,si) { byte[] data = getRecord().getData(); value = DoubleHelper.getIEEEDouble(data,6); // Now get the number format format = fr.getNumberFormat(getXFIndex()); if (format == null) format = defaultFormat; }
/// <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="excelFile">the excel file /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="es">the workbook, which contains the external sheet references /// </param> /// <param name="nt">the name table /// </param> /// <param name="si">the sheet /// </param> /// <param name="ws">the workbook settings /// </param> public FormulaRecord(Record t, File excelFile, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si, WorkbookSettings ws) : base(t, fr, si) { sbyte[] data = getRecord().Data; 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] == -1 && data[13] == -1) { // It is a shared string formula formula = new SharedStringFormulaRecord(t, excelFile, fr, es, nt, si, ws); } else { // It is a numerical formula double Value = DoubleHelper.getIEEEDouble(data, 6); formula = new SharedNumberFormulaRecord(t, excelFile, Value, fr, es, nt, si); } return; } // microsoft and their goddam magic values determine whether this // is a string or a number value if (data[6] == 0 && data[12] == -1 && data[13] == -1) { // we have a string formula = new StringFormulaRecord(t, excelFile, fr, es, nt, si, ws); } else if (data[6] == 1 && data[12] == -1 && data[13] == -1) { // We have a boolean formula // multiple values. Thanks to Frank for spotting this formula = new BooleanFormulaRecord(t, fr, es, nt, si); } else if (data[6] == 2 && data[12] == -1 && data[13] == -1) { // 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); } }
/// <summary> Constructs this object from the raw excel data /// /// </summary> /// <param name="f">the excel 97 biff file /// </param> /// <param name="s">the workbook settings /// </param> public WorkbookParser(File f, WorkbookSettings s) : base() { excelFile = f; boundsheets = new ArrayList(10); fonts = new Fonts(); formattingRecords = new FormattingRecords(fonts); sheets = new ArrayList(10); supbooks = new ArrayList(10); namedRecords = new Hashtable(); lastSheetIndex = -1; wbProtected = false; settings = s; }
/// <summary> Constructs this object from the raw data /// /// </summary> /// <param name="t">the raw data /// </param> /// <param name="fr">the available formats /// </param> /// <param name="si">the sheet /// </param> public NumberRecord(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { sbyte[] data = getRecord().Data; _Value = DoubleHelper.getIEEEDouble(data, 6); // Now get the number format format = fr.getNumberFormat(XFIndex); if (format == null) { format = defaultFormat; } }
/** * 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 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 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 * * @param f the excel file * @param sst the shared string table * @param fr formatting records * @param sb the bof record which indicates the start of the sheet * @param wb the bof record which indicates the start of the sheet * @param nf the 1904 flag * @param wp the workbook which this sheet belongs to * @exception BiffException */ public SheetImpl(File f, SSTRecord sst, FormattingRecords fr, BOFRecord sb, BOFRecord wb, bool nf, WorkbookParser wp) { excelFile = f; sharedStrings = sst; formattingRecords = fr; sheetBof = sb; workbookBof = wb; columnInfosArray = new ArrayList(); sharedFormulas = new ArrayList(); hyperlinks = new ArrayList(); rowProperties = new ArrayList(10); columnInfosInitialized = false; rowRecordsInitialized = false; nineteenFour = nf; workbook = wp; workbookSettings = workbook.getSettings(); // Mark the position in the stream, and then skip on until the end startPosition = f.getPos(); if (sheetBof.isChart()) { // Set the start pos to include the bof so the sheet reader can handle it startPosition -= (sheetBof.getLength() + 4); } Record r = null; int bofs = 1; while (bofs >= 1) { r = f.next(); // use this form for quick performance if (r.getCode() == Type.EOF.value) { bofs--; } if (r.getCode() == Type.BOF.value) { bofs++; } } }
/** * Overrides the method in the base class in order to add the string * content to the shared string table, and to store its shared string * index * * @param fr the formatting records * @param ss the shared strings used within the workbook * @param s */ public override void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) { base.setCellDetails(fr, ss, s); sharedStrings = ss; index = sharedStrings.getIndex(contents); // Use the sharedStrings reference instead of this object's own // handle - this means that the bespoke copy becomes eligible for // garbage collection contents = sharedStrings.get(index); }
/// <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> public BooleanRecord(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { error = false; _Value = false; sbyte[] data = getRecord().Data; error = (data[7] == 1); if (!error) { _Value = data[6] == 1?true:false; } }
/// <summary> Constructs this object from the raw data /// /// </summary> /// <param name="t">the raw data /// </param> /// <param name="fr">the available cell formats /// </param> /// <param name="si">the sheet /// </param> public RKRecord(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { sbyte[] data = getRecord().Data; int rknum = IntegerHelper.getInt(data[6], data[7], data[8], data[9]); _Value = RKHelper.getDouble(rknum); // Now get the number format format = fr.getNumberFormat(XFIndex); if (format == null) { format = defaultFormat; } }
/// <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="ws">the workbook settings /// </param> public LabelRecord(Record t, FormattingRecords fr, SheetImpl si, WorkbookSettings ws) : base(t, fr, si) { sbyte[] data = getRecord().Data; length = IntegerHelper.getInt(data[6], data[7]); if (data[8] == 0x0) { _Value = StringHelper.getString(data, length, 9, ws); } else { _Value = StringHelper.getUnicodeString(data, length, 9); } }
/** * Constructs this number formula * * @param nfr the number formula records * @param fr the formatting records * @param nf flag indicating whether this uses the 1904 date system * @param si the sheet * @param pos the position */ public SharedDateFormulaRecord(SharedNumberFormulaRecord nfr, FormattingRecords fr, bool nf, SheetImpl si, int pos) : base(nfr.getRecord(), fr, nfr.getExternalSheet(), nfr.getNameTable(), si, pos) { dateRecord = new DateRecord(nfr,nfr.getXFIndex(),fr,nf,si); value = nfr.getValue(); }
/** * Constructs this object from the raw data * * @param t the raw data * @param fr the formatting records * @param si the sheet */ public BooleanRecord(Record t,FormattingRecords fr,SheetImpl si) : base(t,fr,si) { error = false; value = false; byte[] data = getRecord().getData(); error = (data[7] == 1); if (!error) { value = data[6] == 1 ? true : false; } }
/** * 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; }
/** * Constructs this number formula * * @param nfr the number formula records * @param fr the formatting records * @param nf flag indicating whether this uses the 1904 date system * @param si the sheet * @param pos the position */ public SharedDateFormulaRecord(SharedNumberFormulaRecord nfr, FormattingRecords fr, bool nf, SheetImpl si, int pos) : base(nfr.getRecord(), fr, nfr.getExternalSheet(), nfr.getNameTable(), si, pos) { dateRecord = new DateRecord(nfr, nfr.getXFIndex(), fr, nf, si); value = nfr.getValue(); }
/** * Manufactures individual cell formulas out the whole shared formula * debacle * * @param fr the formatting records * @param nf flag indicating whether this uses the 1904 date system * @return an array of formulas to be added to the sheet */ public Cell[] getFormulas(FormattingRecords fr, bool nf) { Cell[] sfs = new Cell[formulas.Count + 1]; // This can happen if there are many identical formulas in the // sheet and excel has not sliced and diced them exclusively if (templateFormula == null) { //logger.warn("Shared formula template formula is null"); return new Cell[0]; } templateFormula.setTokens(tokens); NumberFormat templateNumberFormat = null; // See if the template formula evaluates to date if (templateFormula.getType() == CellType.NUMBER_FORMULA) { SharedNumberFormulaRecord snfr = (SharedNumberFormulaRecord) templateFormula; templateNumberFormat = snfr.getNumberFormat(); if (fr.isDate(templateFormula.getXFIndex())) { templateFormula = new SharedDateFormulaRecord(snfr,fr,nf,sheet, snfr.getFilePos()); templateFormula.setTokens(snfr.getTokens()); } } sfs[0] = templateFormula; BaseSharedFormulaRecord f = null; for (int i = 0; i < formulas.Count; i++) { f = (BaseSharedFormulaRecord)formulas[i]; // See if the formula evaluates to date if (f.getType() == CellType.NUMBER_FORMULA) { SharedNumberFormulaRecord snfr = (SharedNumberFormulaRecord)f; if (fr.isDate(f.getXFIndex())) { f = new SharedDateFormulaRecord(snfr,fr,nf,sheet, snfr.getFilePos()); } else { ;// snfr.setNumberFormat(templateNumberFormat); } } f.setTokens(tokens); sfs[i + 1] = f; } return sfs; }
/** * 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); } }
public void setFormatRecords(FormattingRecords fr) { formatRecords = fr; }
/** * 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; }
/** * Constructor * * @param fr the formatting records * @param sst the shared string table * @param f the excel file * @param sb the bof record which indicates the start of the sheet * @param wb the bof record which indicates the start of the sheet * @param wp the workbook which this sheet belongs to * @param sp the start position of the sheet bof in the excel file * @param sh the sheet * @param nf 1904 date record flag * @exception BiffException */ public SheetReader(File f, SSTRecord sst, FormattingRecords fr, BOFRecord sb, BOFRecord wb, bool nf, WorkbookParser wp, int sp, SheetImpl sh) { excelFile = f; sharedStrings = sst; formattingRecords = fr; sheetBof = sb; workbookBof = wb; columnInfosArray = new ArrayList(); sharedFormulas = new ArrayList(); hyperlinks = new ArrayList(); conditionalFormats = new ArrayList(); rowProperties = new ArrayList(10); charts = new ArrayList(); drawings = new ArrayList(); outOfBoundsCells = new ArrayList(); nineteenFour = nf; workbook = wp; startPosition = sp; sheet = sh; settings = new SheetSettings(sh); workbookSettings = workbook.getSettings(); }
/** * Constructs this object from the raw cell data * * @param t the raw cell data * @param fr the formatting records * @param si the sheet containing this cell */ protected CellValue(Record t,FormattingRecords fr,SheetImpl si) : base(t) { byte[] data = getRecord().getData(); row = IntegerHelper.getInt(data[0],data[1]); column = IntegerHelper.getInt(data[2],data[3]); xfIndex = IntegerHelper.getInt(data[4],data[5]); sheet = si; formattingRecords = fr; initialized = false; }
/** * Constructor. Writes the workbook direct to the existing output stream * * @exception IOException * @param os the output stream * @param cs TRUE if the workbook should close the output stream, FALSE * @param ws the configuration for this workbook * otherwise */ public WritableWorkbookImpl(Stream os, bool cs, WorkbookSettings ws) : base() { outputFile = new File(os, ws, null); sheets = new ArrayList(); sharedStrings = new SharedStrings(); nameRecords = new Dictionary<string, NameRecord>(); closeStream = cs; wbProtected = false; containsMacros = false; settings = ws; rcirCells = new ArrayList(); styles = new Styles(); // Reset the statically declared styles. These are no longer needed // because the Styles class will intercept all calls within // CellValue.setCellDetails and if it detects a standard format, then it // will return a clone. In short, the static cell values will // never get initialized anyway. Still, just to be extra sure... //lock (SYNCHRONIZER) // { // WritableWorkbook.ARIAL_10_PT.initialize(); // WritableWorkbook.HYPERLINK_FONT.initialize(); // WritableWorkbook.NORMAL_STYLE.initialize(); // WritableWorkbook.HYPERLINK_STYLE.initialize(); // WritableWorkbook.HIDDEN_STYLE.initialize(); // DateRecord.defaultDateFormat.initialize(); // } WritableFonts wf = new WritableFonts(this); fonts = wf; WritableFormattingRecords wfr = new WritableFormattingRecords(fonts, styles); formatRecords = wfr; }
/** * A pseudo copy constructor. Takes the handles to the font and formatting * records * * @exception IOException * @param w the workbook to copy * @param os the output stream to write the data to * @param cs TRUE if the workbook should close the output stream, FALSE * @param ws the configuration for this workbook */ public WritableWorkbookImpl(Stream os, Workbook w, bool cs, WorkbookSettings ws) : base() { CSharpJExcel.Jxl.Read.Biff.WorkbookParser wp = (CSharpJExcel.Jxl.Read.Biff.WorkbookParser)w; // Reset the statically declared styles. These are no longer needed // because the Styles class will intercept all calls within // CellValue.setCellDetails and if it detects a standard format, then it // will return a clone. In short, the static cell values will // never get initialized anyway. Still, just to be extra sure... //lock (SYNCHRONIZER) // { // WritableWorkbook.ARIAL_10_PT.uninitialize(); // WritableWorkbook.HYPERLINK_FONT.uninitialize(); // WritableWorkbook.NORMAL_STYLE.uninitialize(); // WritableWorkbook.HYPERLINK_STYLE.uninitialize(); // WritableWorkbook.HIDDEN_STYLE.uninitialize(); // DateRecord.defaultDateFormat.uninitialize(); // } closeStream = cs; sheets = new ArrayList(); sharedStrings = new SharedStrings(); nameRecords = new Dictionary<string, NameRecord>(); fonts = wp.getFonts(); formatRecords = wp.getFormattingRecords(); wbProtected = false; settings = ws; rcirCells = new ArrayList(); styles = new Styles(); outputFile = new File(os, ws, wp.getCompoundFile()); containsMacros = false; if (!ws.getPropertySetsDisabled()) containsMacros = wp.containsMacros(); // Copy the country settings if (wp.getCountryRecord() != null) countryRecord = new CountryRecord(wp.getCountryRecord()); // Copy any add in functions addInFunctionNames = wp.getAddInFunctionNames(); // Copy XCT records xctRecords = wp.getXCTRecords(); // Copy any external sheets if (wp.getExternalSheetRecord() != null) { externSheet = new ExternalSheetRecord(wp.getExternalSheetRecord()); // Get the associated supbooks CSharpJExcel.Jxl.Read.Biff.SupbookRecord[] readsr = wp.getSupbookRecords(); supbooks = new ArrayList(readsr.Length); for (int i = 0; i < readsr.Length; i++) { CSharpJExcel.Jxl.Read.Biff.SupbookRecord readSupbook = readsr[i]; if (readSupbook.getType() == SupbookRecord.INTERNAL || readSupbook.getType() == SupbookRecord.EXTERNAL) supbooks.Add(new SupbookRecord(readSupbook, settings)); else { if (readSupbook.getType() != SupbookRecord.ADDIN) { //logger.warn("unsupported supbook type - ignoring"); } } } } // Copy any drawings. These must be present before we try and copy // the images from the read workbook if (wp.getDrawingGroup() != null) drawingGroup = new DrawingGroup(wp.getDrawingGroup()); // Copy the property set references if (containsMacros && wp.getButtonPropertySet() != null) buttonPropertySet = new ButtonPropertySetRecord(wp.getButtonPropertySet()); // Copy any names if (!settings.getNamesDisabled()) { CSharpJExcel.Jxl.Read.Biff.NameRecord[] na = wp.getNameRecords(); names = new ArrayList(na.Length); for (int i = 0; i < na.Length; i++) { if (na[i].isBiff8()) { NameRecord n = new NameRecord(na[i], i); names.Add(n); string key = n.getName() == null ? NULLKEY : n.getName(); nameRecords.Add(key, n); } else { //logger.warn("Cannot copy Biff7 name records - ignoring"); } } } copyWorkbook(w); // The copy process may have caused some critical fields in the // read drawing group to change. Make sure these updates are reflected // in the writable drawing group if (drawingGroup != null) drawingGroup.updateData(wp.getDrawingGroup()); }
/** * 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. 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); }
/** * Constructor used when copying an existing spreadsheet * * @param col the column number * @param cir the column info record read in * @param fr the format records */ public ColumnInfoRecord(CSharpJExcel.Jxl.Read.Biff.ColumnInfoRecord cir,int col,FormattingRecords fr) : base(Type.COLINFO) { column = col; width = cir.getWidth(); xfIndex = cir.getXFIndex(); style = fr.getXFRecord(xfIndex); outlineLevel = cir.getOutlineLevel(); collapsed = cir.getCollapsed(); }
/** * 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); }
/** * 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); }
/** * Constructs this cell * * @param r the zero based row * @param c the zero base column * @param xfi the xf index * @param fr the formatting records * @param si the sheet */ public MulBlankCell(int r,int c, int xfi, FormattingRecords fr, SheetImpl si) { row = r; column = c; xfIndex = xfi; formattingRecords = fr; sheet = si; initialized = false; }
/** * Overrides the method in the base class to add this to the Workbook's * list of maintained formulas * * @param fr the formatting records * @param ss the shared strings used within the workbook * @param s the sheet this is being added to */ public override void setCellDetails(FormattingRecords fr, SharedStrings ss, WritableSheetImpl s) { base.setCellDetails(fr, ss, s); s.getWorkbook().addRCIRCell(this); }
/** * Constructs this object from the raw excel data * * @param f the excel 97 biff file * @param s the workbook settings */ public WorkbookParser(File f,WorkbookSettings s) : base() { excelFile = f; boundsheets = new ArrayList(10); fonts = new Fonts(); formattingRecords = new FormattingRecords(fonts); sheets = new ArrayList(10); supbooks = new ArrayList(10); namedRecords = new Dictionary<string,NameRecord>(); lastSheetIndex = -1; wbProtected = false; doesContainMacros = false; settings = s; xctRecords = new ArrayList(10); }
/** * Constructs this object from the raw data * * @param num the numerical representation of this * @param xfi the java equivalent of the excel date format * @param fr the formatting records * @param nf flag indicating whether we are using the 1904 date system * @param si the sheet */ public DateRecord(NumberCell num, int xfi,FormattingRecords fr, bool nf,SheetImpl si) { row = num.getRow(); column = num.getColumn(); xfIndex = xfi; formattingRecords = fr; sheet = si; initialized = false; format = formattingRecords.getDateFormat(xfIndex); // This value represents the number of days since 01 Jan 1900 double numValue = num.getValue(); if (Math.Abs(numValue) < 1) { if (format == null) format = timeFormat; time = true; } else { if (format == null) format = dateFormat; time = false; } // Work round a bug in excel. Excel seems to think there is a date // called the 29th Feb, 1900 - but in actual fact this was not a leap year. // Therefore for values less than 61 in the 1900 date system, // add one to the numeric value if (!nf && !time && numValue < nonLeapDay) { numValue += 1; } // Get rid of any timezone adjustments - we are not interested // in automatic adjustments // TODO: CML -- don't know what to do here.... // format.setTimeZone(gmtZone); // Convert this to the number of days since 01 Jan 1970 int offsetDays = nf ? utcOffsetDays1904 : utcOffsetDays; double utcDays = numValue - offsetDays; // Convert this into utc by multiplying by the number of milliseconds // in a day. Use the round function prior to ms conversion due // to a rounding feature of Excel (contributed by Jurgen) long utcValue = (long)Math.Round(utcDays * secondsInADay) * msInASecond; date = new System.DateTime(ticksTo1970 + (utcValue * msTicks)); }