📄 workbook.java
字号:
/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2003 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache POI" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache POI", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * <http://www.apache.org/>. */package org.apache.poi.hssf.model;import org.apache.poi.hssf.record.*;import org.apache.poi.hssf.util.HSSFColor;import org.apache.poi.hssf.util.SheetReferences;import org.apache.poi.util.POILogFactory;import org.apache.poi.util.POILogger;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Locale;/** * Low level model implementation of a Workbook. Provides creational methods * for settings and objects contained in the workbook object. * <P> * This file contains the low level binary records starting at the workbook's BOF and * ending with the workbook's EOF. Use HSSFWorkbook 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. * * * @author Shawn Laubach (slaubach at apache dot org) (Data Formats) * @author Andrew C. Oliver (acoliver at apache dot org) * @author Glen Stampoultzis (glens at apache.org) * @author Sergei Kozello (sergeikozello at mail.ru) * @author Luc Girardin (luc dot girardin at macrofocus dot com) * @author Dan Sherman (dsherman at isisph.com) * @author Brian Sanders (bsanders at risklabs dot com) - custom palette * @see org.apache.poi.hssf.usermodel.HSSFWorkbook * @version 1.0-pre */public class Workbook implements Model { private static final int DEBUG = POILogger.DEBUG;// public static Workbook currentBook = null; /** * constant used to set the "codepage" wherever "codepage" is set in records * (which is duplciated in more than one record) */ private final static short CODEPAGE = ( short ) 0x4b0; /** * this contains the Worksheet record objects */ protected WorkbookRecordList records = new WorkbookRecordList(); /** * this contains a reference to the SSTRecord so that new stings can be added * to it. */ protected SSTRecord sst = null; /** * Holds the Extern Sheet with references to bound sheets */ protected ExternSheetRecord externSheet= null; /** * holds the "boundsheet" records (aka bundlesheet) so that they can have their * reference to their "BOF" marker */ protected ArrayList boundsheets = new ArrayList(); protected ArrayList formats = new ArrayList(); protected ArrayList names = new ArrayList(); protected int numxfs = 0; // hold the number of extended format records protected int numfonts = 0; // hold the number of font records private short maxformatid = -1; // holds the max format id private boolean uses1904datewindowing = false; // whether 1904 date windowing is being used private static POILogger log = POILogFactory.getLogger(Workbook.class); /** * Creates new Workbook with no intitialization --useless right now * @see #createWorkbook(List) */ public Workbook() { } /** * read support for low level * API. Pass in an array of Record objects, A Workbook * object is constructed and passed back with all of its initialization set * to the passed in records and references to those records held. Unlike Sheet * workbook does not use an offset (its assumed to be 0) since its first in a file. * If you need an offset then construct a new array with a 0 offset or write your * own ;-p. * * @param recs an array of Record objects * @return Workbook object */ public static Workbook createWorkbook(List recs) { log.log(DEBUG, "Workbook (readfile) created with reclen=", new Integer(recs.size())); Workbook retval = new Workbook(); ArrayList records = new ArrayList(recs.size() / 3); for (int k = 0; k < recs.size(); k++) { Record rec = ( Record ) recs.get(k); if (rec.getSid() == EOFRecord.sid) { records.add(rec); log.log(DEBUG, "found workbook eof record at " + k); break; } switch (rec.getSid()) { case BoundSheetRecord.sid : log.log(DEBUG, "found boundsheet record at " + k); retval.boundsheets.add(rec); retval.records.setBspos( k ); break; case SSTRecord.sid : log.log(DEBUG, "found sst record at " + k); retval.sst = ( SSTRecord ) rec; break; case FontRecord.sid : log.log(DEBUG, "found font record at " + k); retval.records.setFontpos( k ); retval.numfonts++; break; case ExtendedFormatRecord.sid : log.log(DEBUG, "found XF record at " + k); retval.records.setXfpos( k ); retval.numxfs++; break; case TabIdRecord.sid : log.log(DEBUG, "found tabid record at " + k); retval.records.setTabpos( k ); break; case ProtectRecord.sid : log.log(DEBUG, "found protect record at " + k); retval.records.setProtpos( k ); break; case BackupRecord.sid : log.log(DEBUG, "found backup record at " + k); retval.records.setBackuppos( k ); break; case ExternSheetRecord.sid : log.log(DEBUG, "found extern sheet record at " + k); retval.externSheet = ( ExternSheetRecord ) rec; break; case NameRecord.sid : log.log(DEBUG, "found name record at " + k); retval.names.add(rec);// retval.records.namepos = k; break; case SupBookRecord.sid : log.log(DEBUG, "found SupBook record at " + k);// retval.records.supbookpos = k; break; case FormatRecord.sid : log.log(DEBUG, "found format record at " + k); retval.formats.add(rec); retval.maxformatid = retval.maxformatid >= ((FormatRecord)rec).getIndexCode() ? retval.maxformatid : ((FormatRecord)rec).getIndexCode(); break; case DateWindow1904Record.sid : log.log(DEBUG, "found datewindow1904 record at " + k); retval.uses1904datewindowing = ((DateWindow1904Record)rec).getWindowing() == 1; break; case PaletteRecord.sid: log.log(DEBUG, "found palette record at " + k); retval.records.setPalettepos( k ); default : } records.add(rec); } //What if we dont have any ranges and supbooks// if (retval.records.supbookpos == 0) {// retval.records.supbookpos = retval.records.bspos + 1;// retval.records.namepos = retval.records.supbookpos + 1;// } retval.records.setRecords(records); log.log(DEBUG, "exit create workbook from existing file function"); return retval; } /** * Creates an empty workbook object with three blank sheets and all the empty * fields. Use this to create a workbook from scratch. */ public static Workbook createWorkbook() { log.log( DEBUG, "creating new workbook from scratch" ); Workbook retval = new Workbook(); ArrayList records = new ArrayList( 30 ); ArrayList formats = new ArrayList( 8 ); records.add( retval.createBOF() ); records.add( retval.createInterfaceHdr() ); records.add( retval.createMMS() ); records.add( retval.createInterfaceEnd() ); records.add( retval.createWriteAccess() ); records.add( retval.createCodepage() ); records.add( retval.createDSF() ); records.add( retval.createTabId() ); retval.records.setTabpos( records.size() - 1 ); records.add( retval.createFnGroupCount() ); records.add( retval.createWindowProtect() ); records.add( retval.createProtect() ); retval.records.setProtpos( records.size() - 1 ); records.add( retval.createPassword() ); records.add( retval.createProtectionRev4() ); records.add( retval.createPasswordRev4() ); records.add( retval.createWindowOne() ); records.add( retval.createBackup() ); retval.records.setBackuppos( records.size() - 1 ); records.add( retval.createHideObj() ); records.add( retval.createDateWindow1904() ); records.add( retval.createPrecision() ); records.add( retval.createRefreshAll() ); records.add( retval.createBookBool() ); records.add( retval.createFont() ); records.add( retval.createFont() ); records.add( retval.createFont() ); records.add( retval.createFont() ); retval.records.setFontpos( records.size() - 1 ); // last font record postion retval.numfonts = 4; // set up format records for ( int i = 0; i <= 7; i++ ) { Record rec; rec = retval.createFormat( i ); retval.maxformatid = retval.maxformatid >= ( (FormatRecord) rec ).getIndexCode() ? retval.maxformatid : ( (FormatRecord) rec ).getIndexCode(); formats.add( rec ); records.add( rec ); } retval.formats = formats; for ( int k = 0; k < 21; k++ ) { records.add( retval.createExtendedFormat( k ) ); retval.numxfs++; } retval.records.setXfpos( records.size() - 1 ); for ( int k = 0; k < 6; k++ ) { records.add( retval.createStyle( k ) ); } records.add( retval.createUseSelFS() ); for ( int k = 0; k < 1; k++ ) { // now just do 1 BoundSheetRecord bsr = (BoundSheetRecord) retval.createBoundSheet( k ); records.add( bsr ); retval.boundsheets.add( bsr ); retval.records.setBspos( records.size() - 1 ); }// retval.records.supbookpos = retval.records.bspos + 1;// retval.records.namepos = retval.records.supbookpos + 2; records.add( retval.createCountry() ); retval.sst = (SSTRecord) retval.createSST(); records.add( retval.sst ); records.add( retval.createExtendedSST() ); records.add( retval.createEOF() ); retval.records.setRecords(records); log.log( DEBUG, "exit create new workbook from scratch" ); return retval; } /**Retrieves the Builtin NameRecord that matches the name and index * There shouldn't be too many names to make the sequential search too slow * @param name byte representation of the builtin name to match * @param sheetIndex Index to match * @return null if no builtin NameRecord matches */ public NameRecord getSpecificBuiltinRecord(byte name, int sheetIndex) { Iterator iterator = names.iterator(); while (iterator.hasNext()) { NameRecord record = ( NameRecord ) iterator.next(); //print areas are one based if (record.getBuiltInName() == name && record.getIndexToSheet() == sheetIndex) { return record; } } return null; } /**
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -