* @see org.apache.poi.hssf.dev.EFHSSF
*
* @author Andrew C. Oliver (acoliver at apache dot org)
- * @authro Carey Sublette (careysub@earthling.net)
+ * @author Carey Sublette (careysub@earthling.net)
*/
public class HSSFEventFactory
processEvents(req, in);
}
-
+
/**
* Processes a file into essentially record events.
*
* @param fs a POIFS filesystem containing your workbook
* @return numeric user-specified result code.
*/
-
+
public short abortableProcessWorkbookEvents(HSSFRequest req, POIFSFileSystem fs)
throws IOException, HSSFUserException
{
/**
* Processes a DocumentInputStream into essentially Record events.
- *
+ *
* If an <code>AbortableHSSFListener</code> causes a halt to processing during this call
- * the method will return just as with <code>abortableProcessEvents</code>, but no
+ * the method will return just as with <code>abortableProcessEvents</code>, but no
* user code or <code>HSSFUserException</code> will be passed back.
*
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem#createDocumentInputStream(String)
public void processEvents(HSSFRequest req, InputStream in)
throws IOException
- {
+ {
try
{
genericProcessEvents(req, in);
}
- catch (HSSFUserException hue)
+ catch (HSSFUserException hue)
{/*If an HSSFUserException user exception is thrown, ignore it.*/ }
}
-
+
/**
* Processes a DocumentInputStream into essentially Record events.
*/
public short abortableProcessEvents(HSSFRequest req, InputStream in)
- throws IOException, HSSFUserException
+ throws IOException, HSSFUserException
{
return genericProcessEvents(req, in);
- }
-
+ }
+
/**
* Processes a DocumentInputStream into essentially Record events.
*
import java.util.ArrayList;
import java.util.Iterator;
-import org.apache.poi.util.POILogFactory;
import org.apache.poi.hssf
.record.*; // normally I don't do this, buy we literally mean ALL
import org.apache.poi.hssf.record.formula.Ptg;
-import org.apache.poi.util.IntList;
-import org.apache.poi.util.POILogger;
+import org.apache.poi.util.*;
import org.apache.poi.hssf.record
.aggregates.*; // normally I don't do this, buy we literally mean ALL
public class Sheet
extends java.lang.Object
{
- public static final short LeftMargin = 0;
- public static final short RightMargin = 1;
- public static final short TopMargin = 2;
- public static final short BottomMargin = 3;
-
- protected ArrayList records = null;
- int preoffset = 0; // offset of the sheet in a new file
- int loc = 0;
- protected boolean containsLabels = false;
- ;
- protected int dimsloc = 0;
- protected DimensionsRecord dims;
- protected DefaultColWidthRecord defaultcolwidth = null;
- protected DefaultRowHeightRecord defaultrowheight = null;
- protected GridsetRecord gridset = null;
- protected PrintSetupRecord printSetup = null;
- protected HeaderRecord header = null;
- protected FooterRecord footer = null;
- protected PrintGridlinesRecord printGridlines = null;
- protected MergeCellsRecord merged = null;
- protected int mergedloc = 0;
- private static POILogger log =
- POILogFactory.getLogger(Sheet.class);
- private ArrayList columnSizes =
- null; // holds column info
- protected ValueRecordsAggregate cells = null;
- protected RowRecordsAggregate rows = null;
- private Iterator valueRecIterator = null;
- private Iterator rowRecIterator = null;
+ public static final short LeftMargin = 0;
+ public static final short RightMargin = 1;
+ public static final short TopMargin = 2;
+ public static final short BottomMargin = 3;
+
+ protected ArrayList records = null;
+ int preoffset = 0; // offset of the sheet in a new file
+ int loc = 0;
+ protected boolean containsLabels = false;
+ protected int dimsloc = 0;
+ protected DimensionsRecord dims;
+ protected DefaultColWidthRecord defaultcolwidth = null;
+ protected DefaultRowHeightRecord defaultrowheight = null;
+ protected GridsetRecord gridset = null;
+ protected PrintSetupRecord printSetup = null;
+ protected HeaderRecord header = null;
+ protected FooterRecord footer = null;
+ protected PrintGridlinesRecord printGridlines = null;
+ protected MergeCellsRecord merged = null;
+ protected int mergedloc = 0;
+ private static POILogger log = POILogFactory.getLogger(Sheet.class);
+ private ArrayList columnSizes = null; // holds column info
+ protected ValueRecordsAggregate cells = null;
+ protected RowRecordsAggregate rows = null;
+ private Iterator valueRecIterator = null;
+ private Iterator rowRecIterator = null;
+ protected int eofLoc = 0;
/**
* Creates new Sheet with no intialization --useless at this point
if (rec.getSid() == LabelRecord.sid)
{
- log.log(log.DEBUG, "Hit label record");
+ log.log(log.DEBUG, "Hit label record.");
retval.containsLabels = true;
}
else if (rec.getSid() == BOFRecord.sid)
{
bofEofNestingLevel++;
+ log.log(log.DEBUG, "Hit BOF record. Nesting increased to " + bofEofNestingLevel);
}
- else if ((rec.getSid() == EOFRecord.sid)
- && (--bofEofNestingLevel == 0))
+ else if (rec.getSid() == EOFRecord.sid)
{
- log.log(log.DEBUG, "Hit EOF record at ");
- records.add(rec);
- break;
+ --bofEofNestingLevel;
+ log.log(log.DEBUG, "Hit EOF record. Nesting decreased to " + bofEofNestingLevel);
+ if (bofEofNestingLevel == 0) {
+ records.add(rec);
+ retval.eofLoc = k;
+ break;
+ }
}
else if (rec.getSid() == DimensionsRecord.sid)
{
{
retval.defaultrowheight = ( DefaultRowHeightRecord ) rec;
}
- else if ( rec.isValue() )
+ else if ( rec.isValue() && bofEofNestingLevel == 1 )
{
if ( isfirstcell )
{
rec = null;
}
}
+ else if ( rec.getSid() == StringRecord.sid )
+ {
+ rec = null;
+ }
else if ( rec.getSid() == RowRecord.sid )
{
if ( isfirstrow )
}
}
retval.records = records;
+ if (retval.rows == null)
+ {
+ retval.rows = new RowRecordsAggregate();
+ }
+ if (retval.cells == null)
+ {
+ retval.cells = new ValueRecordsAggregate();
+ }
log.log(log.DEBUG, "sheet createSheet (existing file) exited");
return retval;
}
newrec.setColumn(oldrec.getColumn());
newrec.setXFIndex(oldrec.getXFIndex());
newrec.setSSTIndex(stringid);
- records.add(k, newrec);
+ records.add(k, newrec);
}
}
}
// }
for (int k = 0; k < records.size(); k++)
{
-
- // byte[] rec = (( byte [] ) bytes.get(k));
+// byte[] rec = (( byte [] ) bytes.get(k));
// System.arraycopy(rec, 0, data, offset + pos, rec.length);
- pos += (( Record ) records.get(k)).serialize(pos + offset,
- data); // rec.length;
+ Record record = (( Record ) records.get(k));
+
+ //uncomment to test record sizes
+// byte[] data2 = new byte[record.getRecordSize()];
+// record.serialize(0, data2 ); // rec.length;
+// if (LittleEndian.getUShort(data2, 2) != record.getRecordSize() - 4
+// && record instanceof RowRecordsAggregate == false && record instanceof ValueRecordsAggregate == false)
+// throw new RuntimeException("Blah!!!");
+
+ pos += record.serialize(pos + offset, data ); // rec.length;
+
}
log.log(log.DEBUG, "Sheet.serialize returning ");
return pos;
}
m.setMargin(size);
}
+
+ public int getEofLoc()
+ {
+ return eofLoc;
+ }
+
}
import org.apache.poi.util.LittleEndian;
-import java.util.ArrayList;
-
/**
* Title: DBCell Record (Currently read only. Not required.)
* Description: Used to find rows in blocks...TODO<P>
* sets offset from the start of this DBCellRecord to the start of the first cell in
* the next DBCell block.
*
- * @param rowoffset to the start of the first cell in the next DBCell block
+ * @param offset offset to the start of the first cell in the next DBCell block
*/
public void setRowOffset(int offset)
LittleEndian.putShort(data, 4 + offset, ( short ) getRow());
LittleEndian.putShort(data, 6 + offset, getColumn());
LittleEndian.putShort(data, 8 + offset, getXFIndex());
- LittleEndian.putDouble(data, 10 + offset, getValue());
+ LittleEndian.putDouble(data, 10 + offset, field_4_value);
LittleEndian.putShort(data, 18 + offset, getOptions());
LittleEndian.putInt(data, 20 + offset, field_6_zero);
LittleEndian.putShort(data, 24 + offset, getExpressionLength());
package org.apache.poi.hssf.record.aggregates;
-import org.apache.poi.hssf.record.CellValueRecordInterface;
-import org.apache.poi.hssf.record.Record;
-import org.apache.poi.hssf.record.UnknownRecord;
+import org.apache.poi.hssf.record.*;
import java.util.Iterator;
import java.util.List;
}*/
// XYLocator xy = new XYLocator(cell.getRow(), cell.getColumn());
- records.put(cell, cell);
+ Object o = records.put(cell, cell);
+
if ((cell.getColumn() < firstcell) || (firstcell == -1))
{
firstcell = cell.getColumn();
{
int k = 0;
+ FormulaRecordAggregate lastFormulaAggregate = null;
+
for (k = offset; k < records.size(); k++)
{
Record rec = ( Record ) records.get(k);
- if (!rec.isInValueSection() && !(rec instanceof UnknownRecord))
+ if (rec instanceof StringRecord == false && !rec.isInValueSection() && !(rec instanceof UnknownRecord))
{
break;
}
- if (rec.isValue())
+ if (rec instanceof FormulaRecord)
+ {
+ lastFormulaAggregate = new FormulaRecordAggregate((FormulaRecord)rec, null);
+ insertCell( lastFormulaAggregate );
+ }
+ else if (rec instanceof StringRecord)
+ {
+ lastFormulaAggregate.setStringRecord((StringRecord)rec);
+ }
+ else if (rec.isValue())
{
insertCell(( CellValueRecordInterface ) rec);
}
}
return pos - offset;
}
-
/**
* called by the constructor, should set class level fields. Should throw
* runtime exception for bad/icomplete data.
*/
public abstract String toFormulaString(SheetReferences refs);
/**
- * dump a debug representation (hexdump) to a strnig
+ * dump a debug representation (hexdump) to a string
*/
public String toDebugString() {
byte[] ba = new byte[getSize()];
String retval=null;
writeBytes(ba,0);
try {
- retval = org.apache.poi.util.HexDump.dump(ba,0,0);
+ retval = org.apache.poi.util.HexDump.dump(ba,0,0);
} catch (Exception e) {
e.printStackTrace();
}
import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.ExtendedFormatRecord;
+import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.util.SheetReferences;
break;
case CELL_TYPE_FORMULA :
- record = new FormulaRecord();
- (( FormulaRecord ) record).setColumn(col);
- (( FormulaRecord ) record).setRow(row);
- (( FormulaRecord ) record).setXFIndex(( short ) 0);
+ FormulaRecord formulaRecord = new FormulaRecord();
+ record = new FormulaRecordAggregate(formulaRecord,null);
+ formulaRecord.setColumn(col);
+ formulaRecord.setRow(row);
+ formulaRecord.setXFIndex(( short ) 0);
case CELL_TYPE_BOOLEAN :
record = new BoolErrRecord();
(( BoolErrRecord ) record).setColumn(col);
case CELL_TYPE_STRING :
stringValue =
- book
- .getSSTString((( LabelSSTRecord ) cval).getSSTIndex());
+ book.getSSTString( ( (LabelSSTRecord ) cval).getSSTIndex());
break;
case CELL_TYPE_BLANK :
break;
case CELL_TYPE_FORMULA :
- cellValue = (( FormulaRecord ) cval).getValue();
+ cellValue = (( FormulaRecordAggregate ) cval).getFormulaRecord().getValue();
break;
case CELL_TYPE_BOOLEAN :
retval = HSSFCell.CELL_TYPE_STRING;
break;
- case FormulaRecord.sid :
+ case FormulaRecordAggregate.sid :
retval = HSSFCell.CELL_TYPE_FORMULA;
break;
{
case CELL_TYPE_FORMULA :
- FormulaRecord frec = null;
+ FormulaRecordAggregate frec = null;
if (cellType != this.cellType)
{
- frec = new FormulaRecord();
+ frec = new FormulaRecordAggregate(new FormulaRecord(),null);
}
else
{
- frec = ( FormulaRecord ) record;
+ frec = ( FormulaRecordAggregate ) record;
}
frec.setColumn(getCellNum());
if (setValue)
{
- frec.setValue(getNumericCellValue());
+ frec.getFormulaRecord().setValue(getNumericCellValue());
}
frec.setXFIndex(( short ) cellStyle.getIndex());
frec.setRow(row);
}
else
{
- if ((cellType != CELL_TYPE_STRING)
- && (cellType != CELL_TYPE_FORMULA))
+ if ((cellType != CELL_TYPE_STRING ) && ( cellType != CELL_TYPE_FORMULA))
{
setCellType(CELL_TYPE_STRING, false);
}
setCellType(CELL_TYPE_BLANK,false);
} else {
setCellType(CELL_TYPE_FORMULA,false);
- FormulaRecord rec = (FormulaRecord) record;
- rec.setOptions(( short ) 2);
- rec.setValue(0);
+ FormulaRecordAggregate rec = (FormulaRecordAggregate) record;
+ rec.getFormulaRecord().setOptions(( short ) 2);
+ rec.getFormulaRecord().setValue(0);
rec.setXFIndex(( short ) 0x0f);
FormulaParser fp = new FormulaParser(formula+";",book);
fp.parse();
//System.out.println("got Ptgs " + ptg.length);
for (int k = 0; k < ptg.length; k++) {
size += ptg[ k ].getSize();
- rec.pushExpressionToken(ptg[ k ]);
+ rec.getFormulaRecord().pushExpressionToken(ptg[ k ]);
}
- rec.setExpressionLength(( short ) size);
+ rec.getFormulaRecord().setExpressionLength(( short ) size);
//Workbook.currentBook = null;
}
}
public String getCellFormula() {
//Workbook.currentBook=book;
SheetReferences refs = book.getSheetReferences();
- String retval = FormulaParser.toFormulaString(refs, ((FormulaRecord)record).getParsedExpression());
+ String retval = FormulaParser.toFormulaString(refs, ((FormulaRecordAggregate)record).getFormulaRecord().getParsedExpression());
//Workbook.currentBook=null;
return retval;
}
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);
}
workbook = Workbook.createWorkbook(records);
setPropertiesFromWorkbook(workbook);
- int numRecords = workbook.getNumRecords();
+ int recOffset = workbook.getNumRecords();
int sheetNum = 0;
- while (numRecords < records.size())
+ while (recOffset < records.size())
{
- Sheet sheet = Sheet.createSheet(records, sheetNum++, numRecords);
+ Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset );
- numRecords += sheet.getNumRecords();
+ recOffset = sheet.getEofLoc()+1;
sheet.convertLabelRecords(
workbook); // convert all LabelRecord records to LabelSSTRecord
HSSFSheet hsheet = new HSSFSheet(workbook, sheet);
{
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++)
// 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++)
{
- retval[k] = 0;
+ data[k] = 0;
}
- return retval;
+ return data;
}
public int addSSTString(String string)
public static void putDouble(final byte[] data, final int offset,
final double value) {
- putNumber(data, offset, Double.doubleToLongBits(value), DOUBLE_SIZE);
+ putNumber(data, offset, Double.doubleToRawLongBits(value), DOUBLE_SIZE);
}
{
56, 50, -113, -4, -63, -64, -13, 63, 76, -32, -42, -35, 60, -43, 3, 64
};
+ private static final byte[] _nan_double_array =
+ {
+ (byte)0x00, (byte)0x00, (byte)0x3C, (byte)0x00, (byte)0x20, (byte)0x04, (byte)0xFF, (byte)0xFF
+ };
private static final double[] _doubles =
{
- 1.23456, 2.47912
+ 1.23456, 2.47912, Double.NaN
};
/**
public void testGetDouble()
{
- assertEquals(_doubles[ 0 ], LittleEndian.getDouble(_double_array),
- 0.000001);
- assertEquals(_doubles[ 1 ], LittleEndian
- .getDouble(_double_array, LittleEndian.DOUBLE_SIZE), 0.000001);
+ assertEquals(_doubles[ 0 ], LittleEndian.getDouble(_double_array), 0.000001 );
+ assertEquals(_doubles[ 1 ], LittleEndian.getDouble( _double_array, LittleEndian.DOUBLE_SIZE), 0.000001);
+ assertTrue(Double.isNaN(LittleEndian.getDouble(_nan_double_array)));
+
+ // does not work. apparently nan does not always equal nan!
+ //assertEquals(_doubles[ 2 ], LittleEndian.getDouble(_nan_double_array), 0.000001);
+
+ double nan = LittleEndian.getDouble(_nan_double_array);
+ byte[] data = new byte[8];
+ LittleEndian.putDouble(data, nan);
+ for ( int i = 0; i < data.length; i++ )
+ {
+ byte b = data[i];
+ assertEquals(data[i], _nan_double_array[i]);
+ }
}
/**