sheet.java

来自「EXCEL read and write」· Java 代码 · 共 1,758 行 · 第 1/5 页

JAVA
1,758
字号
/* ====================================================================   Licensed to the Apache Software Foundation (ASF) under one or more   contributor license agreements.  See the NOTICE file distributed with   this work for additional information regarding copyright ownership.   The ASF licenses this file to You under the Apache License, Version 2.0   (the "License"); you may not use this file except in compliance with   the License.  You may obtain a copy of the License at       http://www.apache.org/licenses/LICENSE-2.0   Unless required by applicable law or agreed to in writing, software   distributed under the License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   See the License for the specific language governing permissions and   limitations under the License.==================================================================== */package org.apache.poi.hssf.model;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import org.apache.poi.hssf.record.BOFRecord;import org.apache.poi.hssf.record.CFHeaderRecord;import org.apache.poi.hssf.record.CalcCountRecord;import org.apache.poi.hssf.record.CalcModeRecord;import org.apache.poi.hssf.record.CellValueRecordInterface;import org.apache.poi.hssf.record.ColumnInfoRecord;import org.apache.poi.hssf.record.DVALRecord;import org.apache.poi.hssf.record.DefaultColWidthRecord;import org.apache.poi.hssf.record.DefaultRowHeightRecord;import org.apache.poi.hssf.record.DeltaRecord;import org.apache.poi.hssf.record.DimensionsRecord;import org.apache.poi.hssf.record.DrawingRecord;import org.apache.poi.hssf.record.EOFRecord;import org.apache.poi.hssf.record.EscherAggregate;import org.apache.poi.hssf.record.GridsetRecord;import org.apache.poi.hssf.record.GutsRecord;import org.apache.poi.hssf.record.IndexRecord;import org.apache.poi.hssf.record.IterationRecord;import org.apache.poi.hssf.record.MergeCellsRecord;import org.apache.poi.hssf.record.ObjRecord;import org.apache.poi.hssf.record.ObjectProtectRecord;import org.apache.poi.hssf.record.PaneRecord;import org.apache.poi.hssf.record.PasswordRecord;import org.apache.poi.hssf.record.PrintGridlinesRecord;import org.apache.poi.hssf.record.PrintHeadersRecord;import org.apache.poi.hssf.record.ProtectRecord;import org.apache.poi.hssf.record.Record;import org.apache.poi.hssf.record.RecordBase;import org.apache.poi.hssf.record.RefModeRecord;import org.apache.poi.hssf.record.RowRecord;import org.apache.poi.hssf.record.SCLRecord;import org.apache.poi.hssf.record.SaveRecalcRecord;import org.apache.poi.hssf.record.ScenarioProtectRecord;import org.apache.poi.hssf.record.SelectionRecord;import org.apache.poi.hssf.record.UncalcedRecord;import org.apache.poi.hssf.record.WSBoolRecord;import org.apache.poi.hssf.record.WindowTwoRecord;import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate;import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable;import org.apache.poi.hssf.record.aggregates.DataValidityTable;import org.apache.poi.hssf.record.aggregates.MergedCellsTable;import org.apache.poi.hssf.record.aggregates.PageSettingsBlock;import org.apache.poi.hssf.record.aggregates.RecordAggregate;import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;import org.apache.poi.hssf.record.aggregates.RecordAggregate.PositionTrackingVisitor;import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;import org.apache.poi.hssf.record.formula.FormulaShifter;import org.apache.poi.hssf.util.CellRangeAddress;import org.apache.poi.hssf.util.PaneInformation;import org.apache.poi.util.POILogFactory;import org.apache.poi.util.POILogger;/** * Low level model implementation of a Sheet (one workbook contains many sheets) * This file contains the low level binary records starting at the sheets BOF and * ending with the sheets EOF.  Use HSSFSheet for a high level representation. * <P> * The structures of the highlevel API use references to this to perform most of their * operations.  Its probably unwise to use these low level structures directly unless you * really know what you're doing.  I recommend you read the Microsoft Excel 97 Developer's * Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf * before even attempting to use this. * <P> * @author  Andrew C. Oliver (acoliver at apache dot org) * @author  Glen Stampoultzis (glens at apache.org) * @author  Shawn Laubach (slaubach at apache dot org) Gridlines, Headers, Footers, PrintSetup, and Setting Default Column Styles * @author Jason Height (jheight at chariot dot net dot au) Clone support. DBCell & Index Record writing support * @author  Brian Sanders (kestrel at burdell dot org) Active Cell support * @author  Jean-Pierre Paris (jean-pierre.paris at m4x dot org) (Just a little) * * @see org.apache.poi.hssf.model.Workbook * @see org.apache.poi.hssf.usermodel.HSSFSheet * @version 1.0-pre */public final class Sheet implements Model {    public static final short   LeftMargin = 0;    public static final short   RightMargin = 1;    public static final short   TopMargin = 2;    public static final short   BottomMargin = 3;    private static POILogger            log              = POILogFactory.getLogger(Sheet.class);    protected ArrayList                  records           =     null;    protected PrintGridlinesRecord       printGridlines    =     null;    protected GridsetRecord              gridset           =     null;    private   GutsRecord                 _gutsRecord;    protected DefaultColWidthRecord      defaultcolwidth   =     null;    protected DefaultRowHeightRecord     defaultrowheight  =     null;    private PageSettingsBlock _psBlock;    // 'Worksheet Protection Block'    protected ProtectRecord              protect           =     null;    protected ObjectProtectRecord        objprotect        =     null;    protected ScenarioProtectRecord      scenprotect       =     null;    protected PasswordRecord             password          =     null;    protected WindowTwoRecord            windowTwo         =     null;    protected SelectionRecord            selection         =     null;    /** java object always present, but if empty no BIFF records are written */    private final MergedCellsTable       _mergedCellsTable;    /** always present in this POI object, not always written to Excel file */    /*package*/ColumnInfoRecordsAggregate _columnInfos;    /** the DimensionsRecord is always present */    private DimensionsRecord             _dimensions;    /** always present */    protected final RowRecordsAggregate        _rowsAggregate;    private   DataValidityTable          _dataValidityTable=     null;    private   ConditionalFormattingTable condFormatting;    private   Iterator                   rowRecIterator    =     null;    /** Add an UncalcedRecord if not true indicating formulas have not been calculated */    protected boolean _isUncalced = false;    public static final byte PANE_LOWER_RIGHT = (byte)0;    public static final byte PANE_UPPER_RIGHT = (byte)1;    public static final byte PANE_LOWER_LEFT = (byte)2;    public static final byte PANE_UPPER_LEFT = (byte)3;    /**     * read support  (offset used as starting point for search) for low level     * API.  Pass in an array of Record objects, the sheet number (0 based) and     * a record offset (should be the location of the sheets BOF record).  A Sheet     * object is constructed and passed back with all of its initialization set     * to the passed in records and references to those records held. This function     * is normally called via Workbook.     *     * @param inRecs array containing those records in the sheet in sequence (normally obtained from RecordFactory)     * @param sheetnum integer specifying the sheet's number (0,1 or 2 in this release)     * @param offset of the sheet's BOF record     *     * @return Sheet object with all values set to those read from the file     *     * @see org.apache.poi.hssf.model.Workbook     * @see org.apache.poi.hssf.record.Record     */    public static Sheet createSheet(RecordStream rs) {        return new Sheet(rs);    }    private Sheet(RecordStream rs) {        _mergedCellsTable = new MergedCellsTable();        RowRecordsAggregate rra = null;        records            = new ArrayList(128);        // TODO - take chart streams off into separate java objects        int       bofEofNestingLevel = 0;  // nesting level can only get to 2 (when charts are present)        int dimsloc = -1;        while (rs.hasNext()) {            int recSid = rs.peekNextSid();            if ( recSid == CFHeaderRecord.sid ) {                condFormatting = new ConditionalFormattingTable(rs);                records.add(condFormatting);                continue;            }            if (recSid == ColumnInfoRecord.sid) {                _columnInfos = new ColumnInfoRecordsAggregate(rs);                records.add(_columnInfos);                continue;            }            if ( recSid == DVALRecord.sid) {                _dataValidityTable = new DataValidityTable(rs);                records.add(_dataValidityTable);                continue;            }            if (RecordOrderer.isRowBlockRecord(recSid) && bofEofNestingLevel == 1 ) {                //only add the aggregate once                if (rra != null) {                    throw new RuntimeException("row/cell records found in the wrong place");                }                RowBlocksReader rbr = new RowBlocksReader(rs);                _mergedCellsTable.addRecords(rbr.getLooseMergedCells());                rra = new RowRecordsAggregate(rbr.getPlainRecordStream(), rbr.getSharedFormulaManager());                records.add(rra); //only add the aggregate once                continue;            }            if (PageSettingsBlock.isComponentRecord(recSid)) {                PageSettingsBlock psb = new PageSettingsBlock(rs);                if (bofEofNestingLevel == 1) {                    if (_psBlock == null) {                        _psBlock = psb;                    } else {                        // more than one 'Page Settings Block' at nesting level 1 ?                        // apparently this happens in about 15 test sample files                    }                }                records.add(psb);                continue;            }            if (recSid == MergeCellsRecord.sid) {                // when the MergedCellsTable is found in the right place, we expect those records to be contiguous                _mergedCellsTable.read(rs);                continue;            }            Record rec = rs.getNext();            if ( recSid == IndexRecord.sid ) {                // ignore INDEX record because it is only needed by Excel,                // and POI always re-calculates its contents                continue;            }            if (recSid == UncalcedRecord.sid) {                // don't add UncalcedRecord to the list                _isUncalced = true; // this flag is enough                continue;            }            if (recSid == BOFRecord.sid)            {                bofEofNestingLevel++;                if (log.check( POILogger.DEBUG ))                    log.log(POILogger.DEBUG, "Hit BOF record. Nesting increased to " + bofEofNestingLevel);            }            else if (recSid == EOFRecord.sid)            {                --bofEofNestingLevel;                if (log.check( POILogger.DEBUG ))                    log.log(POILogger.DEBUG, "Hit EOF record. Nesting decreased to " + bofEofNestingLevel);                if (bofEofNestingLevel == 0) {                    records.add(rec);                    break;                }            }            else if (recSid == DimensionsRecord.sid)            {                // Make a columns aggregate if one hasn't ready been created.                if (_columnInfos == null)                {                    _columnInfos = new ColumnInfoRecordsAggregate();                    records.add(_columnInfos);                }                _dimensions    = ( DimensionsRecord ) rec;                dimsloc = records.size();            }            else if (recSid == DefaultColWidthRecord.sid)            {                defaultcolwidth = ( DefaultColWidthRecord ) rec;            }            else if (recSid == DefaultRowHeightRecord.sid)            {                defaultrowheight = ( DefaultRowHeightRecord ) rec;            }            else if ( recSid == PrintGridlinesRecord.sid )            {                printGridlines = (PrintGridlinesRecord) rec;            }            else if ( recSid == GridsetRecord.sid )            {                gridset = (GridsetRecord) rec;            }            else if ( recSid == SelectionRecord.sid )            {                selection = (SelectionRecord) rec;            }            else if ( recSid == WindowTwoRecord.sid )            {                windowTwo = (WindowTwoRecord) rec;            }            else if ( recSid == ProtectRecord.sid )            {                protect = (ProtectRecord) rec;            }            else if ( recSid == ObjectProtectRecord.sid )            {                objprotect = (ObjectProtectRecord) rec;            }            else if ( recSid == ScenarioProtectRecord.sid )            {                scenprotect = (ScenarioProtectRecord) rec;            }            else if ( recSid == PasswordRecord.sid )            {                password = (PasswordRecord) rec;            }            records.add(rec);        }        if (_dimensions == null) {            throw new RuntimeException("DimensionsRecord was not found");        }        if (windowTwo == null) {            throw new RuntimeException("WINDOW2 was not found");        }        if (rra == null) {            rra = new RowRecordsAggregate();            records.add(dimsloc + 1, rra);        }        _rowsAggregate = rra;        // put merged cells table in the right place (regardless of where the first MergedCellsRecord was found */        RecordOrderer.addNewSheetRecord(records, _mergedCellsTable);        if (log.check( POILogger.DEBUG ))            log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited");    }    private static final class RecordCloner implements RecordVisitor {        private final List _destList;        public RecordCloner(List destList) {            _destList = destList;        }        public void visitRecord(Record r) {            _destList.add(r.clone());        }    }    /**     * Clones the low level records of this sheet and returns the new sheet instance.     * This method is implemented by adding methods for deep cloning to all records that     * can be added to a sheet. The <b>Record</b> object does not implement cloneable.     * When adding a new record, implement a public clone method if and only if the record     * belongs to a sheet.     */    public Sheet cloneSheet() {        List clonedRecords = new ArrayList(this.records.size());        for (int i = 0; i < this.records.size(); i++) {            RecordBase rb = (RecordBase) this.records.get(i);            if (rb instanceof RecordAggregate) {                ((RecordAggregate) rb).visitContainedRecords(new RecordCloner(clonedRecords));                continue;            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?