First go at performance refactor. Most unit tests working, some have to be removed to compile (need to get things up to spec as far as new patches)

PR:
Obtained from:
Submitted by:
Reviewed by:


git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/branches/performance-branch@352982 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andrew C. Oliver 2003-01-05 19:04:40 +00:00
parent 888bdbf619
commit fea5acbbe9
11 changed files with 1050 additions and 1056 deletions

View File

@ -139,8 +139,8 @@ public class HSSFChart
sheet.insertChartRecords( records );
workbook.insertChartRecord();
//sheet.insertChartRecords( records );
//workbook.insertChartRecord();
}
private EOFRecord createEOFRecord()

View File

@ -61,6 +61,7 @@ import java.util.Iterator;
import org.apache.poi.hssf
.record.*; // normally I don't do this, buy we literally mean ALL
import org.apache.poi.hssf.model.Model;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.util.*;
import org.apache.poi.hssf.record
@ -79,16 +80,17 @@ import org.apache.poi.hssf.record
* <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, and PrintSetup
* @author Shawn Laubach (laubach at acm.org) Just Gridlines, Headers, Footers, and PrintSetup
* @author Jason Height (jheight at chariot dot net dot au) Clone support
* @author Brian Sanders (kestrel at burdell dot org) Active Cell support
*
* @see org.apache.poi.hssf.model.Workbook
* @see org.apache.poi.hssf.usermodel.HSSFSheet
* @version 1.0-pre
*/
public class Sheet implements Model
public class Sheet
extends java.lang.Object
implements Model
{
public static final short LeftMargin = 0;
public static final short RightMargin = 1;
@ -109,7 +111,6 @@ public class Sheet implements Model
protected FooterRecord footer = null;
protected PrintGridlinesRecord printGridlines = null;
protected MergeCellsRecord merged = null;
protected SelectionRecord selection = null;
protected int mergedloc = 0;
private static POILogger log = POILogFactory.getLogger(Sheet.class);
private ArrayList columnSizes = null; // holds column info
@ -196,7 +197,7 @@ public class Sheet implements Model
{
retval.columnSizes = new ArrayList();
}
retval.columnSizes.add(rec);
retval.columnSizes.add(( ColumnInfoRecord ) rec);
}
else if (rec.getSid() == DefaultColWidthRecord.sid)
{
@ -254,10 +255,6 @@ public class Sheet implements Model
{
retval.printSetup = (PrintSetupRecord) rec;
}
else if ( rec.getSid() == SelectionRecord.sid )
{
retval.selection = (SelectionRecord) rec;
}
if (rec != null)
{
@ -382,9 +379,7 @@ public class Sheet implements Model
records.add(retval.dims);
records.add(retval.createWindowTwo());
retval.setLoc(records.size() - 1);
retval.selection =
(SelectionRecord) retval.createSelection();
records.add(retval.selection);
records.add(retval.createSelection());
records.add(retval.createEOF());
retval.records = records;
log.log(log.DEBUG, "Sheet createsheet from scratch exit");
@ -439,10 +434,9 @@ public class Sheet implements Model
}
public int getNumMergedRegions()
{
return merged!=null ? merged.getNumAreas() : 0;
}
{
return merged.getNumAreas();
}
/**
* This is basically a kludge to deal with the now obsolete Label records. If
@ -1047,6 +1041,7 @@ public class Sheet implements Model
setLoc(getDimsLoc());
rows.removeRow(row);
cells.removeRow(row.getRowNumber());
/*
* for (int k = loc; k < records.size(); k++)
@ -1118,6 +1113,10 @@ public class Sheet implements Model
*/
}
public CellValueRecordInterface getValueRecord(int row, short col) {
return cells.getCell(row, col);
}
/**
* get the NEXT RowRecord or CellValueRecord(from LOC). The first record that
* is a Row record or CellValueRecord(starting at LOC) will be returned.
@ -1223,6 +1222,9 @@ public class Sheet implements Model
public RowRecord getRow(int rownum)
{
log.log(log.DEBUG, "getNextRow loc= " + loc);
if (rows == null) {
return null;
}
return rows.getRow(rownum);
/*
@ -1247,6 +1249,15 @@ public class Sheet implements Model
// return null;
}
public Iterator rowRecordIterator() {
return rows.getIterator();
}
public Iterator rowCellIterator(int row) {
return this.cells.getRowCellIterator(row);
}
/**
* Not currently used method to calculate and add dbcell records
*
@ -1325,6 +1336,15 @@ public class Sheet implements Model
}
}
public int getFirstRow() {
return rows.getFirstRowNum();
}
public int getLastRow() {
return rows.getLastRowNum();
}
/** not currently used */
private DBCellRecord createDBCell(int offset, IntList rowoffsets,
@ -1943,66 +1963,6 @@ public class Sheet implements Model
retval.setNumRefs(( short ) 0x0);
return retval;
}
/**
* Returns the active row
*
* @see org.apache.poi.hssf.record.SelectionRecord
* @return row the active row index
*/
public int getActiveCellRow()
{
if (selection == null)
{
return 0;
}
return selection.getActiveCellRow();
}
/**
* Sets the active row
*
* @param row the row index
* @see org.apache.poi.hssf.record.SelectionRecord
*/
public void setActiveCellRow(int row)
{
//shouldn't have a sheet w/o a SelectionRecord, but best to guard anyway
if (selection != null)
{
selection.setActiveCellRow(row);
}
}
/**
* Returns the active column
*
* @see org.apache.poi.hssf.record.SelectionRecord
* @return row the active column index
*/
public short getActiveCellCol()
{
if (selection == null)
{
return (short) 0;
}
return selection.getActiveCellCol();
}
/**
* Sets the active column
*
* @param col the column index
* @see org.apache.poi.hssf.record.SelectionRecord
*/
public void setActiveCellCol(short col)
{
//shouldn't have a sheet w/o a SelectionRecord, but best to guard anyway
if (selection != null)
{
selection.setActiveCellCol(col);
}
}
protected Record createMergedCells()
{
@ -2024,6 +1984,32 @@ public class Sheet implements Model
return new EOFRecord();
}
public void setLastColForRow(int row, short col) {
this.getRow(row).setLastCol(col);
}
public void setFirstColForRow(int row, short col) {
this.getRow(row).setFirstCol(col);
}
public short getLastColForRow(int row) {
return this.getRow(row).getLastCol();
}
public short getFirstColForRow(int row) {
return this.getRow(row).getFirstCol();
}
public void setCellValue(int row, short col, double val) {
this.cells.setValue(row, col, val);
}
public void setCellStyle(int row, short col, short xf) {
this.cells.setStyle(row, col, xf);
}
/**
* get the location of the DimensionsRecord (which is the last record before the value section)
* @return location in the array of records of the DimensionsRecord
@ -2056,6 +2042,7 @@ public class Sheet implements Model
{
retval += (( Record ) records.get(k)).getRecordSize();
}
return retval;
}
@ -2091,27 +2078,8 @@ public class Sheet implements Model
return null;
}
/**
* Finds the first occurance of a record matching a particular sid and
* returns it's position.
* @param sid the sid to search for
* @return the record position of the matching record or -1 if no match
* is made.
*/
public int findFirstRecordLocBySid( short sid )
{
int index = 0;
for (Iterator iterator = records.iterator(); iterator.hasNext(); )
{
Record record = ( Record ) iterator.next();
if (record.getSid() == sid)
{
return index;
}
index++;
}
return -1;
public int getPhysicalNumberOfRows() {
return rows.getPhysicalNumberOfRows();
}
/**
@ -2129,7 +2097,7 @@ public class Sheet implements Model
*/
public void setHeader (HeaderRecord newHeader)
{
header = newHeader;
header = newHeader;
}
/**
@ -2138,7 +2106,7 @@ public class Sheet implements Model
*/
public FooterRecord getFooter ()
{
return footer;
return footer;
}
/**
@ -2147,7 +2115,7 @@ public class Sheet implements Model
*/
public void setFooter (FooterRecord newFooter)
{
footer = newFooter;
footer = newFooter;
}
/**
@ -2156,7 +2124,7 @@ public class Sheet implements Model
*/
public PrintSetupRecord getPrintSetup ()
{
return printSetup;
return printSetup;
}
/**
@ -2165,7 +2133,7 @@ public class Sheet implements Model
*/
public void setPrintSetup (PrintSetupRecord newPrintSetup)
{
printSetup = newPrintSetup;
printSetup = newPrintSetup;
}
/**
@ -2174,7 +2142,7 @@ public class Sheet implements Model
*/
public PrintGridlinesRecord getPrintGridlines ()
{
return printGridlines;
return printGridlines;
}
/**
@ -2183,7 +2151,7 @@ public class Sheet implements Model
*/
public void setPrintGridlines (PrintGridlinesRecord newPrintGridlines)
{
printGridlines = newPrintGridlines;
printGridlines = newPrintGridlines;
}
/**
@ -2191,43 +2159,43 @@ public class Sheet implements Model
* @param sel True to select the sheet, false otherwise.
*/
public void setSelected(boolean sel) {
WindowTwoRecord windowTwo = (WindowTwoRecord) findFirstRecordBySid(WindowTwoRecord.sid);
windowTwo.setSelected(sel);
WindowTwoRecord windowTwo = (WindowTwoRecord) findFirstRecordBySid(WindowTwoRecord.sid);
windowTwo.setSelected(sel);
}
/**
* Gets the size of the margin in inches.
* @param margin which margin to get
* @return the size of the margin
*/
public double getMargin(short margin) {
Margin m;
switch ( margin )
{
case LeftMargin:
m = (Margin) findFirstRecordBySid( LeftMarginRecord.sid );
if ( m == null )
return .75;
break;
case RightMargin:
m = (Margin) findFirstRecordBySid( RightMarginRecord.sid );
if ( m == null )
return .75;
break;
case TopMargin:
m = (Margin) findFirstRecordBySid( TopMarginRecord.sid );
if ( m == null )
return 1.0;
break;
case BottomMargin:
m = (Margin) findFirstRecordBySid( BottomMarginRecord.sid );
if ( m == null )
return 1.0;
break;
default :
throw new RuntimeException( "Unknown margin constant: " + margin );
}
return m.getMargin();
Margin m;
switch (margin) {
case LeftMargin :
m = (Margin)findFirstRecordBySid(LeftMarginRecord.sid);
if (m == null)
return .75;
break;
case RightMargin :
m = (Margin)findFirstRecordBySid(RightMarginRecord.sid);
if (m == null)
return .75;
break;
case TopMargin :
m = (Margin)findFirstRecordBySid(TopMarginRecord.sid);
if (m == null)
return 1.0;
break;
case BottomMargin :
m = (Margin)findFirstRecordBySid(BottomMarginRecord.sid);
if (m == null)
return 1.0;
break;
default : throw new RuntimeException("Unknown margin constant: " + margin);
}
return m.getMargin();
}
/**
@ -2236,45 +2204,39 @@ public class Sheet implements Model
* @param size the size of the margin
*/
public void setMargin(short margin, double size) {
Margin m;
switch ( margin )
{
case LeftMargin:
m = (Margin) findFirstRecordBySid( LeftMarginRecord.sid );
if ( m == null )
{
m = new LeftMarginRecord();
records.add( getDimsLoc() + 1, m );
}
break;
case RightMargin:
m = (Margin) findFirstRecordBySid( RightMarginRecord.sid );
if ( m == null )
{
m = new RightMarginRecord();
records.add( getDimsLoc() + 1, m );
}
break;
case TopMargin:
m = (Margin) findFirstRecordBySid( TopMarginRecord.sid );
if ( m == null )
{
m = new TopMarginRecord();
records.add( getDimsLoc() + 1, m );
}
break;
case BottomMargin:
m = (Margin) findFirstRecordBySid( BottomMarginRecord.sid );
if ( m == null )
{
m = new BottomMarginRecord();
records.add( getDimsLoc() + 1, m );
}
break;
default :
throw new RuntimeException( "Unknown margin constant: " + margin );
}
m.setMargin( size );
Margin m;
switch (margin) {
case LeftMargin :
m = (Margin)findFirstRecordBySid(LeftMarginRecord.sid);
if (m == null) {
m = new LeftMarginRecord();
records.add(getDimsLoc() + 1, (Record)m);
}
break;
case RightMargin :
m = (Margin)findFirstRecordBySid(RightMarginRecord.sid);
if (m == null) {
m = new RightMarginRecord();
records.add(getDimsLoc() + 1, (Record)m);
}
break;
case TopMargin :
m = (Margin)findFirstRecordBySid(TopMarginRecord.sid);
if (m == null) {
m = new TopMarginRecord();
records.add(getDimsLoc() + 1, (Record)m);
}
break;
case BottomMargin :
m = (Margin)findFirstRecordBySid(BottomMarginRecord.sid);
if (m == null) {
m = new BottomMarginRecord();
records.add(getDimsLoc() + 1, (Record)m);
}
break;
default : throw new RuntimeException("Unknown margin constant: " + margin);
}
m.setMargin(size);
}
public int getEofLoc()

View File

@ -55,18 +55,24 @@
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.io.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Iterator;
import java.util.Locale;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.hssf.model.Model;
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.util.SheetReferences;
import org.apache.poi.hssf.util.HSSFColor;
/**
* Workbook
* Low level model implementation of a Workbook. Provides creational methods
* for settings and objects contained in the workbook object.
* <P>
@ -79,17 +85,10 @@ import java.util.Locale;
* Kit (Microsoft Press) and the documentation at http://sc.openoffice.org/excelfileformat.pdf
* before even attempting to use this.
*
* @todo Need a good way of keeping track of bookmarks in a list. Currently
* we are manually incrementing multiple indexes whenever new records
* are added. This mechanism makes it very easy to introduce bugs.
*
* @author Shawn Laubach (slaubach at apache dot org) (Data Formats)
* @author Shawn Laubach (shawnlaubach at cox.net) (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
*/
@ -137,21 +136,29 @@ public class Workbook implements Model {
protected ArrayList names = new ArrayList();
protected int protpos = 0; // holds the position of the protect record.
protected int bspos = 0; // holds the position of the last bound sheet.
protected int tabpos = 0; // holds the position of the tabid record
protected int fontpos = 0; // hold the position of the last font record
protected int numfonts = 0; // hold the number of font records
protected int xfpos = 0; // hold the position of the last extended font record
protected int numxfs = 0; // hold the number of extended format records
private int backuppos = 0; // holds the position of the backup record.
private int namepos = 0; // holds the position of last name record
private int supbookpos = 0; // holds the position of sup book
private int palettepos = 0; // hold the position of the palette, if applicable
private short maxformatid = -1; // holds the max format id
private boolean uses1904datewindowing = false; // whether 1904 date windowing is being used
protected int bspos =
0; // holds the position of the last bound sheet.
protected int tabpos =
0; // holds the position of the tabid record
protected int fontpos =
0; // hold the position of the last font record
protected int numfonts =
0; // hold the number of font records
protected int xfpos =
0; // hold the position of the last extended font record
protected int numxfs =
0; // hold the number of extended format records
private int backuppos =
0; // holds the position of the backup record.
private int namepos =
0; // holds the position of last name record
private int supbookpos =
0; // holds the position of sup book
private short maxformatid =
-1; // holds the max format id
private static POILogger log = POILogFactory.getLogger(Workbook.class);
private static POILogger log =
POILogFactory.getLogger(Workbook.class);
/**
* Creates new Workbook with no intitialization --useless right now
@ -218,11 +225,6 @@ public class Workbook implements Model {
retval.tabpos = k;
break;
case ProtectRecord.sid :
log.log(DEBUG, "found protect record at " + k);
retval.protpos = k;
break;
case BackupRecord.sid :
log.log(DEBUG, "found backup record at " + k);
retval.backuppos = k;
@ -247,13 +249,7 @@ public class Workbook implements Model {
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.palettepos = k;
default :
}
records.add(rec);
@ -273,84 +269,79 @@ public class Workbook implements Model {
* 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() );
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.tabpos = records.size() - 1;
records.add( retval.createFnGroupCount() );
records.add( retval.createWindowProtect() );
records.add( retval.createProtect() );
retval.protpos = records.size() - 1;
records.add( retval.createPassword() );
records.add( retval.createProtectionRev4() );
records.add( retval.createPasswordRev4() );
records.add( retval.createWindowOne() );
records.add( retval.createBackup() );
records.add(retval.createFnGroupCount());
records.add(retval.createWindowProtect());
records.add(retval.createProtect());
records.add(retval.createPassword());
records.add(retval.createProtectionRev4());
records.add(retval.createPasswordRev4());
records.add(retval.createWindowOne());
records.add(retval.createBackup());
retval.backuppos = 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.fontpos = records.size() - 1; // last font record postion
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.fontpos = 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 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 ) );
for (int k = 0; k < 21; k++) {
records.add(retval.createExtendedFormat(k));
retval.numxfs++;
}
retval.xfpos = records.size() - 1;
for ( int k = 0; k < 6; k++ )
{
records.add( retval.createStyle( k ) );
for (int k = 0; k < 6; k++) {
records.add(retval.createStyle(k));
}
retval.palettepos = records.size();
records.add( retval.createUseSelFS() );
for ( int k = 0; k < 1; k++ )
{ // now just do 1
records.add(retval.createUseSelFS());
for (int k = 0; k < 1; k++) { // now just do 1
BoundSheetRecord bsr =
(BoundSheetRecord) retval.createBoundSheet( k );
( BoundSheetRecord ) retval.createBoundSheet(k);
records.add( bsr );
retval.boundsheets.add( bsr );
records.add(bsr);
retval.boundsheets.add(bsr);
retval.bspos = records.size() - 1;
}
records.add( retval.createCountry() );
retval.sst = (SSTRecord) retval.createSST();
records.add( retval.sst );
records.add( retval.createExtendedSST() );
records.add(retval.createCountry());
retval.sst = ( SSTRecord ) retval.createSST();
records.add(retval.sst);
records.add(retval.createExtendedSST());
records.add( retval.createEOF() );
// TODO
records.add(retval.createEOF());
retval.records = records;
log.log( DEBUG, "exit create new workbook from scratch" );
log.log(DEBUG, "exit create new workbook from scratch");
return retval;
}
@ -523,6 +514,7 @@ public class Workbook implements Model {
* make the tabid record look like the current situation.
*
*/
private void fixTabIdRecord() {
TabIdRecord tir = ( TabIdRecord ) records.get(tabpos);
short[] tia = new short[ boundsheets.size() ];
@ -583,7 +575,6 @@ public class Workbook implements Model {
ExtendedFormatRecord xf = createExtendedFormat();
++xfpos;
++palettepos;
++bspos;
records.add(xfpos, xf);
numxfs++;
@ -680,11 +671,8 @@ public class Workbook implements Model {
// byte[] rec = (( byte [] ) bytes.get(k));
// System.arraycopy(rec, 0, retval, pos, rec.length);
Record record = (( Record ) records.get(k));
// Let's skip RECALCID records, as they are only use for optimization
if(record.getSid() != RecalcIdRecord.sid || ((RecalcIdRecord)record).isNeeded()) {
pos += record.serialize(pos, retval); // rec.length;
}
pos += (( Record ) records.get(k)).serialize(pos,
retval); // rec.length;
}
log.log(DEBUG, "Exiting serialize workbook");
return retval;
@ -717,11 +705,8 @@ public class Workbook implements Model {
// byte[] rec = (( byte [] ) bytes.get(k));
// System.arraycopy(rec, 0, data, offset + pos, rec.length);
Record record = (( Record ) records.get(k));
// Let's skip RECALCID records, as they are only use for optimization
if(record.getSid() != RecalcIdRecord.sid || ((RecalcIdRecord)record).isNeeded()) {
pos += record.serialize(pos + offset, data); // rec.length;
}
pos += (( Record ) records.get(k)).serialize(pos + offset,
data); // rec.length;
}
log.log(DEBUG, "Exiting serialize workbook");
return pos;
@ -731,11 +716,7 @@ public class Workbook implements Model {
int retval = 0;
for (int k = 0; k < records.size(); k++) {
Record record = (( Record ) records.get(k));
// Let's skip RECALCID records, as they are only use for optimization
if(record.getSid() != RecalcIdRecord.sid || ((RecalcIdRecord)record).isNeeded()) {
retval += record.getRecordSize();
}
retval += (( Record ) records.get(k)).getRecordSize();
}
return retval;
}
@ -1572,16 +1553,6 @@ public class Workbook implements Model {
return retval;
}
/**
* Creates a palette record initialized to the default palette
* @return a PaletteRecord instance populated with the default colors
* @see org.apache.poi.hssf.record.PaletteRecord
*/
protected PaletteRecord createPalette()
{
return new PaletteRecord(PaletteRecord.sid);
}
/**
* Creates the UseSelFS object with the use natural language flag set to 0 (false)
* @return record containing a UseSelFSRecord
@ -1877,30 +1848,27 @@ public class Workbook implements Model {
* @see org.apache.poi.hssf.record.FormatRecord
* @see org.apache.poi.hssf.record.Record
*/
public short createFormat( String format )
{
++xfpos; //These are to ensure that positions are updated properly
++palettepos;
++bspos;
FormatRecord rec = new FormatRecord();
maxformatid = maxformatid >= (short) 0xa4 ? (short) ( maxformatid + 1 ) : (short) 0xa4; //Starting value from M$ empiracle study.
rec.setIndexCode( maxformatid );
rec.setFormatStringLength( (byte) format.length() );
rec.setFormatString( format );
public short createFormat(String format) {
FormatRecord rec = new FormatRecord();
maxformatid = maxformatid >= (short)0xa4 ? (short)(maxformatid + 1) : (short)0xa4; //Starting value from M$ empiracle study.
rec.setIndexCode(maxformatid);
rec.setFormatStringLength((byte)format.length());
rec.setFormatString(format);
int pos = 0;
while ( pos < records.size() && ( (Record) records.get( pos ) ).getSid() != FormatRecord.sid )
pos++;
pos += formats.size();
formats.add( rec );
records.add( pos, rec );
return maxformatid;
}
int pos = 0;
while (pos < records.size() && ((Record)records.get(pos)).getSid() != FormatRecord.sid)
pos++;
pos += formats.size();
formats.add(rec);
records.add(pos, rec);
return maxformatid;
}
/**
* Returns the first occurance of a record matching a particular sid.
*/
public Record findFirstRecordBySid(short sid) {
for (Iterator iterator = records.iterator(); iterator.hasNext(); ) {
Record record = ( Record ) iterator.next();
@ -1912,34 +1880,13 @@ public class Workbook implements Model {
return null;
}
/**
* Returns the index of a record matching a particular sid.
* @param sid The sid of the record to match
* @return The index of -1 if no match made.
*/
public int findFirstRecordLocBySid(short sid) {
int index = 0;
for (Iterator iterator = records.iterator(); iterator.hasNext(); ) {
Record record = ( Record ) iterator.next();
if (record.getSid() == sid) {
return index;
}
index ++;
}
return -1;
}
/**
* Returns the next occurance of a record matching a particular sid.
*/
public Record findNextRecordBySid(short sid, int pos) {
Iterator iterator = records.iterator();
for (;pos > 0 && iterator.hasNext(); iterator.next(),pos--)
{
// intentionally empty
}
while (iterator.hasNext()) {
for (;pos > 0 && iterator.hasNext(); iterator.next(),pos--);
while (iterator.hasNext()) {
Record record = ( Record ) iterator.next();
if (record.getSid() == sid) {
@ -1953,46 +1900,4 @@ public class Workbook implements Model {
{
return records;
}
// public void insertChartRecords( List chartRecords )
// {
// backuppos += chartRecords.size();
// fontpos += chartRecords.size();
// palettepos += chartRecords.size();
// bspos += chartRecords.size();
// xfpos += chartRecords.size();
//
// records.addAll(protpos, chartRecords);
// }
/**
* Whether date windowing is based on 1/2/1904 or 1/1/1900.
* Some versions of Excel (Mac) can save workbooks using 1904 date windowing.
*
* @return true if using 1904 date windowing
*/
public boolean isUsing1904DateWindowing() {
return uses1904datewindowing;
}
/**
* Returns the custom palette in use for this workbook; if a custom palette record
* does not exist, then it is created.
*/
public PaletteRecord getCustomPalette()
{
PaletteRecord palette;
Record rec = (Record) records.get(palettepos);
if (rec instanceof PaletteRecord)
{
palette = (PaletteRecord) rec;
}
else
{
palette = createPalette();
records.add(palettepos, palette);
++bspos;
}
return palette;
}
}

View File

@ -145,7 +145,7 @@ public class FormulaRecord
field_6_zero = LittleEndian.getInt(data, 16 + offset);
field_7_expression_len = LittleEndian.getShort(data, 20 + offset);
field_8_parsed_expr = getParsedExpressionTokens(data, size,
22 + offset);
offset);
} catch (java.lang.UnsupportedOperationException uoe) {
field_8_parsed_expr = null;
@ -164,7 +164,7 @@ public class FormulaRecord
int offset)
{
Stack stack = new Stack();
int pos = offset;
int pos = 22 + offset;
while (pos < size)
{
@ -329,7 +329,15 @@ public class FormulaRecord
public List getParsedExpression()
{
return field_8_parsed_expr;
return ( List ) field_8_parsed_expr;
}
/**
* sets the stack with a list
*/
public void setParsedExpression(List ptgs) {
field_8_parsed_expr = new Stack();
field_8_parsed_expr.addAll(ptgs);
}
/**
@ -545,23 +553,20 @@ public class FormulaRecord
.append("\n");
buffer.append(" .expressionlength= ").append(getExpressionLength())
.append("\n");
if (field_8_parsed_expr != null) {
buffer.append(" .numptgsinarray = ").append(field_8_parsed_expr.size())
.append("\n");
buffer.append(" .numptgsinarray = ").append(field_8_parsed_expr.size())
.append("\n");
for (int k = 0; k < field_8_parsed_expr.size(); k++ ) {
for (int k = 0; k < field_8_parsed_expr.size(); k++ ) {
/* buffer.append("formula ").append(k).append(" ")
.append(((Ptg)field_8_parsed_expr.get(k)).toFormulaString());*/
buffer.append("Formula ")
.append(k)
.append("=")
.append(field_8_parsed_expr.get(k).toString())
.append("\n")
.append(((Ptg)field_8_parsed_expr.get(k)).toDebugString())
.append("\n");
}
.append(((Ptg)field_8_parsed_expr.get(k)).toFormulaString());*/
buffer.append("Formula ")
.append(k)
.append("=")
.append(((Ptg)field_8_parsed_expr.get(k)).toString())
.append("\n")
.append(((Ptg)field_8_parsed_expr.get(k)).toDebugString())
.append("\n");
}

View File

@ -75,10 +75,12 @@ public class RowRecordsAggregate
{
int firstrow = -1;
int lastrow = -1;
boolean firstdirty = false;
boolean lastdirty = false;
Map records = null;
int size = 0;
/** Creates a new instance of ValueRecordsAggregate */
/** Creates a new instance of RowRecordsAggregate */
public RowRecordsAggregate()
{
@ -107,6 +109,12 @@ public class RowRecordsAggregate
size -= row.getRecordSize();
// Integer integer = new Integer(row.getRowNumber());
if (lastrow == row.getRowNumber()) {
lastdirty = true;
}
if (firstrow == row.getRowNumber()) {
firstdirty = true;
}
records.remove(row);
}
@ -127,11 +135,17 @@ public class RowRecordsAggregate
public int getFirstRowNum()
{
if (firstdirty) {
firstrow = findFirstRow();
}
return firstrow;
}
public int getLastRowNum()
{
if (lastdirty) {
lastrow = findLastRow();
}
return lastrow;
}
@ -219,7 +233,43 @@ public class RowRecordsAggregate
{
return records.values().iterator();
}
/**
* used internally to refresh the "last row" when the last row is removed.
*/
private int findLastRow()
{
int rownum = lastrow-1;
RowRecord r = getRow(rownum);
while (r == null && rownum >= 0)
{
r = this.getRow(--rownum);
}
return rownum;
}
/**
* used internally to refresh the "first row" when the first row is removed.
*/
private int findFirstRow()
{
int rownum = firstrow+1;
RowRecord r = getRow(rownum);
while (r == null && rownum <= getLastRowNum())
{
r = getRow(++rownum);
}
if (rownum > getLastRowNum())
return -1;
return rownum;
}
/** Performs a deep clone of the record*/
public Object clone() {
RowRecordsAggregate rec = new RowRecordsAggregate();

View File

@ -55,17 +55,23 @@
package org.apache.poi.hssf.record.aggregates;
import org.apache.poi.hssf.usermodel.HSSFCell; //kludge shouldn't refer to this
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.util.DoubleList;
import org.apache.poi.util.IntList;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.TreeMap;
/**
*
* Aggregate value records together. Things are easier to handle that way.
*
* @author andy
* @author Andrew C. Oliver
* @author Glen Stampoultzis (glens at apache.org)
* @author Jason Height (jheight at chariot dot net dot au)
*/
@ -76,63 +82,72 @@ public class ValueRecordsAggregate
public final static short sid = -1000;
int firstcell = -1;
int lastcell = -1;
TreeMap records = null;
// int size = 0;
//TreeMap records = null;
/** Creates a new instance of ValueRecordsAggregate */
private final static int DEFAULT_ROWS=10000;
private final static int DEFAULT_COLS=256;
List celltype = null;
List xfs = null;
List numericcells = null;
List formulaptgs = null;
List stringvals = null;
IntList populatedRows = null;
int physCells; //physical number of cells
public CellValueRecordInterface getCell(int row, short col) {
return constructRecord(row, col);
public ValueRecordsAggregate()
{
records = new TreeMap();
}
public void insertCell(CellValueRecordInterface cell)
{
/* if (records.get(cell) == null)
{
size += (( Record ) cell).getRecordSize();
public int getRecordSize() {
//throw new RuntimeException("Not Implemented getRecordSize");
int size = 0;
Iterator irecs = getIterator();
while (irecs.hasNext()) {
size += (( Record ) irecs.next()).getRecordSize();
}
else
return size;
// return size;
}
public int serialize(int offset, byte [] data)
{
//throw new RuntimeException("Not Implemented serialize");
int pos = offset;
Iterator irecs = getIterator();
while (irecs.hasNext()) {
pos += (( Record ) irecs.next()).serialize(pos,data);
}
/* Iterator itr = records.values().iterator();
int pos = offset;
while (itr.hasNext())
{
size += (( Record ) cell).getRecordSize()
- (( Record ) records.get(cell)).getRecordSize();
pos += (( Record ) itr.next()).serialize(pos, data);
}*/
// XYLocator xy = new XYLocator(cell.getRow(), cell.getColumn());
Object o = records.put(cell, cell);
if ((cell.getColumn() < firstcell) || (firstcell == -1))
{
firstcell = cell.getColumn();
}
if ((cell.getColumn() > lastcell) || (lastcell == -1))
{
lastcell = cell.getColumn();
}
return pos - offset;
}
public void removeCell(CellValueRecordInterface cell)
{
// size -= (( Record ) cell).getRecordSize();
// XYLocator xy = new XYLocator(cell.getRow(), cell.getColumn());
records.remove(cell);
public ValueRecordsAggregate() {
celltype = new ArrayList(DEFAULT_ROWS);
xfs = new ArrayList(DEFAULT_ROWS);
numericcells = new ArrayList(DEFAULT_ROWS);
formulaptgs = new ArrayList(DEFAULT_ROWS);
stringvals = new ArrayList(DEFAULT_ROWS);
populatedRows = new IntList(DEFAULT_ROWS);
physCells = 0;
}
public int getPhysicalNumberOfCells()
{
return records.size();
public Iterator getIterator() {
return new VRAIterator(this);
}
public int getFirstCellNum()
{
return firstcell;
}
public int getLastCellNum()
{
return lastcell;
}
public int construct(int offset, List records)
{
@ -165,140 +180,449 @@ public class ValueRecordsAggregate
return k;
}
/**
* called by the class that is responsible for writing this sucker.
* Subclasses should implement this so that their data is passed back in a
* byte array.
*
* @param offset to begin writing at
* @param data byte array containing instance data
* @return number of bytes written
*/
public int getPhysicalNumberOfCells() {
return physCells;
}
public int serialize(int offset, byte [] data)
public int getPhysicalNumberOfCellsInRow(int row) {
int count = -1;
int col = -1;
boolean firsttime = true;
while (col > 0 || count == -1) {
col = findNextPopulatedCell(row,col);
count++;
}
return count;
}
public void setValue(int row, short cell, double val) {
((DoubleList)numericcells.get(row)).set(cell, val);
}
public void setStyle(int row, short cell, short xf) {
((IntList)xfs.get(row)).set(cell, xf);
}
public Iterator getRowCellIterator(int row) {
return new VRAIterator(this, row);
}
public void removeRow(int row) {
Iterator iterator = this.getRowCellIterator(row);
while(iterator.hasNext()) {
iterator.next();
iterator.remove();
}
}
public void removeCell(CellValueRecordInterface cell) {
int rownum = cell.getRow();
int colnum = cell.getColumn();
int xf = cell.getXFIndex();
int type = determineType(cell);
if (rownum < celltype.size() && colnum < ((IntList)celltype.get(rownum)).size()) {
IntList ctRow = (IntList)celltype.get(rownum);
if (ctRow.size()-1 == colnum) {
ctRow.remove(colnum);
if (ctRow.size() == 0 && celltype.size()-1 == rownum) {
celltype.remove(rownum);
int remp = populatedRows.indexOf(rownum);
System.err.println("remp == "+remp);
populatedRows.removeValue(rownum);
}
} else {
ctRow.set(colnum,-1);
}
physCells--;
} else {
//this cell doesn't exist...
throw new RuntimeException("Tried to remove a cell that does not exist r,c="+rownum+","+colnum);
}
}
public void insertCell(CellValueRecordInterface cell) {
int rownum = cell.getRow();
int colnum = cell.getColumn();
int xf = cell.getXFIndex();
int type = determineType(cell);
if (celltype.size() < rownum+1) {
populatedRows.add(rownum); //this means we must never have had this row inserted
}
ensureRows(rownum);
IntList ctRow = (IntList)celltype.get(rownum);
IntList xfRow = (IntList)xfs.get(rownum);
adjustIntList(ctRow, colnum+1);
adjustIntList(xfRow, colnum+1);
ctRow.set(colnum, type);
xfRow.set(colnum, xf);
insertCell(cell, type);
}
CellValueRecordInterface constructRecord(int row, int col) {
if (celltype.size() < row || ((IntList)celltype.get(row)).size() < col) {
throw new ArrayIndexOutOfBoundsException("constructRecord called with row = "+row+
"and col ="+col+" but there are only "+celltype.size()+" rows and "+
((IntList)celltype.get(row)).size()+" cols!!");
}
CellValueRecordInterface retval = null;
int type = ((IntList)celltype.get(row)).get(col);
switch (type) {
case HSSFCell.CELL_TYPE_NUMERIC:
NumberRecord nrecord = new NumberRecord();
nrecord.setColumn((short)col);
nrecord.setRow(row);
nrecord.setValue(((DoubleList)numericcells.get(row)).get(col));
nrecord.setXFIndex((short)((IntList)xfs.get(row)).get(col));
retval = nrecord;
break;
case HSSFCell.CELL_TYPE_STRING:
LabelSSTRecord srecord = new LabelSSTRecord();
srecord.setColumn((short)col);
srecord.setRow(row);
srecord.setSSTIndex((int)((DoubleList)numericcells.get(row)).get(col));
srecord.setXFIndex((short)((IntList)xfs.get(row)).get(col));
retval=srecord;
break;
case HSSFCell.CELL_TYPE_BLANK:
BlankRecord brecord = new BlankRecord();
brecord.setColumn((short)col);
brecord.setRow(row);
brecord.setXFIndex((short)((IntList)xfs.get(row)).get(col));
retval=brecord;
break;
case HSSFCell.CELL_TYPE_FORMULA:
FormulaRecord fr = new FormulaRecord();
fr.setColumn((short)col);
fr.setOptions((short)2);
fr.setRow(row);
fr.setXFIndex((short)((IntList)xfs.get(row)).get(col));
StringRecord st = null;
String strval = (String)((List)stringvals.get(row)).get(col);
List expressionlist = (List)((List)formulaptgs.get(row)).get(col);
fr.setParsedExpression(expressionlist);
fr.setExpressionLength(calculatePtgSize(expressionlist));
if (strval != null) {
st = new StringRecord();
st.setString(strval);
}
FormulaRecordAggregate frarecord = new FormulaRecordAggregate(fr,st);
retval= frarecord;
break;
default:
throw new RuntimeException("UnImplemented Celltype "+type);
}
return retval;
}
private short calculatePtgSize(List expressionlist) {
short retval = 0;
Iterator iter = expressionlist.iterator();
while (iter.hasNext()) {
retval += (short)((Ptg)iter.next()).getSize();
}
return retval;
}
private void insertCell(CellValueRecordInterface cell, int type) {
int rownum = cell.getRow();
int colnum = cell.getColumn();
DoubleList nmRow = (DoubleList)numericcells.get(rownum);
switch (type) {
case HSSFCell.CELL_TYPE_NUMERIC:
NumberRecord nrecord = (NumberRecord)cell;
adjustDoubleList(nmRow, colnum+1);
nmRow.set(colnum,nrecord.getValue());
physCells++;
break;
case HSSFCell.CELL_TYPE_STRING:
LabelSSTRecord srecord = (LabelSSTRecord)cell;
adjustDoubleList(nmRow, colnum+1);
nmRow.set(colnum,srecord.getSSTIndex());
physCells++;
break;
case HSSFCell.CELL_TYPE_FORMULA:
List ptRow = (List)formulaptgs.get(rownum);
List stRow = (List)stringvals.get(rownum);
FormulaRecordAggregate frarecord = (FormulaRecordAggregate)cell;
adjustDoubleList(nmRow, colnum+1);
adjustObjectList(ptRow, colnum+1);
adjustStringList(stRow, colnum+1);
nmRow.set(colnum,frarecord.getFormulaRecord().getValue());
ptRow.set(colnum,frarecord.getFormulaRecord().getParsedExpression());
StringRecord str = frarecord.getStringRecord();
if (str != null) {
stRow.set(colnum,str.getString());
} else {
stRow.set(colnum,null);
}
physCells++;
break;
case HSSFCell.CELL_TYPE_BLANK:
//BlankRecord brecord = (BlankRecord)cell;
physCells++;
break;
default:
throw new RuntimeException("UnImplemented Celltype "+cell.toString());
}
}
private int determineType(CellValueRecordInterface cval)
{
Iterator itr = records.values().iterator();
int pos = offset;
Record record = ( Record ) cval;
int sid = record.getSid();
int retval = 0;
while (itr.hasNext())
switch (sid)
{
pos += (( Record ) itr.next()).serialize(pos, data);
case NumberRecord.sid :
retval = HSSFCell.CELL_TYPE_NUMERIC;
break;
case BlankRecord.sid :
retval = HSSFCell.CELL_TYPE_BLANK;
break;
case LabelSSTRecord.sid :
retval = HSSFCell.CELL_TYPE_STRING;
break;
case FormulaRecordAggregate.sid :
retval = HSSFCell.CELL_TYPE_FORMULA;
break;
case BoolErrRecord.sid :
BoolErrRecord boolErrRecord = ( BoolErrRecord ) record;
retval = (boolErrRecord.isBoolean())
? HSSFCell.CELL_TYPE_BOOLEAN
: HSSFCell.CELL_TYPE_ERROR;
break;
}
return pos - offset;
}
/**
* called by the constructor, should set class level fields. Should throw
* runtime exception for bad/icomplete data.
*
* @param data raw data
* @param size size of data
* @param offset of the record's data (provided a big array of the file)
*/
protected void fillFields(byte [] data, short size, int offset)
{
return retval;
}
/**
* called by constructor, should throw runtime exception in the event of a
* record passed with a differing ID.
*
* @param id alleged id for this record
*/
private void ensureRows(int rownum) {
adjustRows(celltype, rownum+1, IntList.class);
adjustRows(xfs, rownum+1, IntList.class);
adjustRows(numericcells, rownum+1, DoubleList.class);
adjustRows(formulaptgs, rownum+1, ArrayList.class);
adjustRows(stringvals, rownum+1, ArrayList.class);
protected void validateSid(short id)
{
}
/**
* return the non static version of the id for this record.
*/
public short getSid()
{
return sid;
}
public int getRecordSize() {
int size = 0;
Iterator irecs = records.values().iterator();
while (irecs.hasNext()) {
size += (( Record ) irecs.next()).getRecordSize();
private void adjustRows(List list, int size, Class theclass) {
while (list.size() < size) {
try {
list.add(theclass.newInstance());
} catch (Exception e) {
throw new RuntimeException("Could Not Instantiate Row in adjustRows");
}
}
return size;
// return size;
}
public Iterator getIterator()
{
return records.values().iterator();
private void adjustIntList(IntList list, int size) {
while (list.size() < size) {
list.add(-1);
}
}
/** Performs a deep clone of the record*/
public Object clone() {
ValueRecordsAggregate rec = new ValueRecordsAggregate();
for (Iterator valIter = getIterator(); valIter.hasNext();) {
CellValueRecordInterface val = (CellValueRecordInterface)((CellValueRecordInterface)valIter.next()).clone();
rec.insertCell(val);
}
return rec;
private void adjustDoubleList(DoubleList list, int size) {
while (list.size() < size) {
list.add(-1);
}
}
private void adjustObjectList(List list, int size) {
while (list.size() < size) {
list.add(new ArrayList());
}
}
private void adjustStringList(List list, int size) {
while (list.size() < size) {
list.add(new String());
}
}
protected int findNextPopulatedCell(int row, int col) {
IntList ctRow = (IntList) celltype.get(row);
int retval = -1;
if (ctRow.size() > col+1) {
for (int k = col+1; k < ctRow.size() +1; k++) {
if (k != ctRow.size()) {
int val = ctRow.get(k);
if (val != -1) {
retval = k;
break;
} // end if (val !=...
} //end if (k !=..
} //end for
} //end if (ctRow.size()...
return retval;
}
public short getSid() {
return sid;
}
public void fillFields(byte[] data, short size, int offset) {
}
protected void validateSid(short sid) {
}
}
/*
* class XYLocator implements Comparable {
* private int row = 0;
* private int col = 0;
* public XYLocator(int row, int col) {
* this.row = row;
* this.col = col;
* }
*
* public int getRow() {
* return row;
* }
*
* public int getCol() {
* return col;
* }
*
* public int compareTo(Object obj) {
* XYLocator loc = (XYLocator)obj;
*
* if (this.getRow() == loc.getRow() &&
* this.getCol() == loc.getCol() )
* return 0;
*
* if (this.getRow() < loc.getRow())
* return -1;
*
* if (this.getRow() > loc.getRow())
* return 1;
*
* if (this.getCol() < loc.getCol())
* return -1;
*
* if (this.getCol() > loc.getCol())
* return 1;
*
* return -1;
*
* }
*
* public boolean equals(Object obj) {
* if (!(obj instanceof XYLocator)) return false;
*
* XYLocator loc = (XYLocator)obj;
* if (this.getRow() == loc.getRow()
* &&
* this.getCol() == loc.getCol()
* ) return true;
* return false;
* }
*
*
* }
*/
class VRAIterator implements Iterator {
private boolean hasNext;
private ValueRecordsAggregate vra;
int popindex;
int row;
int rowlimit;
int col;
CellValueRecordInterface current = null;
CellValueRecordInterface next = null;
public VRAIterator(ValueRecordsAggregate vra) {
this.vra = vra;
this.rowlimit = -1;
popindex = 0;
if (vra.getPhysicalNumberOfCells() > 0) {
hasNext = true;
next = findNextCell(null);
}
}
public VRAIterator(ValueRecordsAggregate vra, int row) {
this(vra);
rowlimit = row;
this.row = row;
this.popindex = vra.populatedRows.indexOf(row);
}
public boolean hasNext() {
return hasNext;
}
public Object next() {
current = next;
next = findNextCell(current);
if (next == null) {
hasNext = false;
}
return current;
}
public void remove() {
vra.removeCell(current);
}
private CellValueRecordInterface findNextCell(CellValueRecordInterface current) {
IntList ctRow = null;
int rowNum = -1;
int colNum = -1;
int newCol = -1;
boolean wasntFirst = false;
if (current != null) {
wasntFirst = true;
rowNum = current.getRow();
colNum = current.getColumn();
ctRow = ((IntList)vra.celltype.get(rowNum));
}
//if popindex = row iwth no cells, fast forward till we get to one with size > 0
while ((ctRow == null || ctRow.size() == 0) && vra.populatedRows.size() > popindex) {
if (wasntFirst == true) {
throw new RuntimeException("CANT HAPPEN WASNTFIRST BUT WE'RE FASTFORWARDING!");
}
rowNum = vra.populatedRows.get(popindex);
ctRow = (IntList)vra.celltype.get(rowNum);
if (ctRow.size() == 0) {
if (rowlimit == -1) {
popindex++;
} else {
this.hasNext = false;
}
}
}
if (rowNum == -1) {
return null;
}
while (newCol == -1) {
newCol = findNextPopulatedCell(rowNum,colNum);
colNum = newCol;
if (colNum == -1) { //end of row, forward one row
popindex++;
if (popindex < vra.populatedRows.size() && rowlimit == -1) {
rowNum = vra.populatedRows.get(popindex);
} else {
return null;
}
}
}
return vra.constructRecord(rowNum,colNum);
}
private int findNextPopulatedCell(int row, int col) {
/*IntList ctRow = (IntList) vra.celltype.get(row);
int retval = -1;
if (ctRow.size() > col+1) {
for (int k = col+1; k < ctRow.size() +1; k++) {
if (k != ctRow.size()) {
int val = ctRow.get(k);
if (val != -1) {
retval = k;
break;
} // end if (val !=...
} //end if (k !=..
} //end for
} //end if (ctRow.size()...
return retval;*/
return vra.findNextPopulatedCell(row, col);
}
}

View File

@ -94,8 +94,6 @@ import java.util.Calendar;
* NOTE: the alpha won't be implementing formulas
*
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Dan Sherman (dsherman at isisph.com)
* @author Brian Sanders (kestrel at burdell dot org) Active Cell support
* @version 1.0-pre
*/
@ -163,7 +161,7 @@ public class HSSFCell
private Sheet sheet;
//private short row;
private int row;
private CellValueRecordInterface record;
// private CellValueRecordInterface record;
/**
* Creates new Cell - Should only be called by HSSFRow. This creates a cell
@ -196,13 +194,25 @@ public class HSSFCell
this.book = book;
this.sheet = sheet;
BlankRecord rec = new BlankRecord();
rec.setRow(row);
rec.setColumn(cellNum);
rec.setXFIndex((short)0xf);
cellType = HSSFCell.CELL_TYPE_BLANK;
sheet.addValueRecord(row,(CellValueRecordInterface)rec);
// Relying on the fact that by default the cellType is set to 0 which
// is different to CELL_TYPE_BLANK hence the following method call correctly
// creates a new blank cell.
setCellType(CELL_TYPE_BLANK, false);
ExtendedFormatRecord xf = book.getExFormatAt(0xf);
//setCellType(CELL_TYPE_BLANK, false);
//ExtendedFormatRecord xf = book.getExFormatAt(0xf);
//setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
}
/**
@ -236,15 +246,16 @@ public class HSSFCell
errorValue = ( byte ) 0;
this.book = book;
this.sheet = sheet;
switch (type)
/* switch (type)
{
case CELL_TYPE_NUMERIC :
record = new NumberRecord();
(( NumberRecord ) record).setColumn(col);
(( NumberRecord ) record).setRow(row);
(( NumberRecord ) record).setValue(( short ) 0);
(( NumberRecord ) record).setXFIndex(( short ) 0);
//record = new NumberRecord();
//(( NumberRecord ) record).setColumn(col);
//(( NumberRecord ) record).setRow(row);
//(( NumberRecord ) record).setValue(( short ) 0);
//(( NumberRecord ) record).setXFIndex(( short ) 0);
break;
case CELL_TYPE_STRING :
@ -285,7 +296,7 @@ public class HSSFCell
}
ExtendedFormatRecord xf = book.getExFormatAt(0xf);
setCellStyle(new HSSFCellStyle(( short ) 0xf, xf));
setCellStyle(new HSSFCellStyle(( short ) 0xf, xf)); */
}
/**
@ -302,7 +313,7 @@ public class HSSFCell
CellValueRecordInterface cval)
{
cellNum = cval.getColumn();
record = cval;
//record = cval;
this.row = row;
cellType = determineType(cval);
cellStyle = null;
@ -394,8 +405,14 @@ public class HSSFCell
public void setCellNum(short num)
{
CellValueRecordInterface cval = sheet.getValueRecord(row, cellNum);
if (cval != null) {
sheet.removeValueRecord(this.row, cval);
}
cellNum = num;
record.setColumn(num);
sheet.addValueRecord(row, cval);
//record.setColumn(num);
}
/**
@ -457,16 +474,17 @@ public class HSSFCell
}
else
{
frec = ( FormulaRecordAggregate ) record;
frec = (FormulaRecordAggregate)sheet.getValueRecord(row, cellNum);
}
frec.setColumn(getCellNum());
if (setValue)
{
frec.getFormulaRecord().setValue(getNumericCellValue());
//frec.getFormulaRecord().setParsedExpression();
}
frec.setXFIndex(( short ) cellStyle.getIndex());
// frec.setXFIndex(( short ) cellStyle.getIndex());
frec.setRow(row);
record = frec;
sheet.replaceValueRecord(frec);
break;
case CELL_TYPE_NUMERIC :
@ -478,16 +496,16 @@ public class HSSFCell
}
else
{
nrec = ( NumberRecord ) record;
nrec = ( NumberRecord ) sheet.getValueRecord(row, cellNum);
}
nrec.setColumn(getCellNum());
if (setValue)
{
nrec.setValue(getNumericCellValue());
}
nrec.setXFIndex(( short ) cellStyle.getIndex());
nrec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex());
nrec.setRow(row);
record = nrec;
sheet.replaceValueRecord(nrec);
break;
case CELL_TYPE_STRING :
@ -499,11 +517,11 @@ public class HSSFCell
}
else
{
lrec = ( LabelSSTRecord ) record;
lrec = ( LabelSSTRecord ) sheet.getValueRecord(row, cellNum);
}
lrec.setColumn(getCellNum());
lrec.setRow(row);
lrec.setXFIndex(( short ) cellStyle.getIndex());
lrec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex());
if (setValue)
{
if ((getStringCellValue() != null)
@ -523,7 +541,7 @@ public class HSSFCell
lrec.setSSTIndex(sst);
}
}
record = lrec;
sheet.replaceValueRecord(lrec);
break;
case CELL_TYPE_BLANK :
@ -535,21 +553,21 @@ public class HSSFCell
}
else
{
brec = ( BlankRecord ) record;
brec = ( BlankRecord ) sheet.getValueRecord(row, cellNum);
}
brec.setColumn(getCellNum());
// During construction the cellStyle may be null for a Blank cell.
if (cellStyle != null)
{
brec.setXFIndex(( short ) cellStyle.getIndex());
brec.setXFIndex(sheet.getValueRecord(row,cellNum).getXFIndex());
}
else
{
brec.setXFIndex(( short ) 0);
}
brec.setRow(row);
record = brec;
sheet.replaceValueRecord(brec);
break;
case CELL_TYPE_BOOLEAN :
@ -561,7 +579,7 @@ public class HSSFCell
}
else
{
boolRec = ( BoolErrRecord ) record;
boolRec = ( BoolErrRecord ) sheet.getValueRecord(row, cellNum);
}
boolRec.setColumn(getCellNum());
if (setValue)
@ -570,7 +588,7 @@ public class HSSFCell
}
boolRec.setXFIndex(( short ) cellStyle.getIndex());
boolRec.setRow(row);
record = boolRec;
sheet.replaceValueRecord(boolRec);
break;
case CELL_TYPE_ERROR :
@ -582,7 +600,7 @@ public class HSSFCell
}
else
{
errRec = ( BoolErrRecord ) record;
errRec = ( BoolErrRecord ) sheet.getValueRecord(row, cellNum);
}
errRec.setColumn(getCellNum());
if (setValue)
@ -591,16 +609,17 @@ public class HSSFCell
}
errRec.setXFIndex(( short ) cellStyle.getIndex());
errRec.setRow(row);
record = errRec;
sheet.replaceValueRecord(errRec);
break;
}
if (cellType != this.cellType)
{
int loc = sheet.getLoc();
sheet.replaceValueRecord(record);
//sheet.replaceValueRecord(record);
sheet.setLoc(loc);
}
//sheet.setCellType(this.row, this.cellNum);
this.cellType = cellType;
}
@ -631,7 +650,7 @@ public class HSSFCell
{
setCellType(CELL_TYPE_NUMERIC, false);
}
(( NumberRecord ) record).setValue(value);
sheet.setCellValue(row, cellNum, value);
cellValue = value;
}
@ -693,7 +712,7 @@ public class HSSFCell
{
index = book.addSSTString(value, true);
}
(( LabelSSTRecord ) record).setSSTIndex(index);
sheet.setCellValue(row, cellNum, index);
stringValue = value;
}
}
@ -704,12 +723,12 @@ public class HSSFCell
setCellType(CELL_TYPE_BLANK,false);
} else {
setCellType(CELL_TYPE_FORMULA,false);
FormulaRecordAggregate rec = (FormulaRecordAggregate) record;
FormulaRecordAggregate rec = new FormulaRecordAggregate(new FormulaRecord(), null);
rec.getFormulaRecord().setOptions(( short ) 2);
rec.getFormulaRecord().setValue(0);
//only set to default if there is no extended format index already set
if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f);
rec.setRow(row);
rec.setColumn(cellNum);
rec.setXFIndex(( short ) 0x0f);
FormulaParser fp = new FormulaParser(formula+";",book);
fp.parse();
Ptg[] ptg = fp.getRPNPtg();
@ -720,6 +739,9 @@ public class HSSFCell
rec.getFormulaRecord().pushExpressionToken(ptg[ k ]);
}
rec.getFormulaRecord().setExpressionLength(( short ) size);
sheet.replaceValueRecord(rec);
//sheet.setCellFormula(row, cellNum, options, value
//Workbook.currentBook = null;
}
}
@ -727,9 +749,11 @@ public class HSSFCell
public String getCellFormula() {
//Workbook.currentBook=book;
SheetReferences refs = book.getSheetReferences();
String retval = FormulaParser.toFormulaString(refs, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
String retval = FormulaParser.toFormulaString(refs,
((FormulaRecordAggregate)sheet.getValueRecord(row,cellNum)).getFormulaRecord().getParsedExpression());
//Workbook.currentBook=null;
return retval;
//return null;
}
@ -787,12 +811,7 @@ public class HSSFCell
throw new NumberFormatException(
"You cannot get a date value from an error cell");
}
if (book.isUsing1904DateWindowing()) {
return HSSFDateUtil.getJavaDate(cellValue,true);
}
else {
return HSSFDateUtil.getJavaDate(cellValue,false);
}
return HSSFDateUtil.getJavaDate(cellValue);
}
/**
@ -834,12 +853,12 @@ public class HSSFCell
public void setCellValue(boolean value)
{
if ((cellType != CELL_TYPE_BOOLEAN ) && ( cellType != CELL_TYPE_FORMULA))
/*if ((cellType != CELL_TYPE_BOOLEAN ) && ( cellType != CELL_TYPE_FORMULA))
{
setCellType(CELL_TYPE_BOOLEAN, false);
}
(( BoolErrRecord ) record).setValue(value);
booleanValue = value;
booleanValue = value; */
}
/**
@ -853,11 +872,11 @@ public class HSSFCell
public void setCellErrorValue(byte value)
{
if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA))
/*if ((cellType != CELL_TYPE_ERROR) && (cellType != CELL_TYPE_FORMULA))
{
setCellType(CELL_TYPE_ERROR, false);
}
(( BoolErrRecord ) record).setValue(value);
(( BoolErrRecord ) record).setValue(value);*/
errorValue = value;
}
@ -911,7 +930,8 @@ public class HSSFCell
public void setCellStyle(HSSFCellStyle style)
{
cellStyle = style;
record.setXFIndex(style.getIndex());
sheet.setCellStyle(row, cellNum, style.getIndex());
}
/**
@ -961,7 +981,7 @@ public class HSSFCell
protected CellValueRecordInterface getCellValueRecord()
{
return record;
return sheet.getValueRecord(row, cellNum);
}
/**
@ -976,13 +996,4 @@ public class HSSFCell
throw new RuntimeException("You cannot reference columns with an index of less then 0.");
}
}
/**
* Sets this cell as the active cell for the worksheet
*/
public void setAsActiveCell()
{
this.sheet.setActiveCellRow(this.row);
this.sheet.setActiveCellCol(this.cellNum);
}
}

View File

@ -61,21 +61,28 @@ package org.apache.poi.hssf.usermodel;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RowRecord;
import org.apache.poi.hssf.record.VCenterRecord;
import org.apache.poi.hssf.record.WindowTwoRecord;
import org.apache.poi.hssf.record.WSBoolRecord;
import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate;
import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.IntList;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.List;
/**
* High level representation of a worksheet.
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Glen Stampoultzis (glens at apache.org)
* @author Libin Roman (romal at vistaportal.com)
* @author Shawn Laubach (slaubach at apache dot org) (Just a little)
* @author Shawn Laubach (laubach at acm.org) (Just a little)
*/
public class HSSFSheet
@ -101,7 +108,9 @@ public class HSSFSheet
*/
private Sheet sheet;
private TreeMap rows;
// private TreeMap rows;
// private RowRecordsAggregate rows;
// private ValueRecordsAggregate vra;
private Workbook book;
private int firstrow;
private int lastrow;
@ -118,7 +127,7 @@ public class HSSFSheet
protected HSSFSheet(Workbook book)
{
sheet = Sheet.createSheet();
rows = new TreeMap(); // new ArrayList(INITIAL_CAPACITY);
//rows = new TreeMap(); // new ArrayList(INITIAL_CAPACITY);
this.book = book;
}
@ -134,7 +143,7 @@ public class HSSFSheet
protected HSSFSheet(Workbook book, Sheet sheet)
{
this.sheet = sheet;
rows = new TreeMap();
//rows = new TreeMap();
this.book = book;
setPropertiesFromSheet(sheet);
}
@ -150,7 +159,7 @@ public class HSSFSheet
private void setPropertiesFromSheet(Sheet sheet)
{
int sloc = sheet.getLoc();
/* int sloc = sheet.getLoc();
RowRecord row = sheet.getNextRow();
while (row != null)
@ -159,7 +168,9 @@ public class HSSFSheet
row = sheet.getNextRow();
}
sheet.setLoc(sloc);
sheet.setLoc(sloc);*/
/*
CellValueRecordInterface cval = sheet.getNextValueRecord();
long timestart = System.currentTimeMillis();
@ -190,8 +201,9 @@ public class HSSFSheet
cval = null;
}
}
log.log(DEBUG, "total sheet cell creation took ",
new Long(System.currentTimeMillis() - timestart));
*/
// log.log(DEBUG, "total sheet cell creation took ",
// new Long(System.currentTimeMillis() - timestart));
}
/**
@ -219,13 +231,13 @@ public class HSSFSheet
* @return HSSFRow high level representation
*/
private HSSFRow createRowFromRecord(RowRecord row)
/* private HSSFRow createRowFromRecord(RowRecord row)
{
HSSFRow hrow = new HSSFRow(book, sheet, row);
addRow(hrow, false);
return hrow;
}
}*/
/**
* Remove a row from this sheet. All cells contained in the row are removed as well
@ -236,35 +248,35 @@ public class HSSFSheet
public void removeRow(HSSFRow row)
{
sheet.setLoc(sheet.getDimsLoc());
if (rows.size() > 0)
{
rows.remove(row);
if (row.getRowNum() == getLastRowNum())
{
lastrow = findLastRow(lastrow);
}
if (row.getRowNum() == getFirstRowNum())
{
firstrow = findFirstRow(firstrow);
}
Iterator iter = row.cellIterator();
// if (rows.size() > 0)
// {
// rows.remove(row);
// if (row.getRowNum() == getLastRowNum())
// {
// lastrow = findLastRow(lastrow);
// }
// if (row.getRowNum() == getFirstRowNum())
// {
// firstrow = findFirstRow(firstrow);
// }
//Iterator iter = row.cellIterator();
while (iter.hasNext())
/* while (iter.hasNext())
{
HSSFCell cell = (HSSFCell) iter.next();
sheet.removeValueRecord(row.getRowNum(),
cell.getCellValueRecord());
}
}*/
sheet.removeRow(row.getRowRecord());
}
//}
}
/**
* used internally to refresh the "last row" when the last row is removed.
*/
private int findLastRow(int lastrow)
/* private int findLastRow(int lastrow)
{
int rownum = lastrow - 1;
HSSFRow r = getRow(rownum);
@ -274,13 +286,13 @@ public class HSSFSheet
r = getRow(--rownum);
}
return rownum;
}
}*/
/**
* used internally to refresh the "first row" when the first row is removed.
*/
private int findFirstRow(int firstrow)
/*private int findFirstRow(int firstrow)
{
int rownum = firstrow + 1;
HSSFRow r = getRow(rownum);
@ -294,7 +306,7 @@ public class HSSFSheet
return -1;
return rownum;
}
} */
/**
* add a row to the sheet
@ -304,19 +316,22 @@ public class HSSFSheet
private void addRow(HSSFRow row, boolean addLow)
{
rows.put(row, row);
if (addLow)
{
sheet.addRow(row.getRowRecord());
//rows.put(row, row);
if (addLow) {
RowRecord rec = sheet.getRow(row.getRowNum());
if (rec == null) {
rec = new RowRecord();
sheet.addRow(sheet.createRow(row.getRowNum()));
}
}
if (row.getRowNum() > getLastRowNum())
/* if (row.getRowNum() > getLastRowNum())
{
lastrow = row.getRowNum();
}
if (row.getRowNum() < getFirstRowNum())
{
firstrow = row.getRowNum();
}
}*/
}
/**
@ -328,11 +343,9 @@ public class HSSFSheet
public HSSFRow getRow(int rownum)
{
HSSFRow row = new HSSFRow();
HSSFRow retval = new HSSFRow(book, sheet, this.sheet.getRow(rownum));
//row.setRowNum((short) rownum);
row.setRowNum( rownum);
return (HSSFRow) rows.get(row);
return retval;
}
/**
@ -341,7 +354,7 @@ public class HSSFSheet
public int getPhysicalNumberOfRows()
{
return rows.size();
return sheet.getPhysicalNumberOfRows();
}
/**
@ -351,7 +364,7 @@ public class HSSFSheet
public int getFirstRowNum()
{
return firstrow;
return sheet.getFirstRow();
}
/**
@ -361,7 +374,7 @@ public class HSSFSheet
public int getLastRowNum()
{
return lastrow;
return sheet.getLastRow();
}
/**
@ -513,33 +526,6 @@ public class HSSFSheet
return record.getVCenter();
}
/**
* determines whether the output is horizontally centered on the page.
* @param value true to horizontally center, false otherwise.
*/
public void setHorizontallyCenter(boolean value)
{
HCenterRecord record =
(HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid);
record.setHCenter(value);
}
/**
* Determine whether printed output for this sheet will be horizontally centered.
*/
public boolean getHorizontallyCenter()
{
HCenterRecord record =
(HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid);
return record.getHCenter();
}
/**
* removes a merged region of cells (hence letting them free)
* @param index of the region to unmerge
@ -578,7 +564,7 @@ public class HSSFSheet
public Iterator rowIterator()
{
return rows.values().iterator();
return new SheetRowIterator(this, this.book);
}
/**
@ -799,125 +785,90 @@ public class HSSFSheet
* @param newPrintGridlines boolean to turn on or off the printing of
* gridlines
*/
public void setPrintGridlines( boolean newPrintGridlines )
{
getSheet().getPrintGridlines().setPrintGridlines( newPrintGridlines );
public void setPrintGridlines(boolean newPrintGridlines) {
getSheet().getPrintGridlines().setPrintGridlines(newPrintGridlines);
}
/**
* Gets the print setup object.
* @return The user model for the print setup object.
*/
public HSSFPrintSetup getPrintSetup()
{
return new HSSFPrintSetup( getSheet().getPrintSetup() );
public HSSFPrintSetup getPrintSetup() {
return new HSSFPrintSetup(getSheet().getPrintSetup());
}
/**
* Gets the user model for the document header.
* @return The Document header.
*/
public HSSFHeader getHeader()
{
return new HSSFHeader( getSheet().getHeader() );
public HSSFHeader getHeader() {
return new HSSFHeader(getSheet().getHeader());
}
/**
* Gets the user model for the document footer.
* @return The Document footer.
*/
public HSSFFooter getFooter()
{
return new HSSFFooter( getSheet().getFooter() );
}
public HSSFFooter getFooter() {
return new HSSFFooter(getSheet().getFooter());
}
/**
* Sets whether sheet is selected.
* @param sel Whether to select the sheet or deselect the sheet.
*/
public void setSelected( boolean sel )
{
getSheet().setSelected( sel );
}
/**
* Sets whether sheet is selected.
* @param sel Whether to select the sheet or deselect the sheet.
*/
public void setSelected(boolean sel) {
getSheet().setSelected(sel);
}
/**
* Gets the size of the margin in inches.
* @param margin which margin to get
* @return the size of the margin
*/
public double getMargin( short margin )
{
return getSheet().getMargin( margin );
}
/**
* Gets the size of the margin in inches.
* @param margin which margin to get
* @return the size of the margin
*/
public double getMargin(short margin) {
return getSheet().getMargin(margin);
}
/**
* Sets the size of the margin in inches.
* @param margin which margin to get
* @param size the size of the margin
*/
public void setMargin( short margin, double size )
{
getSheet().setMargin( margin, size );
}
/**
* Shifts rows between startRow and endRow n number of rows.
* If you use a negative number, it will shift rows up.
* Code ensures that rows don't wrap around
*
* @param startRow the row to start shifting
* @param endRow the row to end shifting
* @param n the number of rows to shift
*/
public void shiftRows( int startRow, int endRow, int n )
{
int s, e, inc;
if ( n < 0 )
{
s = startRow;
e = endRow;
inc = 1;
}
else
{
s = endRow;
e = startRow;
inc = -1;
}
for ( int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc )
{
HSSFRow row = getRow( rowNum );
HSSFRow row2Replace = getRow( rowNum + n );
if ( row2Replace == null )
row2Replace = createRow( rowNum + n );
HSSFCell cell;
for ( short col = row2Replace.getFirstCellNum(); col <= row2Replace.getLastCellNum(); col++ )
{
cell = row2Replace.getCell( col );
if ( cell != null )
row2Replace.removeCell( cell );
}
for ( short col = row.getFirstCellNum(); col <= row.getLastCellNum(); col++ )
{
cell = row.getCell( col );
if ( cell != null )
{
row.removeCell( cell );
CellValueRecordInterface cellRecord = cell.getCellValueRecord();
cellRecord.setRow( rowNum + n );
row2Replace.createCellFromRecord( cellRecord );
sheet.addValueRecord( rowNum + n, cellRecord );
}
}
}
if ( endRow == lastrow || endRow + n > lastrow ) lastrow = Math.min( endRow + n, 65535 );
if ( startRow == firstrow || startRow + n < firstrow ) firstrow = Math.max( startRow + n, 0 );
}
protected void insertChartRecords( List records )
{
int window2Loc = sheet.findFirstRecordLocBySid( WindowTwoRecord.sid );
sheet.getRecords().addAll( window2Loc, records );
}
/**
* Sets the size of the margin in inches.
* @param margin which margin to get
* @param size the size of the margin
*/
public void setMargin(short margin, double size) {
getSheet().setMargin(margin, size);
}
}
class SheetRowIterator implements Iterator {
Iterator rows;
Workbook book;
Sheet sheet;
public SheetRowIterator(HSSFSheet sheet, Workbook book) {
this.sheet = sheet.getSheet();
this.book = book;
rows = this.sheet.rowRecordIterator();
}
public boolean hasNext() {
return rows.hasNext();
}
public Object next() {
HSSFRow retval = null;
if (rows.hasNext()) {
retval = new HSSFRow(book, sheet, (RowRecord)rows.next());
}
return retval;
}
public void remove() {
rows.remove();
}
}

View File

@ -60,15 +60,10 @@
package org.apache.poi.hssf.usermodel;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.hssf.eventmodel.EventRecordFactory;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.util.POILogger;
import java.io.ByteArrayInputStream;
@ -77,7 +72,6 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
/**
* High level representation of a workbook. This is the first object most users
@ -88,7 +82,7 @@ import java.util.Iterator;
* @see org.apache.poi.hssf.usermodel.HSSFSheet
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Glen Stampoultzis (glens at apache.org)
* @author Shawn Laubach (slaubach at apache dot org)
* @author Shawn Laubach (shawnlaubach at cox.net)
* @version 2.0-pre
*/
@ -123,18 +117,6 @@ public class HSSFWorkbook
*/
private ArrayList names;
/**
* holds whether or not to preserve other nodes in the POIFS. Used
* for macros and embedded objects.
*/
private boolean preserveNodes;
/**
* if you do preserve the nodes, you'll need to hold the whole POIFS in
* memory.
*/
private POIFSFileSystem poifs;
private static POILogger log = POILogFactory.getLogger(HSSFWorkbook.class);
@ -150,40 +132,22 @@ public class HSSFWorkbook
names = new ArrayList(INITIAL_CAPACITY);
}
public HSSFWorkbook(POIFSFileSystem fs) throws IOException {
this(fs,true);
}
/**
* given a POI POIFSFileSystem object, read in its Workbook and populate the high and
* low level models. If you're reading in a workbook...start here.
*
* @param fs the POI filesystem that contains the Workbook stream.
* @param preserveNodes whether to preseve other nodes, such as
* macros. This takes more memory, so only say yes if you
* need to.
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem
* @exception IOException if the stream cannot be read
*/
public HSSFWorkbook(POIFSFileSystem fs, boolean preserveNodes)
public HSSFWorkbook(POIFSFileSystem fs)
throws IOException
{
this.preserveNodes = preserveNodes;
if (preserveNodes) {
this.poifs = fs;
}
sheets = new ArrayList(INITIAL_CAPACITY);
names = new ArrayList(INITIAL_CAPACITY);
InputStream stream = fs.createDocumentInputStream("Workbook");
EventRecordFactory factory = new EventRecordFactory();
List records = RecordFactory.createRecords(stream);
workbook = Workbook.createWorkbook(records);
@ -211,27 +175,20 @@ public class HSSFWorkbook
}
}
public HSSFWorkbook(InputStream s) throws IOException {
this(s,true);
}
/**
* Companion to HSSFWorkbook(POIFSFileSystem), this constructs the POI filesystem around your
* inputstream.
*
* @param s the POI filesystem that contains the Workbook stream.
* @param preserveNodes whether to preseve other nodes, such as
* macros. This takes more memory, so only say yes if you
* need to.
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem
* @see #HSSFWorkbook(POIFSFileSystem)
* @exception IOException if the stream cannot be read
*/
public HSSFWorkbook(InputStream s, boolean preserveNodes)
public HSSFWorkbook(InputStream s)
throws IOException
{
this(new POIFSFileSystem(s), preserveNodes);
this((new POIFSFileSystem(s)));
}
/**
@ -558,16 +515,9 @@ public class HSSFWorkbook
{
byte[] bytes = getBytes();
POIFSFileSystem fs = new POIFSFileSystem();
fs.createDocument(new ByteArrayInputStream(bytes), "Workbook");
if (preserveNodes) {
List excepts = new ArrayList(1);
excepts.add("Workbook");
copyNodes(this.poifs,fs,excepts);
}
fs.createDocument(new ByteArrayInputStream(bytes), "Workbook");
fs.writeFilesystem(stream);
//poifs.writeFilesystem(stream);
}
/**
@ -598,12 +548,12 @@ public class HSSFWorkbook
// sheetbytes.add((( HSSFSheet ) sheets.get(k)).getSheet().getSize());
totalsize += ((HSSFSheet) sheets.get(k)).getSheet().getSize();
}
/* if (totalsize < 4096)
if (totalsize < 4096)
{
totalsize = 4096;
}*/
byte[] retval = new byte[totalsize];
int pos = workbook.serialize(0, retval);
}
byte[] data = new byte[totalsize];
int pos = workbook.serialize(0, data);
// System.arraycopy(wb, 0, retval, 0, wb.length);
for (int k = 0; k < sheets.size(); k++)
@ -612,13 +562,13 @@ public class HSSFWorkbook
// byte[] sb = (byte[])sheetbytes.get(k);
// System.arraycopy(sb, 0, retval, pos, sb.length);
pos += ((HSSFSheet) sheets.get(k)).getSheet().serialize(pos,
retval); // sb.length;
data); // sb.length;
}
/* for (int k = pos; k < totalsize; k++)
for (int k = pos; k < totalsize; k++)
{
retval[k] = 0;
}*/
return retval;
data[k] = 0;
}
return data;
}
public int addSSTString(String string)
@ -708,14 +658,14 @@ public class HSSFWorkbook
workbook.removeName(index);
}
/**
/**
* Creates an instance of HSSFDataFormat.
* @return the HSSFDataFormat object
* @see org.apache.poi.hssf.record.FormatRecord
* @see org.apache.poi.hssf.record.Record
*/
public HSSFDataFormat createDataFormat() {
return new HSSFDataFormat(workbook);
return new HSSFDataFormat(workbook);
}
/** remove the named range by his name
@ -727,89 +677,5 @@ public class HSSFWorkbook
removeName(index);
}
public HSSFPalette getCustomPalette()
{
return new HSSFPalette(workbook.getCustomPalette());
}
/**
* Copies nodes from one POIFS to the other minus the excepts
* @param source is the source POIFS to copy from
* @param target is the target POIFS to copy to
* @param excepts is a list of Strings specifying what nodes NOT to copy
*/
private void copyNodes(POIFSFileSystem source, POIFSFileSystem target,
List excepts) throws IOException {
//System.err.println("CopyNodes called");
DirectoryEntry root = source.getRoot();
DirectoryEntry newRoot = target.getRoot();
Iterator entries = root.getEntries();
while (entries.hasNext()) {
Entry entry = (Entry)entries.next();
if (!isInList(entry.getName(), excepts)) {
copyNodeRecursively(entry,newRoot);
}
}
}
private boolean isInList(String entry, List list) {
for (int k = 0; k < list.size(); k++) {
if (list.get(k).equals(entry)) {
return true;
}
}
return false;
}
private void copyNodeRecursively(Entry entry, DirectoryEntry target)
throws IOException {
//System.err.println("copyNodeRecursively called with "+entry.getName()+
// ","+target.getName());
DirectoryEntry newTarget = null;
if (entry.isDirectoryEntry()) {
newTarget = target.createDirectory(entry.getName());
Iterator entries = ((DirectoryEntry)entry).getEntries();
while (entries.hasNext()) {
copyNodeRecursively((Entry)entries.next(),newTarget);
}
} else {
DocumentEntry dentry = (DocumentEntry)entry;
DocumentInputStream dstream = new DocumentInputStream(dentry);
target.createDocument(dentry.getName(),dstream);
dstream.close();
}
}
public void insertChartRecord()
{
int loc = workbook.findFirstRecordLocBySid(SSTRecord.sid);
byte[] data = {
(byte)0x0F, (byte)0x00, (byte)0x00, (byte)0xF0, (byte)0x52,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x06, (byte)0xF0, (byte)0x18, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x01, (byte)0x08, (byte)0x00, (byte)0x00,
(byte)0x02, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00,
(byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00,
(byte)0x00, (byte)0x03, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x33, (byte)0x00, (byte)0x0B, (byte)0xF0, (byte)0x12,
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0xBF, (byte)0x00,
(byte)0x08, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x81,
(byte)0x01, (byte)0x09, (byte)0x00, (byte)0x00, (byte)0x08,
(byte)0xC0, (byte)0x01, (byte)0x40, (byte)0x00, (byte)0x00,
(byte)0x08, (byte)0x40, (byte)0x00, (byte)0x1E, (byte)0xF1,
(byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x0D,
(byte)0x00, (byte)0x00, (byte)0x08, (byte)0x0C, (byte)0x00,
(byte)0x00, (byte)0x08, (byte)0x17, (byte)0x00, (byte)0x00,
(byte)0x08, (byte)0xF7, (byte)0x00, (byte)0x00, (byte)0x10,
};
UnknownRecord r = new UnknownRecord((short)0x00EB,(short)0x005a, data);
workbook.getRecords().add(loc, r);
}
}

View File

@ -88,6 +88,7 @@ public class IntList
{
private int[] _array;
private int _limit;
private int fillval = 0;
private static final int _default_size = 128;
/**
@ -97,8 +98,14 @@ public class IntList
public IntList()
{
this(_default_size);
}
}
public IntList(final int initialCapacity)
{
this(initialCapacity,0);
}
/**
* create a copy of an existing IntList
*
@ -118,12 +125,22 @@ public class IntList
* @param initialCapacity the size for the internal array
*/
public IntList(final int initialCapacity)
public IntList(final int initialCapacity, int fillvalue)
{
_array = new int[ initialCapacity ];
if (fillval != 0) {
fillval = fillvalue;
fillArray(fillval, _array, 0);
}
_limit = 0;
}
private void fillArray(int val, int[] array, int index) {
for (int k = index; k < array.length; k++) {
array[k] = val;
}
}
/**
* add the specfied value at the specified index
*
@ -519,7 +536,9 @@ public class IntList
{
if (o == _array[ j ])
{
System.arraycopy(_array, j + 1, _array, j, _limit - j);
if (j+1 < _limit) {
System.arraycopy(_array, j + 1, _array, j, _limit - j);
}
_limit--;
rval = true;
}
@ -670,7 +689,11 @@ public class IntList
int size = (new_size == _array.length) ? new_size + 1
: new_size;
int[] new_array = new int[ size ];
if (fillval != 0) {
fillArray(fillval, new_array, _array.length);
}
System.arraycopy(_array, 0, new_array, 0, _limit);
_array = new_array;
}

View File

@ -56,7 +56,6 @@ package org.apache.poi.hssf.usermodel;
import junit.framework.TestCase;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.record.HCenterRecord;
import org.apache.poi.hssf.record.VCenterRecord;
import org.apache.poi.hssf.record.WSBoolRecord;
@ -116,26 +115,6 @@ public class TestHSSFSheet
// wb.write(new FileOutputStream("c:\\test.xls"));
}
/**
* Test horizontally centered output.
*/
public void testHorizontallyCenter()
throws Exception
{
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet s = wb.createSheet();
Sheet sheet = s.getSheet();
HCenterRecord record =
(HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid);
assertEquals(false, record.getHCenter());
s.setHorizontallyCenter(true);
assertEquals(true, record.getHCenter());
}
/**
* Test WSBboolRecord fields get set in the user model.
*/
@ -236,86 +215,4 @@ public class TestHSSFSheet
assertEquals(cloned.getRow((short)0).getCell((short)0).getStringCellValue(), "clone_test");
}
/**
* Tests the shiftRows function. Does three different shifts.
* After each shift, writes the workbook to file and reads back to
* check. This ensures that if some changes code that breaks
* writing or what not, they realize it.
*
* Shawn Laubach (slaubach at apache dot org)
*/
public void testShiftRows() throws Exception
{
// Read initial file in
String filename = System.getProperty( "HSSF.testdata.path" );
filename = filename + "/SimpleMultiCell.xls";
FileInputStream fin = new FileInputStream( filename );
HSSFWorkbook wb = new HSSFWorkbook( fin );
fin.close();
HSSFSheet s = wb.getSheetAt( 0 );
// Shift the second row down 1 and write to temp file
s.shiftRows( 1, 1, 1 );
File tempFile = File.createTempFile( "shift", "test.xls" );
FileOutputStream fout = new FileOutputStream( tempFile );
wb.write( fout );
fout.close();
// Read from temp file and check the number of cells in each
// row (in original file each row was unique)
fin = new FileInputStream( tempFile );
wb = new HSSFWorkbook( fin );
fin.close();
s = wb.getSheetAt( 0 );
assertEquals( s.getRow( 0 ).getPhysicalNumberOfCells(), 1 );
assertTrue( s.getRow( 1 ) == null || s.getRow( 1 ).getPhysicalNumberOfCells() == 0 );
assertEquals( s.getRow( 2 ).getPhysicalNumberOfCells(), 2 );
assertEquals( s.getRow( 3 ).getPhysicalNumberOfCells(), 4 );
assertEquals( s.getRow( 4 ).getPhysicalNumberOfCells(), 5 );
// Shift rows 1-3 down 3 in the current one. This tests when
// 1 row is blank. Write to a another temp file
s.shiftRows( 0, 2, 3 );
tempFile = File.createTempFile( "shift", "test.xls" );
fout = new FileOutputStream( tempFile );
wb.write( fout );
fout.close();
// Read and ensure things are where they should be
fin = new FileInputStream( tempFile );
wb = new HSSFWorkbook( fin );
fin.close();
s = wb.getSheetAt( 0 );
assertTrue( s.getRow( 0 ) == null || s.getRow( 0 ).getPhysicalNumberOfCells() == 0 );
assertTrue( s.getRow( 1 ) == null || s.getRow( 1 ).getPhysicalNumberOfCells() == 0 );
assertTrue( s.getRow( 2 ) == null || s.getRow( 2 ).getPhysicalNumberOfCells() == 0 );
assertEquals( s.getRow( 3 ).getPhysicalNumberOfCells(), 1 );
assertTrue( s.getRow( 4 ) == null || s.getRow( 4 ).getPhysicalNumberOfCells() == 0 );
assertEquals( s.getRow( 5 ).getPhysicalNumberOfCells(), 2 );
// Read the first file again
fin = new FileInputStream( filename );
wb = new HSSFWorkbook( fin );
fin.close();
s = wb.getSheetAt( 0 );
// Shift rows 3 and 4 up and write to temp file
s.shiftRows( 2, 3, -2 );
tempFile = File.createTempFile( "shift", "test.xls" );
fout = new FileOutputStream( tempFile );
wb.write( fout );
fout.close();
// Read file and test
fin = new FileInputStream( tempFile );
wb = new HSSFWorkbook( fin );
fin.close();
s = wb.getSheetAt( 0 );
assertEquals( s.getRow( 0 ).getPhysicalNumberOfCells(), 3 );
assertEquals( s.getRow( 1 ).getPhysicalNumberOfCells(), 4 );
assertTrue( s.getRow( 2 ) == null || s.getRow( 2 ).getPhysicalNumberOfCells() == 0 );
assertTrue( s.getRow( 3 ) == null || s.getRow( 3 ).getPhysicalNumberOfCells() == 0 );
assertEquals( s.getRow( 4 ).getPhysicalNumberOfCells(), 5 );
}
}