writableworkbookimpl.java

来自「jexcelapi_2_4, JXL的API, JXL是JAVA读取EXCEL的」· Java 代码 · 共 1,039 行 · 第 1/2 页

JAVA
1,039
字号
/*********************************************************************
*
*      Copyright (C) 2002 Andrew Khan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/

package jxl.write.biff;

import java.util.Iterator;
import java.util.ArrayList;
import java.util.HashMap;
import java.io.OutputStream;
import java.io.IOException;

import common.Assert;

import jxl.Workbook;
import jxl.Sheet;
import jxl.Range;
import jxl.WorkbookSettings;
import jxl.write.WritableWorkbook;
import jxl.write.WritableSheet;
import jxl.write.WritableCell;
import jxl.biff.RangeImpl;
import jxl.biff.IntegerHelper;
import jxl.biff.Fonts;
import jxl.biff.FormattingRecords;
import jxl.biff.IndexMapping;
import jxl.biff.WorkbookMethods;
import jxl.read.biff.WorkbookParser;
import jxl.biff.formula.ExternalSheet;
import jxl.format.Colour;
import jxl.biff.drawing.DrawingGroup;
import jxl.biff.drawing.Drawing;

/**
 * A writable workbook
 */
public class WritableWorkbookImpl extends WritableWorkbook 
  implements ExternalSheet, WorkbookMethods
{
  /**
   * The list of formats available within this workbook
   */
  private FormattingRecords formatRecords;
  /**
   * The output file to write the workbook to
   */
  private File outputFile;
  /**
   * The list of sheets within this workbook
   */
  private ArrayList sheets;
  /**
   * The list of fonts available within this workbook
   */
  private Fonts fonts;
  /**
   * The list of external sheets, used by cell references in formulas
   */
  private ExternalSheetRecord externSheet;

  /**
   * The Mso Drawing Group
   */
  //  private MsoDrawingGroupRecord msoDrawingGroup;

  /**
   * The supbook records
   */
  private SupbookRecord[] supbooks;

  /**
   * The name records
   */
  private NameRecord[] names;

  /**
   * A lookup hash map of the name records
   */
  private HashMap nameRecords;

  /**
   * The shared strings used by this workbook
   */
  private SharedStrings sharedStrings;

  /**
   * Indicates whether or not the output stream should be closed.  This
   * depends on whether this Workbook was created with an output stream,
   * or a flat file (flat file closes the stream
   */
  private boolean closeStream;

  /**
   * The workbook protection flag
   */
  private boolean wbProtected;

  /**
   * The settings for the workbook
   */
  private WorkbookSettings settings;

  /**
   * The list of cells for the entire workbook which need to be updated 
   * following a row/column insert or remove
   */
  private ArrayList rcirCells;

  /**
   * The drawing group
   */
  private DrawingGroup drawingGroup;

  /**
   * 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(OutputStream os, boolean cs, WorkbookSettings ws)
    throws IOException
  {
    super();
    outputFile = new File(os, ws);
    sheets = new ArrayList();
    sharedStrings = new SharedStrings();
    nameRecords = new HashMap();
    closeStream = cs;
    wbProtected = false;
    settings = ws;
    rcirCells = new ArrayList();

    // Reset the statically declared styles.  Thanks to Brendan for this
    WritableWorkbook.ARIAL_10_PT.uninitialize();
    WritableWorkbook.HYPERLINK_FONT.uninitialize();
    WritableWorkbook.NORMAL_STYLE.uninitialize();
    WritableWorkbook.HYPERLINK_STYLE.uninitialize();
    DateRecord.defaultDateFormat.uninitialize();

    WritableFonts wf = new WritableFonts();
    fonts = wf;

    WritableFormattingRecords wfr = new WritableFormattingRecords(fonts);
    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(OutputStream os,
                              Workbook w,
                              boolean cs,
                              WorkbookSettings ws) throws IOException
  {
    super();
    WorkbookParser wp = (WorkbookParser) w;

    // Reset the statically declared styles.  Thanks to Brendan for this
    WritableWorkbook.ARIAL_10_PT.uninitialize();
    WritableWorkbook.HYPERLINK_FONT.uninitialize();
    WritableWorkbook.NORMAL_STYLE.uninitialize();
    WritableWorkbook.HYPERLINK_STYLE.uninitialize();
    DateRecord.defaultDateFormat.uninitialize();

    outputFile = new File(os, ws);
    closeStream = cs;
    sheets = new ArrayList();
    sharedStrings = new SharedStrings();
    nameRecords = new HashMap();
    fonts = wp.getFonts();
    formatRecords = wp.getFormattingRecords();
    wbProtected = false;
    settings = ws;
    rcirCells = new ArrayList();

    // Copy any external sheets
    if (wp.getExternalSheetRecord() != null)
    {
      externSheet = new ExternalSheetRecord(wp.getExternalSheetRecord());

      // Get the associated supbooks
      jxl.read.biff.SupbookRecord[] readsr = wp.getSupbookRecords();
      supbooks = new SupbookRecord[readsr.length];

      for (int i = 0; i < supbooks.length; i++)
      {
        supbooks[i] = new SupbookRecord(readsr[i]);
      }
    }

    // Copy any drawings
    /*
    if (wp.getMsoDrawingGroupRecord() != null)
    {
      msoDrawingGroup = new MsoDrawingGroupRecord
        (wp.getMsoDrawingGroupRecord());
    }
    */

    drawingGroup = wp.getDrawingGroup();

    // Copy any names
    if (!settings.getNamesDisabled())
    {
      jxl.read.biff.NameRecord[] na = wp.getNameRecords();
      names = new NameRecord[na.length];
      
      for (int i = 0; i < na.length; i++)
      {
        names[i] = new NameRecord(na[i], i);
        String name = names[i].getName();
        nameRecords.put(name, names[i]);
      }
    }
    
    copyWorkbook(w);
  }

  /**
   * Gets the sheets within this workbook.  Use of this method for
   * large worksheets can cause performance problems.
   * 
   * @return an array of the individual sheets
   */
  public WritableSheet[] getSheets()
  {
    WritableSheet[] sheetArray = new WritableSheet[getNumberOfSheets()];
    
    for (int i = 0 ; i < getNumberOfSheets() ; i++)
    {
      sheetArray[i] = getSheet(i);
    }
    return sheetArray;
  }

  /**
   * Interface method from WorkbookMethods - gets the specified 
   * sheet within this workbook
   *
   * @param index the zero based index of the required sheet
   * @return The sheet specified by the index
   */
  public Sheet getReadSheet(int index)
  {
    return getSheet(index);
  }

  /**
   * Gets the specified sheet within this workbook
   * 
   * @param index the zero based index of the reQuired sheet
   * @return The sheet specified by the index
   */
  public WritableSheet getSheet(int index)
  {
    return (WritableSheet) sheets.get(index);
  }

  /**
   * Gets the sheet with the specified name from within this workbook
   * 
   * @param name the sheet name
   * @return The sheet with the specified name, or null if it is not found
   */
  public WritableSheet getSheet(String name)
  {
    // Iterate through the boundsheet records
    boolean found = false;
    Iterator i = sheets.iterator();
    WritableSheet s = null;

    while (i.hasNext() && !found)
    {
      s = (WritableSheet) i.next();
      
      if (s.getName().equals(name))
      {
        found = true;
      }
    }

    return found ? s : null;
  }

  /**
   * Returns the number of sheets in this workbook
   * 
   * @return the number of sheets in this workbook
   */
  public int getNumberOfSheets()
  {
    return sheets.size();
  }

  /**
   * Closes this workbook, and frees makes any memory allocated available
   * for garbage collection
   * 
   * @exception IOException 
   */
  public void close() throws IOException
  {
    outputFile.close(closeStream);
  }

  /**
   * The internal method implementation for creating new sheets
   *
   * @param name
   * @param index
   * @param handleRefs flag indicating whether or not to handle external
   *                   sheet references
   * @return 
   */
  private WritableSheet createSheet(String name, int index, 
                                    boolean handleRefs)
  {
    WritableSheet w = new WritableSheetImpl(name, outputFile, 
                                            formatRecords, 
                                            sharedStrings,
                                            settings,
                                            this);

    int pos = index;

    if (index <= 0)
    {
      pos = 0;
      sheets.add(0, w);
    }
    else if (index > sheets.size())
    {
      pos = sheets.size();
      sheets.add(w);
    }
    else
    {
      sheets.add(index, w);
    }

    if (handleRefs && externSheet != null)
    {
      externSheet.sheetInserted(pos);
    }

    return w;
  }

  /**
   * Creates a new sheet within the workbook, at the specified position.
   * The new sheet is inserted at the specified position, or prepended/appended
   * to the list of sheets if the index specified is somehow inappropriate
   * 
   * @param name the name of the new sheet
   * @param index the index at which to add the sheet
   * @return the created sheet
   */
  public WritableSheet createSheet(String name, int index)
  {
    return createSheet(name, index, true);
  }

  /**
   * Removes a sheet from this workbook, the other sheets indices being
   * altered accordingly. If the sheet referenced by the index
   * does not exist, then no action is taken.
   * 
   * @param index the index of the sheet to remove
   */
  public void removeSheet(int index)
  {
    int pos = index;
    if (index <= 0)
    {
      pos = 0;
      sheets.remove(0);
    }
    else if (index >= sheets.size())
    {
      pos = sheets.size() - 1;
      sheets.remove(sheets.size() - 1);
    }
    else
    {
      sheets.remove(index);
    }

    if (externSheet != null)
    {
      externSheet.sheetRemoved(pos);
    }
  }

  /**
   * Moves the specified sheet within this workbook to another index
   * position.
   * 
   * @param fromIndex the zero based index of the reQuired sheet
   * @param toIndex the zero based index of the reQuired sheet
   * @return the sheet that has been moved
   */
  public WritableSheet moveSheet(int fromIndex, int toIndex)
  {
    // Handle dodgy index 
    fromIndex = Math.max(fromIndex, 0);
    fromIndex = Math.min(fromIndex, sheets.size() - 1);
    toIndex   = Math.max(toIndex, 0);
    toIndex   = Math.min(toIndex, sheets.size() - 1);

    WritableSheet sheet= (WritableSheet)sheets.remove(fromIndex);
    sheets.add(toIndex, sheet);
    
    return sheet;
  }

  /**
   * Writes out this sheet to the output file.  First it writes out
   * the standard workbook information required by excel, before calling
   * the write method on each sheet individually
   * 
   * @exception IOException 
   */
  public void write() throws IOException
  {
    // Check the merged records.  This has to be done before the
    // globals are written out because some more XF formats might be created
    WritableSheetImpl wsi = null;
    for (int i = 0; i < getNumberOfSheets(); i++)
    {
      wsi = (WritableSheetImpl) getSheet(i);
      wsi.checkMergedBorders();
    }

    // Rationalize all the XF and number formats
    if (!settings.getRationalizationDisabled())
    {
      rationalize();
    }

    // Write the workbook globals
    BOFRecord bof = new BOFRecord(BOFRecord.workbookGlobals);
    outputFile.write(bof);

    InterfaceHeaderRecord ihr = new InterfaceHeaderRecord();
    outputFile.write(ihr);

    MMSRecord mms = new MMSRecord(0,0);
    outputFile.write(mms);

    InterfaceEndRecord ier = new InterfaceEndRecord();
    outputFile.write(ier);

    WriteAccessRecord wr = new WriteAccessRecord();
    outputFile.write(wr);

    CodepageRecord cp = new CodepageRecord();
    outputFile.write(cp);

    DSFRecord dsf = new DSFRecord();
    outputFile.write(dsf);

    TabIdRecord tabid = new TabIdRecord(getNumberOfSheets());
    outputFile.write(tabid);

    FunctionGroupCountRecord fgcr = new FunctionGroupCountRecord();
    outputFile.write(fgcr);

    // do not support password protected workbooks
    WindowProtectRecord wpr = new WindowProtectRecord(false);
    outputFile.write(wpr);

    ProtectRecord pr = new ProtectRecord(wbProtected);
    outputFile.write(pr);

    PasswordRecord pw = new PasswordRecord(null);
    outputFile.write(pw);

    Prot4RevRecord p4r = new Prot4RevRecord(false);
    outputFile.write(p4r);

    Prot4RevPassRecord p4rp = new Prot4RevPassRecord();
    outputFile.write(p4rp);

    Window1Record w1r = new Window1Record();
    outputFile.write(w1r);

    BackupRecord bkr = new BackupRecord(false);
    outputFile.write(bkr);

    HideobjRecord ho = new HideobjRecord(false);
    outputFile.write(ho);
    
    NineteenFourRecord nf = new NineteenFourRecord(false);
    outputFile.write(nf);

⌨️ 快捷键说明

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