示例#1
0
        /**
         * Does the hard work of building up the object graph from the excel bytes
         *
         * @exception BiffException
         * @exception PasswordException if the workbook is password protected
         */
        protected 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();
            ArrayList localNames      = new ArrayList();

            nameTable      = new ArrayList();
            addInFunctions = new ArrayList();

            // Skip to the first worksheet
            while (bofs == 1)
            {
                r = excelFile.next();

                if (r.getType() == Type.SST)
                {
                    continueRecords.Clear();
                    Record nextrec = excelFile.peek();
                    while (nextrec.getType() == Type.CONTINUE)
                    {
                        continueRecords.Add(excelFile.next());
                        nextrec = excelFile.peek();
                    }

                    // cast the array
                    Record[] records = new Record[continueRecords.Count];
                    int      pos     = 0;
                    foreach (Record record in continueRecords)
                    {
                        records[pos++] = record;
                    }

                    sharedStrings = new SSTRecord(r, records, settings);
                }
                else if (r.getType() == Type.FILEPASS)
                {
                    throw new PasswordException();
                }
                else if (r.getType() == Type.NAME)
                {
                    NameRecord nr = null;

                    if (bof.isBiff8())
                    {
                        nr = new NameRecord(r, settings, nameTable.Count);
                    }
                    else
                    {
                        nr = new NameRecord(r, settings, nameTable.Count,
                                            NameRecord.biff7);
                    }

                    // Add all local and global names to the name table in order to
                    // preserve the indexing
                    nameTable.Add(nr);

                    if (nr.isGlobal())
                    {
                        namedRecords.Add(nr.getName(), nr);
                    }
                    else
                    {
                        localNames.Add(nr);
                    }
                }
                else if (r.getType() == 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.getType() == Type.PALETTE)
                {
                    CSharpJExcel.Jxl.Biff.PaletteRecord palette = new CSharpJExcel.Jxl.Biff.PaletteRecord(r);
                    formattingRecords.setPalette(palette);
                }
                else if (r.getType() == Type.NINETEENFOUR)
                {
                    NineteenFourRecord nr = new NineteenFourRecord(r);
                    nineteenFour = nr.is1904();
                }
                else if (r.getType() == 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.Message);
                    }
                }
                else if (r.getType() == Type.XF)
                {
                    XFRecord xfr = null;
                    if (bof.isBiff8())
                    {
                        xfr = new XFRecord(r, settings, XFRecord.biff8);
                    }
                    else
                    {
                        xfr = new XFRecord(r, settings, XFRecord.biff7);
                    }

                    try
                    {
                        formattingRecords.addStyle(xfr);
                    }
                    catch (NumFormatRecordsException e)
                    {
                        // This should not happen.  Bomb out
                        Assert.verify(false, e.Message);
                    }
                }
                else if (r.getType() == Type.BOUNDSHEET)
                {
                    BoundsheetRecord br = null;

                    if (bof.isBiff8())
                    {
                        br = new BoundsheetRecord(r, settings);
                    }
                    else
                    {
                        br = new BoundsheetRecord(r, BoundsheetRecord.biff7);
                    }

                    if (br.isSheet())
                    {
                        boundsheets.Add(br);
                    }
                    else if (br.isChart() && !settings.getDrawingsDisabled())
                    {
                        boundsheets.Add(br);
                    }
                }
                else if (r.getType() == Type.EXTERNSHEET)
                {
                    if (bof.isBiff8())
                    {
                        externSheet = new ExternalSheetRecord(r, settings);
                    }
                    else
                    {
                        externSheet = new ExternalSheetRecord(r, settings, ExternalSheetRecord.biff7);
                    }
                }
                else if (r.getType() == Type.XCT)
                {
                    XCTRecord xctr = new XCTRecord(r);
                    xctRecords.Add(xctr);
                }
                else if (r.getType() == Type.CODEPAGE)
                {
                    CodepageRecord cr = new CodepageRecord(r);
                    settings.setCharacterSet(cr.getCharacterSet());
                }
                else if (r.getType() == Type.SUPBOOK)
                {
                    Record nextrec = excelFile.peek();
                    while (nextrec.getType() == Type.CONTINUE)
                    {
                        r.addContinueRecord(excelFile.next());
                        nextrec = excelFile.peek();
                    }

                    SupbookRecord sr = new SupbookRecord(r, settings);
                    supbooks.Add(sr);
                }
                else if (r.getType() == Type.EXTERNNAME)
                {
                    ExternalNameRecord enr = new ExternalNameRecord(r, settings);

                    if (enr.isAddInFunction())
                    {
                        addInFunctions.Add(enr.getName());
                    }
                }
                else if (r.getType() == Type.PROTECT)
                {
                    ProtectRecord pr = new ProtectRecord(r);
                    wbProtected = pr.isProtected();
                }
                else if (r.getType() == Type.OBJPROJ)
                {
                    doesContainMacros = true;
                }
                else if (r.getType() == Type.COUNTRY)
                {
                    countryRecord = new CountryRecord(r);
                }
                else if (r.getType() == Type.MSODRAWINGGROUP)
                {
                    if (!settings.getDrawingsDisabled())
                    {
                        msoDrawingGroup = new MsoDrawingGroupRecord(r);

                        if (drawingGroup == null)
                        {
                            drawingGroup = new DrawingGroup(Origin.READ);
                        }

                        drawingGroup.add(msoDrawingGroup);

                        Record nextrec = excelFile.peek();
                        while (nextrec.getType() == Type.CONTINUE)
                        {
                            drawingGroup.add(excelFile.next());
                            nextrec = excelFile.peek();
                        }
                    }
                }
                else if (r.getType() == Type.BUTTONPROPERTYSET)
                {
                    buttonPropertySet = new ButtonPropertySetRecord(r);
                }
                else if (r.getType() == Type.EOF)
                {
                    bofs--;
                }
                else if (r.getType() == Type.REFRESHALL)
                {
                    RefreshAllRecord rfm = new RefreshAllRecord(r);
                    settings.setRefreshAll(rfm.getRefreshAll());
                }
                else if (r.getType() == Type.TEMPLATE)
                {
                    TemplateRecord rfm = new TemplateRecord(r);
                    settings.setTemplate(rfm.getTemplate());
                }
                else if (r.getType() == Type.EXCEL9FILE)
                {
                    Excel9FileRecord e9f = new Excel9FileRecord(r);
                    settings.setExcel9File(e9f.getExcel9File());
                }
                else if (r.getType() == Type.WINDOWPROTECT)
                {
                    WindowProtectedRecord winp = new WindowProtectedRecord(r);
                    settings.setWindowProtected(winp.getWindowProtected());
                }
                else if (r.getType() == Type.HIDEOBJ)
                {
                    HideobjRecord hobj = new HideobjRecord(r);
                    settings.setHideobj(hobj.getHideMode());
                }
                else if (r.getType() == Type.WRITEACCESS)
                {
                    WriteAccessRecord war = new WriteAccessRecord(r, bof.isBiff8(), settings);
                    settings.setWriteAccess(war.getWriteAccess());
                }
                else
                {
                    // logger.info("Unsupported record type: " +
                    //            Integer.toHexString(r.getCode())+"h");
                }
            }

            bof = null;
            if (excelFile.hasNext())
            {
                r = excelFile.next();

                if (r.getType() == Type.BOF)
                {
                    bof = new BOFRecord(r);
                }
            }

            // Only get sheets for which there is a corresponding Boundsheet record
            while (bof != null && getNumberOfSheets() < 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[getNumberOfSheets()];
                    s.setName(br.getName());
                    s.setHidden(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[getNumberOfSheets()];
                    s.setName(br.getName());
                    s.setHidden(br.isHidden());
                    addSheet(s);
                }
                else
                {
                    //logger.warn("BOF is unrecognized");


                    while (excelFile.hasNext() && r.getType() != 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.getType() == Type.BOF)
                    {
                        bof = new BOFRecord(r);
                    }
                }
            }

            // Add all the local names to the specific sheets
            foreach (NameRecord nr in localNames)
            {
                if (nr.getBuiltInName() == null)
                {
                    //logger.warn("Usage of a local non-builtin name");
                }
                else if (nr.getBuiltInName() == BuiltInName.PRINT_AREA ||
                         nr.getBuiltInName() == BuiltInName.PRINT_TITLES)
                {
                    // appears to use the internal tab number rather than the
                    // external sheet index
                    SheetImpl s = (SheetImpl)sheets[nr.getSheetRef() - 1];
                    s.addLocalName(nr);
                }
            }
        }
示例#2
0
        /**
         * Writes out this sheet.  First writes out the standard sheet
         * information then writes out each row in turn.
         * Once all the rows have been written out, it retrospectively adjusts
         * the offset references in the file
         *
         * @exception IOException
         */
        public void write()
        {
            Assert.verify(rows != null);

            // This worksheet consists of just one chart, so write it and return
            if (chartOnly)
            {
                drawingWriter.write(outputFile);
                return;
            }

            BOFRecord bof = new BOFRecord(BOFRecord.sheet);

            outputFile.write(bof);

            // Compute the number of blocks of 32 rows that will be needed
            int numBlocks = numRows / 32;

            if (numRows - numBlocks * 32 != 0)
            {
                numBlocks++;
            }

            int indexPos = outputFile.getPos();

            // Write the index record out now in order to serve as a place holder
            // The bof passed in is the bof of the workbook, not this sheet
            IndexRecord indexRecord = new IndexRecord(0, numRows, numBlocks);

            outputFile.write(indexRecord);

            if (settings.getAutomaticFormulaCalculation())
            {
                CalcModeRecord cmr = new CalcModeRecord(CalcModeRecord.automatic);
                outputFile.write(cmr);
            }
            else
            {
                CalcModeRecord cmr = new CalcModeRecord(CalcModeRecord.manual);
                outputFile.write(cmr);
            }

            CalcCountRecord ccr = new CalcCountRecord(0x64);

            outputFile.write(ccr);

            RefModeRecord rmr = new RefModeRecord();

            outputFile.write(rmr);

            IterationRecord itr = new IterationRecord(false);

            outputFile.write(itr);

            DeltaRecord dtr = new DeltaRecord(0.001);

            outputFile.write(dtr);

            SaveRecalcRecord srr = new SaveRecalcRecord(settings.getRecalculateFormulasBeforeSave());

            outputFile.write(srr);

            PrintHeadersRecord phr = new PrintHeadersRecord(settings.getPrintHeaders());

            outputFile.write(phr);

            PrintGridLinesRecord pglr = new PrintGridLinesRecord(settings.getPrintGridLines());

            outputFile.write(pglr);

            GridSetRecord gsr = new GridSetRecord(true);

            outputFile.write(gsr);

            GuttersRecord gutr = new GuttersRecord();

            gutr.setMaxColumnOutline(maxColumnOutlineLevel + 1);
            gutr.setMaxRowOutline(maxRowOutlineLevel + 1);

            outputFile.write(gutr);

            DefaultRowHeightRecord drhr = new DefaultRowHeightRecord
                                              (settings.getDefaultRowHeight(),
                                              settings.getDefaultRowHeight() !=
                                              SheetSettings.DEFAULT_DEFAULT_ROW_HEIGHT);

            outputFile.write(drhr);

            if (maxRowOutlineLevel > 0)
            {
                workspaceOptions.setRowOutlines(true);
            }

            if (maxColumnOutlineLevel > 0)
            {
                workspaceOptions.setColumnOutlines(true);
            }

            workspaceOptions.setFitToPages(settings.getFitToPages());
            outputFile.write(workspaceOptions);

            if (rowBreaks.Count > 0)
            {
                int[] rb = new int[rowBreaks.Count];
                for (int i = 0; i < rb.Length; i++)
                {
                    rb[i] = (int)rowBreaks[i];
                }

                HorizontalPageBreaksRecord hpbr = new HorizontalPageBreaksRecord(rb);
                outputFile.write(hpbr);
            }

            if (columnBreaks.Count > 0)
            {
                int[] rb = new int[columnBreaks.Count];

                for (int i = 0; i < rb.Length; i++)
                {
                    rb[i] = (int)columnBreaks[i];
                }

                VerticalPageBreaksRecord hpbr = new VerticalPageBreaksRecord(rb);
                outputFile.write(hpbr);
            }

            HeaderRecord header = new HeaderRecord(settings.getHeader().ToString());

            outputFile.write(header);

            FooterRecord footer = new FooterRecord(settings.getFooter().ToString());

            outputFile.write(footer);

            HorizontalCentreRecord hcr = new HorizontalCentreRecord(settings.isHorizontalCentre());

            outputFile.write(hcr);

            VerticalCentreRecord vcr = new VerticalCentreRecord(settings.isVerticalCentre());

            outputFile.write(vcr);

            // Write out the margins if they don't equal the default
            if (settings.getLeftMargin() != settings.getDefaultWidthMargin())
            {
                MarginRecord mr = new LeftMarginRecord(settings.getLeftMargin());
                outputFile.write(mr);
            }

            if (settings.getRightMargin() != settings.getDefaultWidthMargin())
            {
                MarginRecord mr = new RightMarginRecord(settings.getRightMargin());
                outputFile.write(mr);
            }

            if (settings.getTopMargin() != settings.getDefaultHeightMargin())
            {
                MarginRecord mr = new TopMarginRecord(settings.getTopMargin());
                outputFile.write(mr);
            }

            if (settings.getBottomMargin() != settings.getDefaultHeightMargin())
            {
                MarginRecord mr = new BottomMarginRecord(settings.getBottomMargin());
                outputFile.write(mr);
            }

            if (plsRecord != null)
            {
                outputFile.write(plsRecord);
            }

            SetupRecord setup = new SetupRecord(settings);

            outputFile.write(setup);

            if (settings.isProtected())
            {
                ProtectRecord pr = new ProtectRecord(settings.isProtected());
                outputFile.write(pr);

                ScenarioProtectRecord spr = new ScenarioProtectRecord(settings.isProtected());
                outputFile.write(spr);

                ObjectProtectRecord opr = new ObjectProtectRecord(settings.isProtected());
                outputFile.write(opr);

                if (settings.getPassword() != null)
                {
                    PasswordRecord pw = new PasswordRecord(settings.getPassword());
                    outputFile.write(pw);
                }
                else if (settings.getPasswordHash() != 0)
                {
                    PasswordRecord pw = new PasswordRecord(settings.getPasswordHash());
                    outputFile.write(pw);
                }
            }

            indexRecord.setDataStartPosition(outputFile.getPos());
            DefaultColumnWidth dcw = new DefaultColumnWidth(settings.getDefaultColumnWidth());

            outputFile.write(dcw);

            // Get a handle to the normal styles
            WritableCellFormat normalStyle       = sheet.getWorkbook().getStyles().getNormalStyle();
            WritableCellFormat defaultDateFormat = sheet.getWorkbook().getStyles().getDefaultDateFormat();

            // Write out all the column formats
            foreach (ColumnInfoRecord cir in columnFormats)
            {
                // Writing out the column info with index 0x100 causes excel to crash
                if (cir.getColumn() < 0x100)
                {
                    outputFile.write(cir);
                }

                XFRecord xfr = cir.getCellFormat();

                if (xfr != normalStyle && cir.getColumn() < 0x100)
                {
                    // Make this the format for every cell in the column
                    Cell[] cells = getColumn(cir.getColumn());

                    for (int i = 0; i < cells.Length; i++)
                    {
                        if (cells[i] != null &&
                            (cells[i].getCellFormat() == normalStyle ||
                             cells[i].getCellFormat() == defaultDateFormat))
                        {
                            // The cell has no overriding format specified, so
                            // set it to the column default
                            ((WritableCell)cells[i]).setCellFormat(xfr);
                        }
                    }
                }
            }

            // Write out the auto filter
            if (autoFilter != null)
            {
                autoFilter.write(outputFile);
            }

            DimensionRecord dr = new DimensionRecord(numRows, numCols);

            outputFile.write(dr);

            // Write out all the rows, in blocks of 32
            for (int block = 0; block < numBlocks; block++)
            {
                DBCellRecord dbcell = new DBCellRecord(outputFile.getPos());

                int  blockRows = System.Math.Min(32, numRows - block * 32);
                bool firstRow  = true;

                // First write out all the row records
                for (int i = block * 32; i < block * 32 + blockRows; i++)
                {
                    if (rows[i] != null)
                    {
                        rows[i].write(outputFile);
                        if (firstRow)
                        {
                            dbcell.setCellOffset(outputFile.getPos());
                            firstRow = false;
                        }
                    }
                }

                // Now write out all the cells
                for (int i = block * 32; i < block * 32 + blockRows; i++)
                {
                    if (rows[i] != null)
                    {
                        dbcell.addCellRowPosition(outputFile.getPos());
                        rows[i].writeCells(outputFile);
                    }
                }

                // Now set the current file position in the index record
                indexRecord.addBlockPosition(outputFile.getPos());

                // Set the position of the file pointer and write out the DBCell
                // record
                dbcell.setPosition(outputFile.getPos());
                outputFile.write(dbcell);
            }

            // Do the drawings and charts if enabled
            if (!workbookSettings.getDrawingsDisabled())
            {
                drawingWriter.write(outputFile);
            }

            Window2Record w2r = new Window2Record(settings);

            outputFile.write(w2r);

            // Handle the frozen panes
            if (settings.getHorizontalFreeze() != 0 || settings.getVerticalFreeze() != 0)
            {
                PaneRecord pr = new PaneRecord(settings.getHorizontalFreeze(), settings.getVerticalFreeze());
                outputFile.write(pr);

                // Handle the selection record.  First, there will always be a top left
                SelectionRecord sr = new SelectionRecord(SelectionRecord.upperLeft, 0, 0);
                outputFile.write(sr);

                // Top right
                if (settings.getHorizontalFreeze() != 0)
                {
                    sr = new SelectionRecord(SelectionRecord.upperRight, settings.getHorizontalFreeze(), 0);
                    outputFile.write(sr);
                }

                // Bottom left
                if (settings.getVerticalFreeze() != 0)
                {
                    sr = new SelectionRecord(SelectionRecord.lowerLeft, 0, settings.getVerticalFreeze());
                    outputFile.write(sr);
                }

                // Bottom right
                if (settings.getHorizontalFreeze() != 0 &&
                    settings.getVerticalFreeze() != 0)
                {
                    sr = new SelectionRecord(SelectionRecord.lowerRight, settings.getHorizontalFreeze(), settings.getVerticalFreeze());
                    outputFile.write(sr);
                }

                Weird1Record w1r = new Weird1Record();
                outputFile.write(w1r);
            }
            else
            {
                // No frozen panes - just write out the selection record for the
                // whole sheet
                SelectionRecord sr = new SelectionRecord(SelectionRecord.upperLeft, 0, 0);
                outputFile.write(sr);
            }

            // Handle the zoom factor
            if (settings.getZoomFactor() != 100)
            {
                SCLRecord sclr = new SCLRecord(settings.getZoomFactor());
                outputFile.write(sclr);
            }

            // Now write out all the merged cells
            mergedCells.write(outputFile);

            // Write out all the hyperlinks
            foreach (WritableHyperlink hlr in hyperlinks)
            {
                outputFile.write(hlr);
            }

            if (buttonPropertySet != null)
            {
                outputFile.write(buttonPropertySet);
            }

            // Write out the data validations
            if (dataValidation != null || validatedCells.Count > 0)
            {
                writeDataValidation();
            }

            // Write out the conditional formats
            if (conditionalFormats != null && conditionalFormats.Count > 0)
            {
                foreach (ConditionalFormat cf in conditionalFormats)
                {
                    cf.write(outputFile);
                }
            }

            EOFRecord eof = new EOFRecord();

            outputFile.write(eof);

            // Now the various cross reference offsets have been calculated,
            // retrospectively set the values in the output file
            outputFile.setData(indexRecord.getData(), indexPos + 4);
        }