/// <summary> Gets the specified sheet within this workbook /// /// </summary> /// <param name="index">the zero based index of the required sheet /// </param> /// <returns> The sheet specified by the index /// </returns> public override Sheet getSheet(int index) { // First see if the last sheet index is the same as this sheet index. // If so, then the same sheet is being re-requested, so simply // return it instead of rereading it if ((lastSheet != null) && lastSheetIndex == index) { return(lastSheet); } // Flush out all of the cached data in the last sheet if (lastSheet != null) { lastSheet.clear(); if (!settings.GCDisabled) { System.GC.Collect(); } } lastSheet = (SheetImpl)sheets[index]; lastSheetIndex = index; lastSheet.readSheet(); return(lastSheet); }
/// <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); }
/// <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; }
/// <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; }
/// <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; } }
/// <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); } }
/// <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. 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); }
/// <summary> Constructor /// /// </summary> /// <param name="fr">the formatting records /// </param> /// <param name="sst">the shared string table /// </param> /// <param name="f">the excel file /// </param> /// <param name="sb">the bof record which indicates the start of the sheet /// </param> /// <param name="wb">the bof record which indicates the start of the sheet /// </param> /// <param name="wp">the workbook which this sheet belongs to /// </param> /// <param name="sp">the start position of the sheet bof in the excel file /// </param> /// <param name="sh">the sheet /// </param> /// <param name="nf">1904 date record flag /// </param> /// <exception cref=""> BiffException /// </exception> internal 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(); rowProperties = new ArrayList(10); charts = new ArrayList(); drawings = new ArrayList(); nineteenFour = nf; workbook = wp; startPosition = sp; sheet = sh; settings = new SheetSettings(); workbookSettings = workbook.Settings; }
/// <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); } }
/// <summary> Does the hard work of building up the object graph from the excel bytes /// /// </summary> /// <exception cref=""> BiffException /// </exception> /// <exception cref=""> PasswordException if the workbook is password protected /// </exception> protected internal override void parse() { Record r = null; BOFRecord bof = new BOFRecord(excelFile.next()); workbookBof = bof; bofs++; if (!bof.isBiff8() && !bof.isBiff7()) { throw new BiffException(BiffException.unrecognizedBiffVersion); } if (!bof.isWorkbookGlobals()) { throw new BiffException(BiffException.expectedGlobals); } ArrayList continueRecords = new ArrayList(); nameTable = new ArrayList(); // Skip to the first worksheet while (bofs == 1) { r = excelFile.next(); if (r.Type == NExcel.Biff.Type.SST) { continueRecords.Clear(); Record nextrec = excelFile.peek(); while (nextrec.Type == NExcel.Biff.Type.CONTINUE) { continueRecords.Add(excelFile.next()); nextrec = excelFile.peek(); } // cast the array System.Object[] rec = continueRecords.ToArray(); Record[] records = new Record[rec.Length]; Array.Copy(rec, 0, records, 0, rec.Length); sharedStrings = new SSTRecord(r, records, settings); } else if (r.Type == NExcel.Biff.Type.FILEPASS) { throw new PasswordException(); } else if (r.Type == NExcel.Biff.Type.NAME) { NameRecord nr = null; if (bof.isBiff8()) { nr = new NameRecord(r, settings, namedRecords.Count); } else { nr = new NameRecord(r, settings, namedRecords.Count, NameRecord.biff7); } namedRecords[nr.Name] = nr; nameTable.Add(nr); } else if (r.Type == NExcel.Biff.Type.FONT) { FontRecord fr = null; if (bof.isBiff8()) { fr = new FontRecord(r, settings); } else { fr = new FontRecord(r, settings, FontRecord.biff7); } fonts.addFont(fr); } else if (r.Type == NExcel.Biff.Type.PALETTE) { NExcel.Biff.PaletteRecord palette = new NExcel.Biff.PaletteRecord(r); formattingRecords.Palette = palette; } else if (r.Type == NExcel.Biff.Type.NINETEENFOUR) { NineteenFourRecord nr = new NineteenFourRecord(r); nineteenFour = nr.is1904(); } else if (r.Type == NExcel.Biff.Type.FORMAT) { FormatRecord fr = null; if (bof.isBiff8()) { fr = new FormatRecord(r, settings, FormatRecord.biff8); } else { fr = new FormatRecord(r, settings, FormatRecord.biff7); } try { formattingRecords.addFormat(fr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out // Assert.verify(false, e.getMessage()); Assert.verify(false, "This should not happen. 64"); } } else if (r.Type == NExcel.Biff.Type.XF) { XFRecord xfr = null; if (bof.isBiff8()) { xfr = new XFRecord(r, XFRecord.biff8); } else { xfr = new XFRecord(r, XFRecord.biff7); } try { formattingRecords.addStyle(xfr); } catch (NumFormatRecordsException e) { // This should not happen. Bomb out // Assert.verify(false, e.getMessage()); Assert.verify(false, "This should not happen. 59"); } } else if (r.Type == NExcel.Biff.Type.BOUNDSHEET) { BoundsheetRecord br = null; if (bof.isBiff8()) { br = new BoundsheetRecord(r); } else { br = new BoundsheetRecord(r, BoundsheetRecord.biff7); } if (br.isSheet() || br.Chart) { boundsheets.Add(br); } } else if (r.Type == NExcel.Biff.Type.EXTERNSHEET) { if (bof.isBiff8()) { externSheet = new ExternalSheetRecord(r, settings); } else { externSheet = new ExternalSheetRecord(r, settings, ExternalSheetRecord.biff7); } } else if (r.Type == NExcel.Biff.Type.CODEPAGE) { CodepageRecord cr = new CodepageRecord(r); settings.CharacterSet = cr.CharacterSet; } else if (r.Type == NExcel.Biff.Type.SUPBOOK) { SupbookRecord sr = new SupbookRecord(r, settings); supbooks.Add(sr); } else if (r.Type == NExcel.Biff.Type.PROTECT) { ProtectRecord pr = new ProtectRecord(r); wbProtected = pr.IsProtected(); } else if (r.Type == NExcel.Biff.Type.MSODRAWINGGROUP) { msoDrawingGroup = new MsoDrawingGroupRecord(r); if (drawingGroup == null) { drawingGroup = new DrawingGroup(DrawingGroup.READ); } drawingGroup.add(msoDrawingGroup); Record nextrec = excelFile.peek(); while (nextrec.Type == NExcel.Biff.Type.CONTINUE) { drawingGroup.add(excelFile.next()); nextrec = excelFile.peek(); } } else if (r.Type == NExcel.Biff.Type.EOF) { bofs--; } } bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.Type == NExcel.Biff.Type.BOF) { bof = new BOFRecord(r); } } // Only get sheets for which there is a corresponding Boundsheet record while (bof != null && NumberOfSheets < boundsheets.Count) { if (!bof.isBiff8() && !bof.isBiff7()) { throw new BiffException(BiffException.unrecognizedBiffVersion); } if (bof.isWorksheet()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[NumberOfSheets]; s.setName(br.Name); s.Hidden = br.isHidden(); addSheet(s); } else if (bof.isChart()) { // Read the sheet in SheetImpl s = new SheetImpl(excelFile, sharedStrings, formattingRecords, bof, workbookBof, nineteenFour, this); BoundsheetRecord br = (BoundsheetRecord)boundsheets[NumberOfSheets]; s.setName(br.Name); s.Hidden = br.isHidden(); addSheet(s); } else { logger.warn("BOF is unrecognized"); while (excelFile.hasNext() && r.Type != NExcel.Biff.Type.EOF) { r = excelFile.next(); } } // The next record will normally be a BOF or empty padding until // the end of the block is reached. In exceptionally unlucky cases, // the last EOF will coincide with a block division, so we have to // check there is more data to retrieve. // Thanks to liamg for spotting this bof = null; if (excelFile.hasNext()) { r = excelFile.next(); if (r.Type == NExcel.Biff.Type.BOF) { bof = new BOFRecord(r); } } } }
/// <summary> Constructs this object from the raw data. We need to use the excelFile /// to retrieve the String record which follows this formula record /// /// </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 external sheet records /// </param> /// <param name="nt">the workbook /// </param> /// <param name="si">the sheet impl /// </param> /// <param name="ws">the workbook settings /// </param> 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().Data; int pos = excelFile.Pos; // 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.Type != NExcel.Biff.Type.STRING && count < 4) { nextRecord = excelFile.next(); count++; } Assert.verify(count < 4, " @ " + pos); readString(nextRecord.Data, ws); }
/// <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; }
/// <summary> Constructs this number formula /// /// </summary> /// <param name="nfr">the number formula records /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="nf">flag indicating whether this uses the 1904 date system /// </param> /// <param name="si">the sheet /// </param> /// <param name="pos">the position /// </param> public SharedDateFormulaRecord(SharedNumberFormulaRecord nfr, FormattingRecords fr, bool nf, SheetImpl si, int pos) : base(nfr.getRecord(), fr, nfr.ExternalSheet, nfr.NameTable, si, pos) { dateRecord = new DateRecord(nfr, nfr.XFIndex, fr, nf, si); Value = nfr.DoubleValue; }
/// <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> internal BlankCell(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { }
/// <summary> Constructs this object from the raw data /// /// </summary> /// <param name="t">the basic number formula record /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="es">the external sheet /// </param> /// <param name="nt">the name table /// </param> /// <param name="nf">flag indicating whether the 1904 date system is in use /// </param> /// <param name="si">the sheet /// </param> public DateFormulaRecord(NumberFormulaRecord t, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, bool nf, SheetImpl si) : base(t, t.XFIndex, fr, nf, si) { externalSheet = es; nameTable = nt; data = t.getFormulaData(); }
/// <summary> Constructs this object /// /// </summary> /// <param name="t">the raw data /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="si">the sheet /// </param> public ErrorRecord(Record t, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { sbyte[] data = getRecord().Data; errorCode = data[6]; }
/// <summary> Constructs this number /// /// </summary> /// <param name="t">the data /// </param> /// <param name="excelFile">the excel biff data /// </param> /// <param name="v">the value /// </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 SharedNumberFormulaRecord(Record t, File excelFile, double v, FormattingRecords fr, ExternalSheet es, WorkbookMethods nt, SheetImpl si) : base(t, fr, es, nt, si, excelFile.Pos) { _Value = v; format = defaultFormat; }
/// <summary> Constructs this number /// /// </summary> /// <param name="t">the record /// </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> /// <param name="pos">the position of the next record in the file /// </param> 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> Constructor. Retrieves the index from the raw data and looks it up /// in the shared string table /// /// </summary> /// <param name="stringTable">the shared string table /// </param> /// <param name="t">the raw data /// </param> /// <param name="fr">the formatting records /// </param> /// <param name="si">the sheet /// </param> public LabelSSTRecord(Record t, SSTRecord stringTable, FormattingRecords fr, SheetImpl si) : base(t, fr, si) { sbyte[] data = getRecord().Data; index = IntegerHelper.getInt(data[6], data[7], data[8], data[9]); _Value = stringTable.getString(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="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 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="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 data /// /// </summary> /// <param name="num">the numerical representation of this /// </param> /// <param name="xfi">the java equivalent of the excel date format /// </param> /// <param name="fr"> the formatting records /// </param> /// <param name="nf"> flag indicating whether we are using the 1904 date system /// </param> /// <param name="si"> the sheet /// </param> public DateRecord(NumberCell num, int xfi, FormattingRecords fr, bool nf, SheetImpl si) { row = num.Row; column = num.Column; 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.DoubleValue; // 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 && numValue < nonLeapDay) { numValue += 1; } if (System.Math.Abs(numValue) < 1) { if (format == null) { format = timeFormat; } time = true; } else { if (format == null) { format = dateFormat; } time = false; } // Get rid of any timezone adjustments - we are not interested // in automatic adjustments // [TODO-NExcel_Next] // 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 // long utcValue = (long) System.Math.Round(utcDays * msInADay); // convert it to 100 nanoseconds long utcValue = (long)System.Math.Round(utcDays * msInADay * 10000); // add the reference date (1/1/1970) DateTime refdate = new DateTime(1970, 1, 1); utcValue += refdate.Ticks; _Value = new DateTime(utcValue); }
/// <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; }