From 4aca9d8ec2631a7591573226286171c4a9498d52 Mon Sep 17 00:00:00 2001 From: Nick Burch Date: Sat, 9 Aug 2008 09:52:35 +0000 Subject: [PATCH] Merged revisions 638786-638802,638805-638811,638813-638814,638816-639230,639233-639241,639243-639253,639255-639486,639488-639601,639603-639835,639837-639917,639919-640056,640058-640710,640712-641156,641158-641184,641186-641795,641797-641798,641800-641933,641935-641963,641965-641966,641968-641995,641997-642230,642232-642562,642564-642565,642568-642570,642572-642573,642576-642736,642739-642877,642879,642881-642890,642892-642903,642905-642945,642947-643624,643626-643653,643655-643669,643671,643673-643830,643832-643833,643835-644342,644344-644472,644474-644508,644510-645347,645349-645351,645353-645559,645561-645565,645568-645951,645953-646193,646195-646311,646313-646404,646406-646665,646667-646853,646855-646869,646871-647151,647153-647185,647187-647277,647279-647566,647568-647573,647575,647578-647711,647714-647737,647739-647823,647825-648155,648157-648202,648204-648273,648275,648277-648302,648304-648333,648335-648588,648590-648622,648625-648673,648675-649141,649144,649146-649556,649558-649795,649799,649801-649910,649912-649913,649915-650128,650131-650132,650134-650137,650140-650914,650916-651991,651993-652284,652286-652287,652289,652291,652293-652297,652299-652328,652330-652425,652427-652445,652447-652560,652562-652933,652935,652937-652993,652995-653116,653118-653124,653126-653483,653487-653519,653522-653550,653552-653607,653609-653667,653669-653674,653676-653814,653817-653830,653832-653891,653893-653944,653946-654055,654057-654355,654357-654365,654367-654648,654651-655215,655217-655277,655279-655281,655283-655911,655913-656212,656214,656216-656251,656253-656698,656700-656756,656758-656892,656894-657135,657137-657165,657168-657179,657181-657354,657356-657357,657359-657701,657703-657874,657876-658032,658034-658284,658286,658288-658301,658303-658307,658309-658321,658323-658335,658337-658348,658351,658353-658832,658834-658983,658985,658987-659066,659068-659402,659404-659428,659430-659451,659453-659454,659456-659461,659463-659477,659479-659524,659526-659571,659574,659576-660255,660257-660262,660264-660279,660281-660343,660345-660473,660475-660827,660829-660833,660835-660888,660890-663321,663323-663435,663437-663764,663766-663854,663856-664219,664221-664489,664494-664514,664516-668013,668015-668142,668144-668152,668154,668156-668256,668258,668260-669139,669141-669455,669457-669657,669659-669808,669810-670189,670191-671321,671323-672229,672231-672549,672551-672552,672554-672561,672563-672566,672568,672571-673049,673051-673852,673854-673862,673864-673986,673988-673996,673998-674347,674349-674890,674892-674910,674912-674936,674938-674952,674954-675078,675080-675085,675087-675217,675219-675660,675662-675670,675672-675716,675718-675726,675728-675733,675735-675775,675777-675782,675784,675786-675791,675794-675852,675854-676200,676202,676204,676206-676220,676222-676309,676311-676456,676458-676994,676996-677027,677030-677040,677042-677056,677058-677375,677377-677968,677970-677971,677973,677975-677994,677996-678286,678288-678538,678540-680393,680395-680469,680471-680529,680531-680852,680854-681529,681531-681571,681573-682224,682226,682228,682231-682281,682283-682335,682337-682507,682509,682512-682517,682519-682532,682534-682619,682622-682777,682779-682998,683000-683019,683021-683022,683024-683080,683082-683092,683094-683095,683097-683127,683129-683131,683133-683166,683168-683698,683700-683705,683707-683902 via svnmerge from https://svn.apache.org/repos/asf/poi/trunk ........ r683758 | josh | 2008-08-08 00:49:10 +0100 (Fri, 08 Aug 2008) | 1 line Consolidating ValueRecordsAggregate within RowRecordsAggregate ........ r683788 | josh | 2008-08-08 02:30:30 +0100 (Fri, 08 Aug 2008) | 1 line Converted RowRecordsAggregate to proper RecordAggregate ........ r683871 | josh | 2008-08-08 07:27:06 +0100 (Fri, 08 Aug 2008) | 1 line Extracting PageSettingsBlock from Sheet ........ r683880 | josh | 2008-08-08 07:56:06 +0100 (Fri, 08 Aug 2008) | 1 line Finished extracting PageSettingsBlock logic from Sheet ........ r683901 | josh | 2008-08-08 09:05:07 +0100 (Fri, 08 Aug 2008) | 1 line Patch 45577 - Added implementations for Excel functions NOW and TODAY, added property getters to HSSFConditionalFormattingRule ........ git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@684213 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/changes.xml | 3 +- src/documentation/content/xdocs/status.xml | 3 +- .../apache/poi/hssf/model/RecordOrderer.java | 30 +- .../apache/poi/hssf/model/RecordStream.java | 7 + src/java/org/apache/poi/hssf/model/Sheet.java | 943 ++++-------------- .../apache/poi/hssf/record/DBCellRecord.java | 6 + .../poi/hssf/record/PrintSetupRecord.java | 15 +- .../org/apache/poi/hssf/record/RowRecord.java | 32 +- .../record/aggregates/PageSettingsBlock.java | 525 ++++++++++ .../record/aggregates/RecordAggregate.java | 4 + .../aggregates/RowRecordsAggregate.java | 335 ++++--- .../aggregates/ValueRecordsAggregate.java | 186 ++-- .../hssf/record/formula/functions/Now.java | 57 +- .../hssf/record/formula/functions/Today.java | 63 +- .../apache/poi/hssf/usermodel/HSSFCell.java | 78 +- .../HSSFConditionalFormattingRule.java | 51 +- .../apache/poi/hssf/usermodel/HSSFRow.java | 88 +- .../apache/poi/hssf/usermodel/HSSFSheet.java | 166 ++- .../poi/hssf/usermodel/HSSFWorkbook.java | 16 +- .../org/apache/poi/ss/usermodel/Row.java | 3 +- .../org/apache/poi/hssf/model/TestSheet.java | 47 +- .../aggregates/TestValueRecordsAggregate.java | 24 +- .../poi/hssf/usermodel/SanityChecker.java | 16 +- .../apache/poi/hssf/usermodel/TestBugs.java | 481 +++++---- .../poi/hssf/usermodel/TestFormulas.java | 34 +- .../poi/hssf/usermodel/TestHSSFSheet.java | 6 +- .../poi/hssf/usermodel/TestWorkbook.java | 103 +- 27 files changed, 1579 insertions(+), 1743 deletions(-) create mode 100644 src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index bc9a75772..60cfd0f9f 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -54,7 +54,8 @@ Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx - 45582 - Fix for workbook streams with extra bytes trailing the EOFRecord + 45577 - Added implementations for Excel functions NOW and TODAY + 45582 - Fix for workbook streams with extra bytes trailing the EOFRecord 45537 - Include headers and footers (of slides and notes) in the extracted text from HSLF 45472 - Fixed incorrect default row height in OpenOffice 2.3 44692 - HSSFPicture.resize() stretched image when there was a text next to it diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 63926ec04..bc6acc93c 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -51,7 +51,8 @@ Created a common interface for handling Excel files, irrespective of if they are .xls or .xlsx - 45582 - Fix for workbook streams with extra bytes trailing the EOFRecord + 45577 - Added implementations for Excel functions NOW and TODAY + 45582 - Fix for workbook streams with extra bytes trailing the EOFRecord 45537 - Include headers and footers (of slides and notes) in the extracted text from HSLF 45472 - Fixed incorrect default row height in OpenOffice 2.3 44692 - HSSFPicture.resize() stretched image when there was a text next to it diff --git a/src/java/org/apache/poi/hssf/model/RecordOrderer.java b/src/java/org/apache/poi/hssf/model/RecordOrderer.java index ae445597d..887497a91 100644 --- a/src/java/org/apache/poi/hssf/model/RecordOrderer.java +++ b/src/java/org/apache/poi/hssf/model/RecordOrderer.java @@ -29,7 +29,6 @@ import org.apache.poi.hssf.record.DimensionsRecord; import org.apache.poi.hssf.record.EOFRecord; import org.apache.poi.hssf.record.GridsetRecord; import org.apache.poi.hssf.record.GutsRecord; -import org.apache.poi.hssf.record.HorizontalPageBreakRecord; import org.apache.poi.hssf.record.HyperlinkRecord; import org.apache.poi.hssf.record.IndexRecord; import org.apache.poi.hssf.record.IterationRecord; @@ -44,11 +43,11 @@ import org.apache.poi.hssf.record.SCLRecord; import org.apache.poi.hssf.record.SaveRecalcRecord; import org.apache.poi.hssf.record.SelectionRecord; import org.apache.poi.hssf.record.UncalcedRecord; -import org.apache.poi.hssf.record.VerticalPageBreakRecord; import org.apache.poi.hssf.record.WindowTwoRecord; import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable; import org.apache.poi.hssf.record.aggregates.DataValidityTable; import org.apache.poi.hssf.record.aggregates.MergedCellsTable; +import org.apache.poi.hssf.record.aggregates.PageSettingsBlock; /** * Finds correct insert positions for records in workbook streams

@@ -88,28 +87,25 @@ final class RecordOrderer { if (recClass == GutsRecord.class) { return getGutsRecordInsertPos(records); } - if (recClass == HorizontalPageBreakRecord.class) { - return getPageBreakRecordInsertPos(records, true); - } - if (recClass == VerticalPageBreakRecord.class) { - return getPageBreakRecordInsertPos(records, false); + if (recClass == PageSettingsBlock.class) { + return getPageBreakRecordInsertPos(records); } throw new RuntimeException("Unexpected record class (" + recClass.getName() + ")"); } - private static int getPageBreakRecordInsertPos(List records, boolean isHorizonal) { + private static int getPageBreakRecordInsertPos(List records) { int dimensionsIndex = getDimensionsIndex(records); int i = dimensionsIndex-1; while (i > 0) { i--; Object rb = records.get(i); - if (isPageBreakPriorRecord(rb, isHorizonal)) { + if (isPageBreakPriorRecord(rb)) { return i+1; } } throw new RuntimeException("Did not find insert point for GUTS"); } - private static boolean isPageBreakPriorRecord(Object rb, boolean newRecIsHorizontal) { + private static boolean isPageBreakPriorRecord(Object rb) { if (rb instanceof Record) { Record record = (Record) rb; switch (record.getSid()) { @@ -132,19 +128,7 @@ final class RecordOrderer { case DefaultRowHeightRecord.sid: case 0x0081: // SHEETPR return true; - } - switch (record.getSid()) { - // page settings block - case HorizontalPageBreakRecord.sid: - if (!newRecIsHorizontal) { - return true; - } - return false; - case VerticalPageBreakRecord.sid: - return false; - // next is case HeaderRecord.sid: case FooterRecord.sid: - // then more records in page settings block - + // next is the 'Worksheet Protection Block' } } return false; diff --git a/src/java/org/apache/poi/hssf/model/RecordStream.java b/src/java/org/apache/poi/hssf/model/RecordStream.java index bec1c40e6..1a0687395 100755 --- a/src/java/org/apache/poi/hssf/model/RecordStream.java +++ b/src/java/org/apache/poi/hssf/model/RecordStream.java @@ -59,6 +59,13 @@ public final class RecordStream { return _list.get(_nextIndex).getClass(); } + public int peekNextSid() { + if(_nextIndex >= _list.size()) { + return -1; + } + return ((Record)_list.get(_nextIndex)).getSid(); + } + public int getCountRead() { return _countRead; } diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java index 5e8faa092..750dbca23 100644 --- a/src/java/org/apache/poi/hssf/model/Sheet.java +++ b/src/java/org/apache/poi/hssf/model/Sheet.java @@ -22,7 +22,6 @@ import java.util.Iterator; import java.util.List; import org.apache.poi.hssf.record.BOFRecord; -import org.apache.poi.hssf.record.BottomMarginRecord; import org.apache.poi.hssf.record.CFHeaderRecord; import org.apache.poi.hssf.record.CalcCountRecord; import org.apache.poi.hssf.record.CalcModeRecord; @@ -37,52 +36,38 @@ import org.apache.poi.hssf.record.DimensionsRecord; import org.apache.poi.hssf.record.DrawingRecord; import org.apache.poi.hssf.record.EOFRecord; import org.apache.poi.hssf.record.EscherAggregate; -import org.apache.poi.hssf.record.FooterRecord; import org.apache.poi.hssf.record.GridsetRecord; import org.apache.poi.hssf.record.GutsRecord; -import org.apache.poi.hssf.record.HCenterRecord; -import org.apache.poi.hssf.record.HeaderRecord; -import org.apache.poi.hssf.record.HorizontalPageBreakRecord; import org.apache.poi.hssf.record.IndexRecord; import org.apache.poi.hssf.record.IterationRecord; -import org.apache.poi.hssf.record.LeftMarginRecord; -import org.apache.poi.hssf.record.Margin; import org.apache.poi.hssf.record.MergeCellsRecord; import org.apache.poi.hssf.record.ObjRecord; import org.apache.poi.hssf.record.ObjectProtectRecord; -import org.apache.poi.hssf.record.PageBreakRecord; import org.apache.poi.hssf.record.PaneRecord; import org.apache.poi.hssf.record.PasswordRecord; import org.apache.poi.hssf.record.PrintGridlinesRecord; import org.apache.poi.hssf.record.PrintHeadersRecord; -import org.apache.poi.hssf.record.PrintSetupRecord; import org.apache.poi.hssf.record.ProtectRecord; import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.RecordBase; import org.apache.poi.hssf.record.RefModeRecord; -import org.apache.poi.hssf.record.RightMarginRecord; import org.apache.poi.hssf.record.RowRecord; import org.apache.poi.hssf.record.SCLRecord; import org.apache.poi.hssf.record.SaveRecalcRecord; import org.apache.poi.hssf.record.ScenarioProtectRecord; import org.apache.poi.hssf.record.SelectionRecord; -import org.apache.poi.hssf.record.SharedFormulaRecord; import org.apache.poi.hssf.record.StringRecord; -import org.apache.poi.hssf.record.TopMarginRecord; import org.apache.poi.hssf.record.UncalcedRecord; -import org.apache.poi.hssf.record.VCenterRecord; -import org.apache.poi.hssf.record.VerticalPageBreakRecord; import org.apache.poi.hssf.record.WSBoolRecord; import org.apache.poi.hssf.record.WindowTwoRecord; import org.apache.poi.hssf.record.aggregates.CFRecordsAggregate; import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate; import org.apache.poi.hssf.record.aggregates.ConditionalFormattingTable; import org.apache.poi.hssf.record.aggregates.DataValidityTable; -import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.aggregates.MergedCellsTable; +import org.apache.poi.hssf.record.aggregates.PageSettingsBlock; import org.apache.poi.hssf.record.aggregates.RecordAggregate; import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; -import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate; import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.hssf.util.PaneInformation; @@ -121,37 +106,33 @@ public final class Sheet implements Model { protected ArrayList records = null; int preoffset = 0; // offset of the sheet in a new file - int loc = 0; protected int dimsloc = -1; // TODO - is it legal for dims record to be missing? - protected DimensionsRecord dims; + protected PrintGridlinesRecord printGridlines = null; + protected GridsetRecord gridset = null; + private GutsRecord _gutsRecord; protected DefaultColWidthRecord defaultcolwidth = null; protected DefaultRowHeightRecord defaultrowheight = null; - protected GridsetRecord gridset = null; - private GutsRecord _gutsRecord; - protected PrintSetupRecord printSetup = null; - protected HeaderRecord header = null; - protected FooterRecord footer = null; - protected PrintGridlinesRecord printGridlines = null; - protected WindowTwoRecord windowTwo = null; - protected Margin[] margins = null; - private MergedCellsTable _mergedCellsTable; - protected SelectionRecord selection = null; - /** always present in this POI object, not always written to Excel file */ - /*package*/ColumnInfoRecordsAggregate _columnInfos; - protected ValueRecordsAggregate cells = null; - protected RowRecordsAggregate _rowsAggregate = null; - private Iterator valueRecIterator = null; - private Iterator rowRecIterator = null; - protected int eofLoc = 0; + private PageSettingsBlock _psBlock; + + // 'Worksheet Protection Block' protected ProtectRecord protect = null; - protected PageBreakRecord _rowBreaksRecord; - protected PageBreakRecord _columnBreaksRecord; - private DataValidityTable _dataValidityTable= null; protected ObjectProtectRecord objprotect = null; protected ScenarioProtectRecord scenprotect = null; protected PasswordRecord password = null; + + protected WindowTwoRecord windowTwo = null; + protected SelectionRecord selection = null; + private MergedCellsTable _mergedCellsTable; + /** always present in this POI object, not always written to Excel file */ + /*package*/ColumnInfoRecordsAggregate _columnInfos; + protected DimensionsRecord dims; + protected RowRecordsAggregate _rowsAggregate = null; + private DataValidityTable _dataValidityTable= null; private ConditionalFormattingTable condFormatting; + protected int eofLoc = 0; + private Iterator rowRecIterator = null; + /** Add an UncalcedRecord if not true indicating formulas have not been calculated */ protected boolean _isUncalced = false; @@ -196,17 +177,8 @@ public final class Sheet implements Model { boolean isfirstcell = true; int bofEofNestingLevel = 0; - for (int k = offset; k < recs.size(); k++) - { + for (int k = offset; k < recs.size(); k++) { Record rec = ( Record ) recs.get(k); - if (rec.isValue() != (rec instanceof CellValueRecordInterface)) { - if (rec instanceof SharedFormulaRecord) { - - } else { - "".length(); - } - } - if ( rec.getSid() == DBCellRecord.sid ) { continue; } @@ -239,23 +211,51 @@ public final class Sheet implements Model { retval._dataValidityTable = new DataValidityTable(rs); k += rs.getCountRead() - 1; // TODO - convert this method result to be zero based records.add(retval._dataValidityTable); - continue; // TODO + continue; } - if ( rec.getSid() == RowRecord.sid ) - { + // TODO construct RowRecordsAggregate from RecordStream + if ( rec.getSid() == RowRecord.sid ) { RowRecord row = (RowRecord)rec; if (retval._rowsAggregate == null) { retval._rowsAggregate = new RowRecordsAggregate(); records.add(retval._rowsAggregate); //only add the aggregate once - } + } retval._rowsAggregate.insertRow(row); continue; } + if ( rec.isValue() && bofEofNestingLevel == 1 ) { + if (isfirstcell) { + isfirstcell = false; + if (retval._rowsAggregate == null) { + retval._rowsAggregate = new RowRecordsAggregate(); + records.add(retval._rowsAggregate); //only add the aggregate once + } + retval._rowsAggregate.constructCellValues( k, recs ); + } + continue; + } + + if (PageSettingsBlock.isComponentRecord(rec.getSid())) { + RecordStream rs = new RecordStream(recs, k); + PageSettingsBlock psb = new PageSettingsBlock(rs); + if (bofEofNestingLevel == 1) { + if (retval._psBlock == null) { + retval._psBlock = psb; + } else { + // more than one 'Page Settings Block' at nesting level 1 ? + // apparently this happens in about 15 test sample files + } + } + records.add(psb); + k += rs.getCountRead()-1; + continue; + } + if (rec.getSid() == MergeCellsRecord.sid) { RecordStream rs = new RecordStream(recs, k); retval._mergedCellsTable = new MergedCellsTable(rs); records.add(retval._mergedCellsTable); - continue; // TODO + continue; } if (rec.getSid() == BOFRecord.sid) @@ -290,21 +290,7 @@ public final class Sheet implements Model { retval.dims = ( DimensionsRecord ) rec; retval.dimsloc = records.size(); } - else if ( rec.isValue() && bofEofNestingLevel == 1 ) - { - if ( isfirstcell ) - { - retval.cells = new ValueRecordsAggregate(); - rec = retval.cells; - retval.cells.construct( k, recs ); - isfirstcell = false; - } - else - { - rec = null; - } - } - else if (rec.getSid() == DefaultColWidthRecord.sid) + else if (rec.getSid() == DefaultColWidthRecord.sid) { retval.defaultcolwidth = ( DefaultColWidthRecord ) rec; } @@ -320,34 +306,6 @@ public final class Sheet implements Model { { retval.gridset = (GridsetRecord) rec; } - else if ( rec.getSid() == HeaderRecord.sid && bofEofNestingLevel == 1) - { - retval.header = (HeaderRecord) rec; - } - else if ( rec.getSid() == FooterRecord.sid && bofEofNestingLevel == 1) - { - retval.footer = (FooterRecord) rec; - } - else if ( rec.getSid() == PrintSetupRecord.sid && bofEofNestingLevel == 1) - { - retval.printSetup = (PrintSetupRecord) rec; - } - else if ( rec.getSid() == LeftMarginRecord.sid) - { - retval.getMargins()[LeftMargin] = (LeftMarginRecord) rec; - } - else if ( rec.getSid() == RightMarginRecord.sid) - { - retval.getMargins()[RightMargin] = (RightMarginRecord) rec; - } - else if ( rec.getSid() == TopMarginRecord.sid) - { - retval.getMargins()[TopMargin] = (TopMarginRecord) rec; - } - else if ( rec.getSid() == BottomMarginRecord.sid) - { - retval.getMargins()[BottomMargin] = (BottomMarginRecord) rec; - } else if ( rec.getSid() == SelectionRecord.sid ) { retval.selection = (SelectionRecord) rec; @@ -372,26 +330,14 @@ public final class Sheet implements Model { { retval.password = (PasswordRecord) rec; } - else if (rec.getSid() == HorizontalPageBreakRecord.sid) - { - retval._rowBreaksRecord = (HorizontalPageBreakRecord)rec; - } - else if (rec.getSid() == VerticalPageBreakRecord.sid) - { - retval._columnBreaksRecord = (VerticalPageBreakRecord)rec; - } - if (rec != null) - { - records.add(rec); - } + records.add(rec); } if (retval.dimsloc < 0) { - throw new RuntimeException("DimensionsRecord was not found"); + throw new RuntimeException("DimensionsRecord was not found"); } retval.records = records; retval.checkRows(); - retval.checkCells(); if (log.check( POILogger.DEBUG )) log.log(POILogger.DEBUG, "sheet createSheet (existing file) exited"); return retval; @@ -399,15 +345,16 @@ public final class Sheet implements Model { private static final class RecordCloner implements RecordVisitor { - private final List _destList; + private final List _destList; - public RecordCloner(List destList) { - _destList = destList; - } - public void visitRecord(Record r) { - _destList.add(r.clone()); - } + public RecordCloner(List destList) { + _destList = destList; + } + public void visitRecord(Record r) { + _destList.add(r.clone()); + } } + /** * Clones the low level records of this sheet and returns the new sheet instance. * This method is implemented by adding methods for deep cloning to all records that @@ -415,57 +362,18 @@ public final class Sheet implements Model { * When adding a new record, implement a public clone method if and only if the record * belongs to a sheet. */ - public Sheet cloneSheet() - { - ArrayList clonedRecords = new ArrayList(this.records.size()); - for (int i=0; i= mrt.getNumberOfMergedRegions()) { - return; - } - mrt.remove(index); + if (index >= mrt.getNumberOfMergedRegions()) { + return; + } + mrt.remove(index); } public CellRangeAddress getMergedRegionAt(int index) { //safety checks MergedCellsTable mrt = getMergedRecords(); - if (index >= mrt.getNumberOfMergedRegions()) { - return null; - } - return mrt.get(index); + if (index >= mrt.getNumberOfMergedRegions()) { + return null; + } + return mrt.get(index); } public int getNumMergedRegions() { return getMergedRecords().getNumberOfMergedRegions(); } private ConditionalFormattingTable getConditionalFormattingTable() { - if (condFormatting == null) { - condFormatting = new ConditionalFormattingTable(); - RecordOrderer.addNewSheetRecord(records, condFormatting); - } - return condFormatting; + if (condFormatting == null) { + condFormatting = new ConditionalFormattingTable(); + RecordOrderer.addNewSheetRecord(records, condFormatting); + } + return condFormatting; } - public int addConditionalFormatting(CFRecordsAggregate cfAggregate) { - ConditionalFormattingTable cft = getConditionalFormattingTable(); + public int addConditionalFormatting(CFRecordsAggregate cfAggregate) { + ConditionalFormattingTable cft = getConditionalFormattingTable(); return cft.add(cfAggregate); } public void removeConditionalFormatting(int index) { - getConditionalFormattingTable().remove(index); + getConditionalFormattingTable().remove(index); } public CFRecordsAggregate getCFRecordsAggregateAt(int index) { - return getConditionalFormattingTable().get(index); + return getConditionalFormattingTable().get(index); } public int getNumConditionalFormattings() { return getConditionalFormattingTable().size(); } - /** - * Returns the number of low level binary records in this sheet. This adjusts things for the so called - * AgregateRecords. - * - * @see org.apache.poi.hssf.record.Record - */ - - public int getNumRecords() - { - checkCells(); - checkRows(); - if (log.check( POILogger.DEBUG )) - { - log.log(POILogger.DEBUG, "Sheet.getNumRecords"); - log.logFormatted(POILogger.DEBUG, "returning % + % + % - 2 = %", new int[] - { - records.size(), cells.getPhysicalNumberOfCells(), - _rowsAggregate.getPhysicalNumberOfRows(), - records.size() + cells.getPhysicalNumberOfCells() - + _rowsAggregate.getPhysicalNumberOfRows() - 2 - }); - } - return records.size() + cells.getPhysicalNumberOfCells() - + _rowsAggregate.getPhysicalNumberOfRows() - 2; - } - /** * Per an earlier reported bug in working with Andy Khan's excel read library. This * sets the values in the sheet's DimensionsRecord object to be correct. Excel doesn't @@ -711,42 +564,6 @@ public final class Sheet implements Model { log.log(POILogger.DEBUG, "Sheet.setDimensions exiting"); } - /** - * set the locator for where we should look for the next value record. The - * algorithm will actually start here and find the correct location so you - * can set this to 0 and watch performance go down the tubes but it will work. - * After a value is set this is automatically advanced. Its also set by the - * create method. So you probably shouldn't mess with this unless you have - * a compelling reason why or the help for the method you're calling says so. - * Check the other methods for whether they care about - * the loc pointer. Many of the "modify" and "remove" methods re-initialize this - * to "dimsloc" which is the location of the Dimensions Record and presumably the - * start of the value section (at or around 19 dec). - * - * @param loc the record number to start at - * - */ - - public void setLoc(int loc) - { - valueRecIterator = null; - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "sheet.setLoc(): " + loc); - this.loc = loc; - } - - /** - * Returns the location pointer to the first record to look for when adding rows/values - * - */ - - public int getLoc() - { - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "sheet.getLoc():" + loc); - return loc; - } - /** * Set the preoffset when using DBCELL records (currently unused) - this is * the position of this sheet within the whole file. @@ -790,7 +607,7 @@ public final class Sheet implements Model { for (int k = 0; k < records.size(); k++) { - RecordBase record = (RecordBase) records.get(k); + RecordBase record = (RecordBase) records.get(k); // Don't write out UncalcedRecord entries, as // we handle those specially just below @@ -800,13 +617,7 @@ public final class Sheet implements Model { // Once the rows have been found in the list of records, start // writing out the blocked row information. This includes the DBCell references - if (record instanceof RowRecordsAggregate) { - pos += ((RowRecordsAggregate)record).serialize(pos, data, cells); - } else if (record instanceof ValueRecordsAggregate) { - //Do nothing here. The records were serialized during the RowRecordAggregate block serialization - } else { - pos += record.serialize(pos, data ); - } + pos += record.serialize(pos, data); // If the BOF record was just serialized then add the IndexRecord if (record instanceof BOFRecord) { @@ -838,13 +649,7 @@ public final class Sheet implements Model { * @param indexRecordOffset also happens to be the end of the BOF record * @return the size of the serialized INDEX record */ - private int serializeIndexRecord(final int bofRecordIndex, final int indexRecordOffset, - byte[] data) { - IndexRecord index = new IndexRecord(); - index.setFirstRow(_rowsAggregate.getFirstRowNum()); - index.setLastRowAdd1(_rowsAggregate.getLastRowNum() + 1); - // Calculate the size of the records from the end of the BOF - // and up to the RowRecordsAggregate... + private int serializeIndexRecord(int bofRecordIndex, int indexRecordOffset, byte[] data) { // 'initial sheet records' are between INDEX and first ROW record. int sizeOfInitialSheetRecords = 0; @@ -862,32 +667,7 @@ public final class Sheet implements Model { if (_isUncalced) { sizeOfInitialSheetRecords += UncalcedRecord.getStaticRecordSize(); } - - // Add the references to the DBCells in the IndexRecord (one for each block) - // Note: The offsets are relative to the Workbook BOF. Assume that this is - // 0 for now..... - - int blockCount = _rowsAggregate.getRowBlockCount(); - // Calculate the size of this IndexRecord - int indexRecSize = IndexRecord.getRecordSizeForBlockCount(blockCount); - - int currentOffset = indexRecordOffset + indexRecSize + sizeOfInitialSheetRecords; - - for (int block = 0; block < blockCount; block++) { - // each row-block has a DBCELL record. - // The offset of each DBCELL record needs to be updated in the INDEX record - - // account for row records in this row-block - currentOffset += _rowsAggregate.getRowBlockSize(block); - // account for cell value records after those - currentOffset += null == cells ? 0 : cells.getRowCellBlockSize(_rowsAggregate - .getStartRowNumberForBlock(block), _rowsAggregate.getEndRowNumberForBlock(block)); - - // currentOffset is now the location of the DBCELL record for this row-block - index.addDbcell(currentOffset); - // Add space required to write the DBCELL record (whose reference was just added). - currentOffset += (8 + (_rowsAggregate.getRowCountForBlock(block) * 2)); - } + IndexRecord index = _rowsAggregate.createIndexRecord(indexRecordOffset, sizeOfInitialSheetRecords); return index.serialize(indexRecordOffset, data); } @@ -911,15 +691,10 @@ public final class Sheet implements Model { * @param row the row to add the cell value to * @param col the cell value record itself. */ - public void addValueRecord(int row, CellValueRecordInterface col) - { - checkCells(); - if(log.check(POILogger.DEBUG)) - { - log.logFormatted(POILogger.DEBUG, "add value record row,loc %,%", new int[] - { - row, loc - }); + public void addValueRecord(int row, CellValueRecordInterface col) { + + if(log.check(POILogger.DEBUG)) { + log.log(POILogger.DEBUG, "add value record row" + row); } DimensionsRecord d = ( DimensionsRecord ) records.get(getDimsLoc()); @@ -931,7 +706,7 @@ public final class Sheet implements Model { { d.setFirstCol(col.getColumn()); } - cells.insertCell(col); + _rowsAggregate.insertCell(col); } /** @@ -943,13 +718,11 @@ public final class Sheet implements Model { * @param col - a record supporting the CellValueRecordInterface. * @see org.apache.poi.hssf.record.CellValueRecordInterface */ - public void removeValueRecord(int row, CellValueRecordInterface col) - { - checkCells(); + public void removeValueRecord(int row, CellValueRecordInterface col) { + log.logFormatted(POILogger.DEBUG, "remove value record row,dimsloc %,%", new int[]{row, dimsloc} ); - loc = dimsloc; - cells.removeCell(col); + _rowsAggregate.removeCell(col); } /** @@ -962,10 +735,8 @@ public final class Sheet implements Model { * be added. */ - public void replaceValueRecord(CellValueRecordInterface newval) - { - checkCells(); - setLoc(dimsloc); + public void replaceValueRecord(CellValueRecordInterface newval) { + if (log.check( POILogger.DEBUG )) log.log(POILogger.DEBUG, "replaceValueRecord "); //The ValueRecordsAggregate use a tree map underneath. @@ -973,8 +744,8 @@ public final class Sheet implements Model { //key and the value, if we dont do a remove, then //the previous instance of the key is retained, effectively using //double the memory - cells.removeCell(newval); - cells.insertCell(newval); + _rowsAggregate.removeCell(newval); + _rowsAggregate.insertCell(newval); } /** @@ -1005,11 +776,12 @@ public final class Sheet implements Model { { d.setFirstRow(row.getRowNumber()); } - //IndexRecord index = null; - //If the row exists remove it, so that any cells attached to the row are removed - RowRecord existingRow = _rowsAggregate.getRow(row.getRowNumber()); - if (existingRow != null) - _rowsAggregate.removeRow(existingRow); + + //If the row exists remove it, so that any cells attached to the row are removed + RowRecord existingRow = _rowsAggregate.getRow(row.getRowNumber()); + if (existingRow != null) { + _rowsAggregate.removeRow(existingRow); + } _rowsAggregate.insertRow(row); @@ -1024,12 +796,8 @@ public final class Sheet implements Model { * * @param row the row record to remove */ - - public void removeRow(RowRecord row) - { + public void removeRow(RowRecord row) { checkRows(); - - setLoc(getDimsLoc()); _rowsAggregate.removeRow(row); } @@ -1047,20 +815,8 @@ public final class Sheet implements Model { * @return CellValueRecordInterface representing the next value record or NULL if there are no more * @see #setLoc(int) */ - - public CellValueRecordInterface getNextValueRecord() - { - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "getNextValue loc= " + loc); - if (valueRecIterator == null) - { - valueRecIterator = cells.getIterator(); - } - if (!valueRecIterator.hasNext()) - { - return null; - } - return ( CellValueRecordInterface ) valueRecIterator.next(); + public CellValueRecordInterface[] getValueRecords() { + return _rowsAggregate.getValueRecords(); } /** @@ -1077,11 +833,7 @@ public final class Sheet implements Model { * @see #setLoc(int) * */ - - public RowRecord getNextRow() - { - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "getNextRow loc= " + loc); + public RowRecord getNextRow() { if (rowRecIterator == null) { rowRecIterator = _rowsAggregate.getIterator(); @@ -1110,8 +862,6 @@ public final class Sheet implements Model { * */ public RowRecord getRow(int rownum) { - if (log.check( POILogger.DEBUG )) - log.log(POILogger.DEBUG, "getNextRow loc= " + loc); return _rowsAggregate.getRow(rownum); } @@ -1235,13 +985,13 @@ public final class Sheet implements Model { return retval; } private GutsRecord getGutsRecord() { - if (_gutsRecord == null) { - GutsRecord result = createGuts(); - RecordOrderer.addNewSheetRecord(records, result); - _gutsRecord = result; - } + if (_gutsRecord == null) { + GutsRecord result = createGuts(); + RecordOrderer.addNewSheetRecord(records, result); + _gutsRecord = result; + } - return _gutsRecord; + return _gutsRecord; } /** @@ -1266,70 +1016,6 @@ public final class Sheet implements Model { return retval; } - /** - * creates the Header Record and sets it to nothing/0 length - */ - private static HeaderRecord createHeader() { - HeaderRecord retval = new HeaderRecord(); - - retval.setHeaderLength(( byte ) 0); - retval.setHeader(null); - return retval; - } - - /** - * creates the Footer Record and sets it to nothing/0 length - */ - private static FooterRecord createFooter() { - FooterRecord retval = new FooterRecord(); - - retval.setFooterLength(( byte ) 0); - retval.setFooter(null); - return retval; - } - - /** - * creates the HCenter Record and sets it to false (don't horizontally center) - */ - private static HCenterRecord createHCenter() { - HCenterRecord retval = new HCenterRecord(); - - retval.setHCenter(false); - return retval; - } - - /** - * creates the VCenter Record and sets it to false (don't horizontally center) - */ - private static VCenterRecord createVCenter() { - VCenterRecord retval = new VCenterRecord(); - - retval.setVCenter(false); - return retval; - } - - /** - * creates the PrintSetup Record and sets it to defaults and marks it invalid - * @see org.apache.poi.hssf.record.PrintSetupRecord - * @see org.apache.poi.hssf.record.Record - * @return record containing a PrintSetupRecord - */ - private static PrintSetupRecord createPrintSetup() { - PrintSetupRecord retval = new PrintSetupRecord(); - - retval.setPaperSize(( short ) 1); - retval.setScale(( short ) 100); - retval.setPageStart(( short ) 1); - retval.setFitWidth(( short ) 1); - retval.setFitHeight(( short ) 1); - retval.setOptions(( short ) 2); - retval.setHResolution(( short ) 300); - retval.setVResolution(( short ) 300); - retval.setHeaderMargin( 0.5); - retval.setFooterMargin( 0.5); - retval.setCopies(( short ) 0); - return retval; - } /** * creates the DefaultColWidth Record and sets it to 8 @@ -1418,7 +1104,7 @@ public final class Sheet implements Model { ColumnInfoRecord ci = _columnInfos.findColumnInfo(columnIndex); if (ci != null) { - return ci.getColumnWidth(); + return ci.getColumnWidth(); } //default column width is measured in characters //multiply @@ -1443,18 +1129,18 @@ public final class Sheet implements Model { ColumnInfoRecord ci = _columnInfos.findColumnInfo(columnIndex); if (ci != null) { return ci.getXFIndex(); - } - return 0xF; - } + } + return 0xF; + } /** - * set the width for a given column in 1/256th of a character width units - * - * @param column - - * the column number - * @param width - * (in units of 1/256th of a character width) - */ + * set the width for a given column in 1/256th of a character width units + * + * @param column - + * the column number + * @param width + * (in units of 1/256th of a character width) + */ public void setColumnWidth(short column, short width) { setColumn( column, new Short(width), null, null, null); } @@ -1468,11 +1154,11 @@ public final class Sheet implements Model { * @return whether the column is hidden or not. */ public boolean isColumnHidden(short columnIndex) { - ColumnInfoRecord cir = _columnInfos.findColumnInfo(columnIndex); - if (cir == null) { - return false; - } - return cir.getHidden(); + ColumnInfoRecord cir = _columnInfos.findColumnInfo(columnIndex); + if (cir == null) { + return false; + } + return cir.getHidden(); } /** @@ -1659,12 +1345,8 @@ public final class Sheet implements Model { /** * in the event the record is a dimensions record, resets both the loc index and dimsloc index */ - - public void checkDimsLoc(Record rec, int recloc) - { - if (rec.getSid() == DimensionsRecord.sid) - { - loc = recloc; + public void checkDimsLoc(Record rec, int recloc) { + if (rec.getSid() == DimensionsRecord.sid) { dimsloc = recloc; } } @@ -1672,32 +1354,21 @@ public final class Sheet implements Model { /** * @return the serialized size of this sheet */ - public int getSize() - { + public int getSize() { int retval = 0; for ( int k = 0; k < records.size(); k++) { - RecordBase record = (RecordBase) records.get(k); + RecordBase record = (RecordBase) records.get(k); if (record instanceof UncalcedRecord) { // skip the UncalcedRecord if present, it's only encoded if the isUncalced flag is set continue; } retval += record.getRecordSize(); } + // add space for IndexRecord if needed if (_rowsAggregate != null) { - // Add space for the IndexRecord and DBCell records - final int nBlocks = _rowsAggregate.getRowBlockCount(); - int nRows = 0; - if (cells != null) { - for (Iterator itr = _rowsAggregate.getIterator(); itr.hasNext();) { - RowRecord row = (RowRecord)itr.next(); - if (cells.rowHasCells(row.getRowNumber())) { - nRows++; - } - } - } - retval += IndexRecord.getRecordSizeForBlockCount(nBlocks); - retval += DBCellRecord.calculateSizeOfRecords(nBlocks, nRows); + // rowsAggregate knows how to make the index record + retval += IndexRecord.getRecordSizeForBlockCount(_rowsAggregate.getRowBlockCount()); } // Add space for UncalcedRecord if (_isUncalced) { @@ -1726,11 +1397,11 @@ public final class Sheet implements Model { public Record findFirstRecordBySid(short sid) { - int ix = findFirstRecordLocBySid(sid); - if (ix < 0) { - return null; - } - return (Record) records.get(ix); + int ix = findFirstRecordLocBySid(sid); + if (ix < 0) { + return null; + } + return (Record) records.get(ix); } /** @@ -1765,9 +1436,9 @@ public final class Sheet implements Model { public int findFirstRecordLocBySid( short sid ) { // TODO - remove this method int max = records.size(); for (int i=0; i< max; i++) { - Object rb = records.get(i); + Object rb = records.get(i); if (!(rb instanceof Record)) { - continue; + continue; } Record record = (Record) rb; if (record.getSid() == sid) { @@ -1777,63 +1448,10 @@ public final class Sheet implements Model { return -1; } - /** - * Returns the HeaderRecord. - * @return HeaderRecord for the sheet. - */ - public HeaderRecord getHeader () - { - return header; - } - public WindowTwoRecord getWindowTwo() { return windowTwo; } - /** - * Sets the HeaderRecord. - * @param newHeader The new HeaderRecord for the sheet. - */ - public void setHeader (HeaderRecord newHeader) - { - header = newHeader; - } - - /** - * Returns the FooterRecord. - * @return FooterRecord for the sheet. - */ - public FooterRecord getFooter () - { - return footer; - } - - /** - * Sets the FooterRecord. - * @param newFooter The new FooterRecord for the sheet. - */ - public void setFooter (FooterRecord newFooter) - { - footer = newFooter; - } - - /** - * Returns the PrintSetupRecord. - * @return PrintSetupRecord for the sheet. - */ - public PrintSetupRecord getPrintSetup () - { - return printSetup; - } - - /** - * Sets the PrintSetupRecord. - * @param newPrintSetup The new PrintSetupRecord for the sheet. - */ - public void setPrintSetup (PrintSetupRecord newPrintSetup) - { - printSetup = newPrintSetup; - } - + /** * Returns the PrintGridlinesRecord. * @return PrintGridlinesRecord for the sheet. @@ -1860,65 +1478,6 @@ public final class Sheet implements Model { 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) { - if (getMargins()[margin] != null) - return margins[margin].getMargin(); - else { - switch ( margin ) - { - case LeftMargin: - return .75; - case RightMargin: - return .75; - case TopMargin: - return 1.0; - case BottomMargin: - return 1.0; - default : - throw new RuntimeException( "Unknown margin constant: " + 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) { - Margin m = getMargins()[margin]; - if (m == null) { - switch ( margin ) - { - case LeftMargin: - m = new LeftMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - case RightMargin: - m = new RightMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - case TopMargin: - m = new TopMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - case BottomMargin: - m = new BottomMarginRecord(); - records.add( getDimsLoc() + 1, m ); - break; - default : - throw new RuntimeException( "Unknown margin constant: " + margin ); - } - margins[margin] = m; - } - m.setMargin( size ); - } - public int getEofLoc() { return eofLoc; @@ -2095,8 +1654,8 @@ public final class Sheet implements Model { */ private static PasswordRecord createPassword() { if (log.check( POILogger.DEBUG )) { - log.log(POILogger.DEBUG, "create password record with 00 password"); - } + log.log(POILogger.DEBUG, "create password record with 00 password"); + } PasswordRecord retval = new PasswordRecord(); retval.setPassword((short)00); @@ -2167,17 +1726,6 @@ public final class Sheet implements Model { this._isUncalced = uncalced; } - /** - * Returns the array of margins. If not created, will create. - * - * @return the array of marings. - */ - protected Margin[] getMargins() { - if (margins == null) - margins = new Margin[4]; - return margins; - } - /** * Finds the DrawingRecord for our sheet, and * attaches it to the DrawingManager (which knows about @@ -2246,153 +1794,16 @@ public final class Sheet implements Model { } } - /** - * Shifts all the page breaks in the range "count" number of rows/columns - * @param breaks The page record to be shifted - * @param start Starting "main" value to shift breaks - * @param stop Ending "main" value to shift breaks - * @param count number of units (rows/columns) to shift by - */ - private static void shiftBreaks(PageBreakRecord breaks, int start, int stop, int count) { - - Iterator iterator = breaks.getBreaksIterator(); - List shiftedBreak = new ArrayList(); - while(iterator.hasNext()) - { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - int breakLocation = breakItem.main; - boolean inStart = (breakLocation >= start); - boolean inEnd = (breakLocation <= stop); - if(inStart && inEnd) - shiftedBreak.add(breakItem); - } - - iterator = shiftedBreak.iterator(); - while (iterator.hasNext()) { - PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); - breaks.removeBreak(breakItem.main); - breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo); + + public PageSettingsBlock getPageSettings() { + if (_psBlock == null) { + _psBlock = new PageSettingsBlock(); + RecordOrderer.addNewSheetRecord(records, _psBlock); + dimsloc++; } + return _psBlock; } - private PageBreakRecord getRowBreaksRecord() { - if (_rowBreaksRecord == null) { - _rowBreaksRecord = new HorizontalPageBreakRecord(); - RecordOrderer.addNewSheetRecord(records, _rowBreaksRecord); - dimsloc++; - } - return _rowBreaksRecord; - } - - private PageBreakRecord getColumnBreaksRecord() { - if (_columnBreaksRecord == null) { - _columnBreaksRecord = new VerticalPageBreakRecord(); - RecordOrderer.addNewSheetRecord(records, _columnBreaksRecord); - dimsloc++; - } - return _columnBreaksRecord; - } - - - /** - * Sets a page break at the indicated row - * @param row - */ - public void setRowBreak(int row, short fromCol, short toCol) { - getRowBreaksRecord().addBreak((short)row, fromCol, toCol); - } - - /** - * Removes a page break at the indicated row - * @param row - */ - public void removeRowBreak(int row) { - if (getRowBreaks() == null) - throw new IllegalArgumentException("Sheet does not define any row breaks"); - getRowBreaksRecord().removeBreak((short)row); - } - - /** - * Queries if the specified row has a page break - * @param row - * @return true if the specified row has a page break - */ - public boolean isRowBroken(int row) { - return getRowBreaksRecord().getBreak(row) != null; - } - - /** - * Sets a page break at the indicated column - * - */ - public void setColumnBreak(short column, short fromRow, short toRow) { - getColumnBreaksRecord().addBreak(column, fromRow, toRow); - } - - /** - * Removes a page break at the indicated column - * - */ - public void removeColumnBreak(short column) { - getColumnBreaksRecord().removeBreak(column); - } - - /** - * Queries if the specified column has a page break - * - * @return true if the specified column has a page break - */ - public boolean isColumnBroken(short column) { - return getColumnBreaksRecord().getBreak(column) != null; - } - - /** - * Shifts the horizontal page breaks for the indicated count - * @param startingRow - * @param endingRow - * @param count - */ - public void shiftRowBreaks(int startingRow, int endingRow, int count) { - shiftBreaks(getRowBreaksRecord(), startingRow, endingRow, count); - } - - /** - * Shifts the vertical page breaks for the indicated count - * @param startingCol - * @param endingCol - * @param count - */ - public void shiftColumnBreaks(short startingCol, short endingCol, short count) { - shiftBreaks(getColumnBreaksRecord(), startingCol, endingCol, count); - } - - /** - * @return all the horizontal page breaks, never null - */ - public int[] getRowBreaks() { - return getRowBreaksRecord().getBreaks(); - } - - /** - * @return the number of row page breaks - */ - public int getNumRowBreaks(){ - return getRowBreaksRecord().getNumBreaks(); - } - - /** - * @return all the column page breaks, never null - */ - public int[] getColumnBreaks(){ - return getColumnBreaksRecord().getBreaks(); - } - - /** - * @return the number of column page breaks - */ - public int getNumColumnBreaks(){ - return getColumnBreaksRecord().getNumBreaks(); - } public void setColumnGroupCollapsed( short columnNumber, boolean collapsed ) { @@ -2520,8 +1931,8 @@ public final class Sheet implements Model { } public DataValidityTable getOrCreateDataValidityTable() { if (_dataValidityTable == null) { - DataValidityTable result = new DataValidityTable(); - RecordOrderer.addNewSheetRecord(records, result); + DataValidityTable result = new DataValidityTable(); + RecordOrderer.addNewSheetRecord(records, result); _dataValidityTable = result; } return _dataValidityTable; diff --git a/src/java/org/apache/poi/hssf/record/DBCellRecord.java b/src/java/org/apache/poi/hssf/record/DBCellRecord.java index 1da6b82c7..d14e689ed 100644 --- a/src/java/org/apache/poi/hssf/record/DBCellRecord.java +++ b/src/java/org/apache/poi/hssf/record/DBCellRecord.java @@ -35,6 +35,7 @@ public final class DBCellRecord extends Record { public DBCellRecord() { + field_2_cell_offsets = new short[0]; } /** @@ -185,4 +186,9 @@ public final class DBCellRecord extends Record { { return true; } + public Object clone() { + // TODO - make immutable. + // this should be safe because only the instantiating code mutates these objects + return this; + } } diff --git a/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java b/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java index 874f304ab..a8518c7b3 100644 --- a/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java +++ b/src/java/org/apache/poi/hssf/record/PrintSetupRecord.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -15,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.record; @@ -24,18 +22,15 @@ import org.apache.poi.util.BitField; import org.apache.poi.util.BitFieldFactory; /** - * Title: Print Setup Record

- * Description: Stores print setup options -- bogus for HSSF (and marked as such)

- * REFERENCE: PG 385 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

+ * Title: PAGESETUP (0x00A1)

+ * Description: Stores print setup options -- bogus for HSSF (and marked as such)

+ * REFERENCE: PG 385 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

* @author Andrew C. Oliver (acoliver at apache dot org) * @author Jason Height (jheight at chariot dot net dot au) * @version 2.0-pre */ - -public class PrintSetupRecord - extends Record -{ - public final static short sid = 0xa1; +public class PrintSetupRecord extends Record { + public final static short sid = 0x00A1; private short field_1_paper_size; private short field_2_scale; private short field_3_page_start; diff --git a/src/java/org/apache/poi/hssf/record/RowRecord.java b/src/java/org/apache/poi/hssf/record/RowRecord.java index 46d4a1efe..2ef876398 100644 --- a/src/java/org/apache/poi/hssf/record/RowRecord.java +++ b/src/java/org/apache/poi/hssf/record/RowRecord.java @@ -22,15 +22,17 @@ import org.apache.poi.util.BitFieldFactory; import org.apache.poi.util.LittleEndian; /** - * Title: Row Record

- * Description: stores the row information for the sheet.

+ * Title: Row Record (0x0208)

+ * Description: stores the row information for the sheet.

* REFERENCE: PG 379 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)

* @author Andrew C. Oliver (acoliver at apache dot org) * @author Jason Height (jheight at chariot dot net dot au) * @version 2.0-pre */ public final class RowRecord extends Record implements Comparable { - public final static short sid = 0x208; + public final static short sid = 0x0208; + + public static final int ENCODED_SIZE = 20; private static final int OPTION_BITS_ALWAYS_SET = 0x0100; private static final int DEFAULT_HEIGHT_BIT = 0x8000; @@ -407,23 +409,23 @@ public final class RowRecord extends Record implements Comparable { public int serialize(int offset, byte [] data) { - LittleEndian.putShort(data, 0 + offset, sid); - LittleEndian.putShort(data, 2 + offset, ( short ) 16); - LittleEndian.putShort(data, 4 + offset, ( short ) getRowNumber()); - LittleEndian.putShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol()); - LittleEndian.putShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol()); - LittleEndian.putShort(data, 10 + offset, getHeight()); - LittleEndian.putShort(data, 12 + offset, getOptimize()); - LittleEndian.putShort(data, 14 + offset, field_6_reserved); - LittleEndian.putShort(data, 16 + offset, getOptionFlags()); + LittleEndian.putUShort(data, 0 + offset, sid); + LittleEndian.putUShort(data, 2 + offset, ENCODED_SIZE - 4); + LittleEndian.putUShort(data, 4 + offset, getRowNumber()); + LittleEndian.putUShort(data, 6 + offset, getFirstCol() == -1 ? (short)0 : getFirstCol()); + LittleEndian.putUShort(data, 8 + offset, getLastCol() == -1 ? (short)0 : getLastCol()); + LittleEndian.putUShort(data, 10 + offset, getHeight()); + LittleEndian.putUShort(data, 12 + offset, getOptimize()); + LittleEndian.putUShort(data, 14 + offset, field_6_reserved); + LittleEndian.putUShort(data, 16 + offset, getOptionFlags()); - LittleEndian.putShort(data, 18 + offset, getXFIndex()); - return getRecordSize(); + LittleEndian.putUShort(data, 18 + offset, getXFIndex()); + return ENCODED_SIZE; } public int getRecordSize() { - return 20; + return ENCODED_SIZE; } public short getSid() diff --git a/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java b/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java new file mode 100644 index 000000000..cc8be4179 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java @@ -0,0 +1,525 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +package org.apache.poi.hssf.record.aggregates; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.poi.hssf.model.RecordStream; +import org.apache.poi.hssf.model.Sheet; +import org.apache.poi.hssf.record.BottomMarginRecord; +import org.apache.poi.hssf.record.FooterRecord; +import org.apache.poi.hssf.record.HCenterRecord; +import org.apache.poi.hssf.record.HeaderRecord; +import org.apache.poi.hssf.record.HorizontalPageBreakRecord; +import org.apache.poi.hssf.record.LeftMarginRecord; +import org.apache.poi.hssf.record.Margin; +import org.apache.poi.hssf.record.PageBreakRecord; +import org.apache.poi.hssf.record.PrintSetupRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RightMarginRecord; +import org.apache.poi.hssf.record.TopMarginRecord; +import org.apache.poi.hssf.record.VCenterRecord; +import org.apache.poi.hssf.record.VerticalPageBreakRecord; + +/** + * Groups the page settings records for a worksheet.

+ * + * See OOO excelfileformat.pdf sec 4.4 'Page Settings Block' + * + * @author Josh Micich + */ +public final class PageSettingsBlock extends RecordAggregate { + // Every one of these component records is optional + // (The whole PageSettingsBlock may not be present) + private PageBreakRecord _rowBreaksRecord; + private PageBreakRecord _columnBreaksRecord; + private HeaderRecord header; + private FooterRecord footer; + private HCenterRecord _hCenter; + private VCenterRecord _vCenter; + private LeftMarginRecord _leftMargin; + private RightMarginRecord _rightMargin; + private TopMarginRecord _topMargin; + private BottomMarginRecord _bottomMargin; + private Record _pls; + private PrintSetupRecord printSetup; + private Record _bitmap; + + public PageSettingsBlock(RecordStream rs) { + while(true) { + if (!readARecord(rs)) { + break; + } + } + } + + /** + * Creates a PageSettingsBlock with default settings + */ + public PageSettingsBlock() { + _rowBreaksRecord = new HorizontalPageBreakRecord(); + _columnBreaksRecord = new VerticalPageBreakRecord(); + header = createHeader(); + footer = createFooter(); + _hCenter = createHCenter(); + _vCenter = createVCenter(); + printSetup = createPrintSetup(); + } + + /** + * @return true if the specified Record sid is one belonging to the + * 'Page Settings Block'. + */ + public static boolean isComponentRecord(int sid) { + switch (sid) { + case HorizontalPageBreakRecord.sid: + case VerticalPageBreakRecord.sid: + case HeaderRecord.sid: + case FooterRecord.sid: + case HCenterRecord.sid: + case VCenterRecord.sid: + case LeftMarginRecord.sid: + case RightMarginRecord.sid: + case TopMarginRecord.sid: + case BottomMarginRecord.sid: + case 0x004D: // PLS + case PrintSetupRecord.sid: + case 0x00E9: // BITMAP + return true; + } + return false; + } + + private boolean readARecord(RecordStream rs) { + switch (rs.peekNextSid()) { + case HorizontalPageBreakRecord.sid: + _rowBreaksRecord = (PageBreakRecord) rs.getNext(); + break; + case VerticalPageBreakRecord.sid: + _columnBreaksRecord = (PageBreakRecord) rs.getNext(); + break; + case HeaderRecord.sid: + header = (HeaderRecord) rs.getNext(); + break; + case FooterRecord.sid: + footer = (FooterRecord) rs.getNext(); + break; + case HCenterRecord.sid: + _hCenter = (HCenterRecord) rs.getNext(); + break; + case VCenterRecord.sid: + _vCenter = (VCenterRecord) rs.getNext(); + break; + case LeftMarginRecord.sid: + _leftMargin = (LeftMarginRecord) rs.getNext(); + break; + case RightMarginRecord.sid: + _rightMargin = (RightMarginRecord) rs.getNext(); + break; + case TopMarginRecord.sid: + _topMargin = (TopMarginRecord) rs.getNext(); + break; + case BottomMarginRecord.sid: + _bottomMargin = (BottomMarginRecord) rs.getNext(); + break; + case 0x004D: // PLS + _pls = rs.getNext(); + break; + case PrintSetupRecord.sid: + printSetup = (PrintSetupRecord)rs.getNext(); + break; + case 0x00E9: // BITMAP + _bitmap = rs.getNext(); + break; + default: + // all other record types are not part of the PageSettingsBlock + return false; + } + return true; + } + + private PageBreakRecord getRowBreaksRecord() { + if (_rowBreaksRecord == null) { + _rowBreaksRecord = new HorizontalPageBreakRecord(); + } + return _rowBreaksRecord; + } + + private PageBreakRecord getColumnBreaksRecord() { + if (_columnBreaksRecord == null) { + _columnBreaksRecord = new VerticalPageBreakRecord(); + } + return _columnBreaksRecord; + } + + + /** + * Sets a page break at the indicated column + * + */ + public void setColumnBreak(short column, short fromRow, short toRow) { + getColumnBreaksRecord().addBreak(column, fromRow, toRow); + } + + /** + * Removes a page break at the indicated column + * + */ + public void removeColumnBreak(int column) { + getColumnBreaksRecord().removeBreak(column); + } + + + + + public void visitContainedRecords(RecordVisitor rv) { + visitIfPresent(_rowBreaksRecord, rv); + visitIfPresent(_columnBreaksRecord, rv); + visitIfPresent(header, rv); + visitIfPresent(footer, rv); + visitIfPresent(_hCenter, rv); + visitIfPresent(_vCenter, rv); + visitIfPresent(_leftMargin, rv); + visitIfPresent(_rightMargin, rv); + visitIfPresent(_topMargin, rv); + visitIfPresent(_bottomMargin, rv); + visitIfPresent(_pls, rv); + visitIfPresent(printSetup, rv); + visitIfPresent(_bitmap, rv); + } + private static void visitIfPresent(Record r, RecordVisitor rv) { + if (r != null) { + rv.visitRecord(r); + } + } + + /** + * creates the Header Record and sets it to nothing/0 length + */ + private static HeaderRecord createHeader() { + HeaderRecord retval = new HeaderRecord(); + + retval.setHeaderLength(( byte ) 0); + retval.setHeader(null); + return retval; + } + + /** + * creates the Footer Record and sets it to nothing/0 length + */ + private static FooterRecord createFooter() { + FooterRecord retval = new FooterRecord(); + + retval.setFooterLength(( byte ) 0); + retval.setFooter(null); + return retval; + } + + /** + * creates the HCenter Record and sets it to false (don't horizontally center) + */ + private static HCenterRecord createHCenter() { + HCenterRecord retval = new HCenterRecord(); + + retval.setHCenter(false); + return retval; + } + + /** + * creates the VCenter Record and sets it to false (don't horizontally center) + */ + private static VCenterRecord createVCenter() { + VCenterRecord retval = new VCenterRecord(); + + retval.setVCenter(false); + return retval; + } + + /** + * creates the PrintSetup Record and sets it to defaults and marks it invalid + * @see org.apache.poi.hssf.record.PrintSetupRecord + * @see org.apache.poi.hssf.record.Record + * @return record containing a PrintSetupRecord + */ + private static PrintSetupRecord createPrintSetup() { + PrintSetupRecord retval = new PrintSetupRecord(); + + retval.setPaperSize(( short ) 1); + retval.setScale(( short ) 100); + retval.setPageStart(( short ) 1); + retval.setFitWidth(( short ) 1); + retval.setFitHeight(( short ) 1); + retval.setOptions(( short ) 2); + retval.setHResolution(( short ) 300); + retval.setVResolution(( short ) 300); + retval.setHeaderMargin( 0.5); + retval.setFooterMargin( 0.5); + retval.setCopies(( short ) 0); + return retval; + } + + + /** + * Returns the HeaderRecord. + * @return HeaderRecord for the sheet. + */ + public HeaderRecord getHeader () + { + return header; + } + + /** + * Sets the HeaderRecord. + * @param newHeader The new HeaderRecord for the sheet. + */ + public void setHeader (HeaderRecord newHeader) + { + header = newHeader; + } + + /** + * Returns the FooterRecord. + * @return FooterRecord for the sheet. + */ + public FooterRecord getFooter () + { + return footer; + } + + /** + * Sets the FooterRecord. + * @param newFooter The new FooterRecord for the sheet. + */ + public void setFooter (FooterRecord newFooter) + { + footer = newFooter; + } + + /** + * Returns the PrintSetupRecord. + * @return PrintSetupRecord for the sheet. + */ + public PrintSetupRecord getPrintSetup () + { + return printSetup; + } + + /** + * Sets the PrintSetupRecord. + * @param newPrintSetup The new PrintSetupRecord for the sheet. + */ + public void setPrintSetup (PrintSetupRecord newPrintSetup) + { + printSetup = newPrintSetup; + } + + + private Margin getMarginRec(int marginIndex) { + switch (marginIndex) { + case Sheet.LeftMargin: return _leftMargin; + case Sheet.RightMargin: return _rightMargin; + case Sheet.TopMargin: return _topMargin; + case Sheet.BottomMargin: return _bottomMargin; + } + throw new RuntimeException( "Unknown margin constant: " + marginIndex ); + } + + + /** + * 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 = getMarginRec(margin); + if (m != null) { + return m.getMargin(); + } else { + switch ( margin ) + { + case Sheet.LeftMargin: + return .75; + case Sheet.RightMargin: + return .75; + case Sheet.TopMargin: + return 1.0; + case Sheet.BottomMargin: + return 1.0; + } + throw new RuntimeException( "Unknown margin constant: " + 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) { + Margin m = getMarginRec(margin); + if (m == null) { + switch ( margin ) + { + case Sheet.LeftMargin: + _leftMargin = new LeftMarginRecord(); + m = _leftMargin; + break; + case Sheet.RightMargin: + _rightMargin = new RightMarginRecord(); + m = _rightMargin; + break; + case Sheet.TopMargin: + _topMargin = new TopMarginRecord(); + m = _topMargin; + break; + case Sheet.BottomMargin: + _bottomMargin = new BottomMarginRecord(); + m = _bottomMargin; + break; + default : + throw new RuntimeException( "Unknown margin constant: " + margin ); + } + } + m.setMargin( size ); + } + + /** + * Shifts all the page breaks in the range "count" number of rows/columns + * @param breaks The page record to be shifted + * @param start Starting "main" value to shift breaks + * @param stop Ending "main" value to shift breaks + * @param count number of units (rows/columns) to shift by + */ + private static void shiftBreaks(PageBreakRecord breaks, int start, int stop, int count) { + + Iterator iterator = breaks.getBreaksIterator(); + List shiftedBreak = new ArrayList(); + while(iterator.hasNext()) + { + PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); + int breakLocation = breakItem.main; + boolean inStart = (breakLocation >= start); + boolean inEnd = (breakLocation <= stop); + if(inStart && inEnd) + shiftedBreak.add(breakItem); + } + + iterator = shiftedBreak.iterator(); + while (iterator.hasNext()) { + PageBreakRecord.Break breakItem = (PageBreakRecord.Break)iterator.next(); + breaks.removeBreak(breakItem.main); + breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo); + } + } + + + /** + * Sets a page break at the indicated row + * @param row + */ + public void setRowBreak(int row, short fromCol, short toCol) { + getRowBreaksRecord().addBreak((short)row, fromCol, toCol); + } + + /** + * Removes a page break at the indicated row + * @param row + */ + public void removeRowBreak(int row) { + if (getRowBreaksRecord().getBreaks().length < 1) + throw new IllegalArgumentException("Sheet does not define any row breaks"); + getRowBreaksRecord().removeBreak((short)row); + } + + /** + * Queries if the specified row has a page break + * @param row + * @return true if the specified row has a page break + */ + public boolean isRowBroken(int row) { + return getRowBreaksRecord().getBreak(row) != null; + } + + + /** + * Queries if the specified column has a page break + * + * @return true if the specified column has a page break + */ + public boolean isColumnBroken(int column) { + return getColumnBreaksRecord().getBreak(column) != null; + } + + /** + * Shifts the horizontal page breaks for the indicated count + * @param startingRow + * @param endingRow + * @param count + */ + public void shiftRowBreaks(int startingRow, int endingRow, int count) { + shiftBreaks(getRowBreaksRecord(), startingRow, endingRow, count); + } + + /** + * Shifts the vertical page breaks for the indicated count + * @param startingCol + * @param endingCol + * @param count + */ + public void shiftColumnBreaks(short startingCol, short endingCol, short count) { + shiftBreaks(getColumnBreaksRecord(), startingCol, endingCol, count); + } + + /** + * @return all the horizontal page breaks, never null + */ + public int[] getRowBreaks() { + return getRowBreaksRecord().getBreaks(); + } + + /** + * @return the number of row page breaks + */ + public int getNumRowBreaks(){ + return getRowBreaksRecord().getNumBreaks(); + } + + /** + * @return all the column page breaks, never null + */ + public int[] getColumnBreaks(){ + return getColumnBreaksRecord().getBreaks(); + } + + /** + * @return the number of column page breaks + */ + public int getNumColumnBreaks(){ + return getColumnBreaksRecord().getNumBreaks(); + } + + public VCenterRecord getVCenter() { + return _vCenter; + } + + public HCenterRecord getHCenter() { + return _hCenter; + } +} diff --git a/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java index ce0bf8945..f9cbcd777 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/RecordAggregate.java @@ -54,6 +54,10 @@ public abstract class RecordAggregate extends RecordBase { } public interface RecordVisitor { + /** + * Implementors may call non-mutating methods on Record r. + * @param r must not be null + */ void visitRecord(Record r); } diff --git a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java index 65af632d3..c9a302b61 100644 --- a/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java +++ b/src/java/org/apache/poi/hssf/record/aggregates/RowRecordsAggregate.java @@ -1,4 +1,3 @@ - /* ==================================================================== Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -16,85 +15,88 @@ limitations under the License. ==================================================================== */ - package org.apache.poi.hssf.record.aggregates; -import org.apache.poi.hssf.record.DBCellRecord; -import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.RecordInputStream; -import org.apache.poi.hssf.record.RowRecord; - - +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.TreeMap; +import org.apache.poi.hssf.record.CellValueRecordInterface; +import org.apache.poi.hssf.record.DBCellRecord; +import org.apache.poi.hssf.record.IndexRecord; +import org.apache.poi.hssf.record.Record; +import org.apache.poi.hssf.record.RowRecord; + /** * * @author andy * @author Jason Height (jheight at chariot dot net dot au) */ - -public final class RowRecordsAggregate extends Record { - private int firstrow = -1; - private int lastrow = -1; - private Map records = null; // TODO - use a proper key in this map - private int size = 0; +public final class RowRecordsAggregate extends RecordAggregate { + private int _firstrow = -1; + private int _lastrow = -1; + private final Map _rowRecords; + private final ValueRecordsAggregate _valuesAgg; /** Creates a new instance of ValueRecordsAggregate */ - public RowRecordsAggregate() - { - records = new TreeMap(); + public RowRecordsAggregate() { + this(new TreeMap(), new ValueRecordsAggregate()); + } + private RowRecordsAggregate(TreeMap rowRecords, ValueRecordsAggregate valuesAgg) { + _rowRecords = rowRecords; + _valuesAgg = valuesAgg; } - public void insertRow(RowRecord row) - { - size += row.getRecordSize(); - + public void insertRow(RowRecord row) { // Integer integer = new Integer(row.getRowNumber()); - records.put(row, row); - if ((row.getRowNumber() < firstrow) || (firstrow == -1)) + _rowRecords.put(new Integer(row.getRowNumber()), row); + if ((row.getRowNumber() < _firstrow) || (_firstrow == -1)) { - firstrow = row.getRowNumber(); + _firstrow = row.getRowNumber(); } - if ((row.getRowNumber() > lastrow) || (lastrow == -1)) + if ((row.getRowNumber() > _lastrow) || (_lastrow == -1)) { - lastrow = row.getRowNumber(); + _lastrow = row.getRowNumber(); } } - public void removeRow(RowRecord row) - { - size -= row.getRecordSize(); - - // Integer integer = new Integer(row.getRowNumber()); - records.remove(row); + public void removeRow(RowRecord row) { + int rowIndex = row.getRowNumber(); + _valuesAgg.removeAllCellsValuesForRow(rowIndex); + Integer key = new Integer(rowIndex); + RowRecord rr = (RowRecord) _rowRecords.remove(key); + if (rr == null) { + throw new RuntimeException("Invalid row index (" + key.intValue() + ")"); + } + if (row != rr) { + _rowRecords.put(key, rr); + throw new RuntimeException("Attempt to remove row that does not belong to this sheet"); + } } - public RowRecord getRow(int rownum) { - // Row must be between 0 and 65535 - if(rownum < 0 || rownum > 65535) { + public RowRecord getRow(int rowIndex) { + if (rowIndex < 0 || rowIndex > 65535) { throw new IllegalArgumentException("The row number must be between 0 and 65535"); } - - RowRecord row = new RowRecord(rownum); - return ( RowRecord ) records.get(row); + return (RowRecord) _rowRecords.get(new Integer(rowIndex)); } public int getPhysicalNumberOfRows() { - return records.size(); + return _rowRecords.size(); } public int getFirstRowNum() { - return firstrow; + return _firstrow; } public int getLastRowNum() { - return lastrow; + return _lastrow; } /** Returns the number of row blocks. @@ -102,184 +104,134 @@ public final class RowRecordsAggregate extends Record { * after them */ public int getRowBlockCount() { - int size = records.size()/DBCellRecord.BLOCK_SIZE; - if ((records.size() % DBCellRecord.BLOCK_SIZE) != 0) + int size = _rowRecords.size()/DBCellRecord.BLOCK_SIZE; + if ((_rowRecords.size() % DBCellRecord.BLOCK_SIZE) != 0) size++; return size; } - public int getRowBlockSize(int block) { - return 20 * getRowCountForBlock(block); + private int getRowBlockSize(int block) { + return RowRecord.ENCODED_SIZE * getRowCountForBlock(block); } /** Returns the number of physical rows within a block*/ public int getRowCountForBlock(int block) { int startIndex = block * DBCellRecord.BLOCK_SIZE; int endIndex = startIndex + DBCellRecord.BLOCK_SIZE - 1; - if (endIndex >= records.size()) - endIndex = records.size()-1; + if (endIndex >= _rowRecords.size()) + endIndex = _rowRecords.size()-1; return endIndex-startIndex+1; } /** Returns the physical row number of the first row in a block*/ - public int getStartRowNumberForBlock(int block) { + private int getStartRowNumberForBlock(int block) { //Given that we basically iterate through the rows in order, - //For a performance improvement, it would be better to return an instance of + // TODO - For a performance improvement, it would be better to return an instance of //an iterator and use that instance throughout, rather than recreating one and //having to move it to the right position. int startIndex = block * DBCellRecord.BLOCK_SIZE; - Iterator rowIter = records.values().iterator(); + Iterator rowIter = _rowRecords.values().iterator(); RowRecord row = null; //Position the iterator at the start of the block for (int i=0; i<=startIndex;i++) { row = (RowRecord)rowIter.next(); } + if (row == null) { + throw new RuntimeException("Did not find start row for block " + block); + } return row.getRowNumber(); } /** Returns the physical row number of the end row in a block*/ - public int getEndRowNumberForBlock(int block) { + private int getEndRowNumberForBlock(int block) { int endIndex = ((block + 1)*DBCellRecord.BLOCK_SIZE)-1; - if (endIndex >= records.size()) - endIndex = records.size()-1; + if (endIndex >= _rowRecords.size()) + endIndex = _rowRecords.size()-1; - Iterator rowIter = records.values().iterator(); + Iterator rowIter = _rowRecords.values().iterator(); RowRecord row = null; for (int i=0; i<=endIndex;i++) { row = (RowRecord)rowIter.next(); } + if (row == null) { + throw new RuntimeException("Did not find start row for block " + block); + } return row.getRowNumber(); } - - - /** Serializes a block of the rows */ - private int serializeRowBlock(final int block, final int offset, byte[] data) { - final int startIndex = block*DBCellRecord.BLOCK_SIZE; - final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE; - - Iterator rowIterator = records.values().iterator(); - int pos = offset; - - //Given that we basically iterate through the rows in order, - //For a performance improvement, it would be better to return an instance of - //an iterator and use that instance throughout, rather than recreating one and - //having to move it to the right position. - int i=0; - for (;i=records.length) return; - CellValueRecordInterface[] rowCells=records[row]; - if(rowCells==null) return; - if(column>=rowCells.length) return; - rowCells[column]=null; - } + public void removeCell(CellValueRecordInterface cell) { + if (cell == null) { + throw new IllegalArgumentException("cell must not be null"); + } + int row = cell.getRow(); + if (row >= records.length) { + throw new RuntimeException("cell row is out of range"); + } + CellValueRecordInterface[] rowCells = records[row]; + if (rowCells == null) { + throw new RuntimeException("cell row is already empty"); + } + short column = cell.getColumn(); + if (column >= rowCells.length) { + throw new RuntimeException("cell column is out of range"); + } + rowCells[column] = null; } + public void removeAllCellsValuesForRow(int rowIndex) { + if (rowIndex >= records.length) { + throw new IllegalArgumentException("Specified rowIndex " + rowIndex + + " is outside the allowable range (0.." +records.length + ")"); + } + records[rowIndex] = null; + } + + public int getPhysicalNumberOfCells() { int count=0; @@ -133,7 +149,7 @@ public final class ValueRecordsAggregate { Record rec = ( Record ) records.get(k); if (rec instanceof SharedFormulaRecord) { - sharedFormulas.add(rec); + sharedFormulas.add(rec); } if(rec instanceof EOFRecord) { // End of current sheet. Ignore all subsequent shared formula records (Bugzilla 44449) @@ -150,30 +166,30 @@ public final class ValueRecordsAggregate { break; } else if (rec instanceof SharedFormulaRecord) { - // Already handled, not to worry + // Already handled, not to worry } else if (rec instanceof FormulaRecord) { FormulaRecord formula = (FormulaRecord)rec; if (formula.isSharedFormula()) { // Traverse the list of shared formulas in - // reverse order, and try to find the correct one + // reverse order, and try to find the correct one // for us boolean found = false; for (int i=sharedFormulas.size()-1;i>=0;i--) { // TODO - there is no junit test case to justify this reversed loop // perhaps it could just run in the normal direction? - SharedFormulaRecord shrd = (SharedFormulaRecord)sharedFormulas.get(i); - if (shrd.isFormulaInShared(formula)) { - shrd.convertSharedFormulaRecord(formula); - found = true; - break; - } + SharedFormulaRecord shrd = (SharedFormulaRecord)sharedFormulas.get(i); + if (shrd.isFormulaInShared(formula)) { + shrd.convertSharedFormulaRecord(formula); + found = true; + break; + } } if (!found) { handleMissingSharedFormulaRecord(formula); } } - + lastFormulaAggregate = new FormulaRecordAggregate((FormulaRecord)rec, null); insertCell( lastFormulaAggregate ); } @@ -206,21 +222,6 @@ public final class ValueRecordsAggregate private static void handleMissingSharedFormulaRecord(FormulaRecord formula) { // could log an info message here since this is a fairly unusual occurrence. } - - /** - * 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 serialize(int offset, byte [] data) - { - throw new RuntimeException("This method shouldnt be called. ValueRecordsAggregate.serializeCellRow() should be called from RowRecordsAggregate."); - } /** Tallies a count of the size of the cell records * that are attached to the rows in the range specified. @@ -241,8 +242,8 @@ public final class ValueRecordsAggregate /** Returns true if the row has cells attached to it */ public boolean rowHasCells(int row) { - if (row > records.length-1) //previously this said row > records.length which means if - return false; // if records.length == 60 and I pass "60" here I get array out of bounds + if (row > records.length-1) //previously this said row > records.length which means if + return false; // if records.length == 60 and I pass "60" here I get array out of bounds CellValueRecordInterface[] rowCells=records[row]; //because a 60 length array has the last index = 59 if(rowCells==null) return false; for(int col=0;col 0) { + return ErrorEval.VALUE_INVALID; + } + + java.util.Date now = new java.util.Date(System.currentTimeMillis()); + return new NumberEval(HSSFDateUtil.getExcelDate(now)); + } } diff --git a/src/java/org/apache/poi/hssf/record/formula/functions/Today.java b/src/java/org/apache/poi/hssf/record/formula/functions/Today.java index 6260d20a5..b70741213 100644 --- a/src/java/org/apache/poi/hssf/record/formula/functions/Today.java +++ b/src/java/org/apache/poi/hssf/record/formula/functions/Today.java @@ -1,25 +1,46 @@ -/* -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -/* - * Created on May 15, 2005 - * - */ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + package org.apache.poi.hssf.record.formula.functions; -public class Today extends NotImplementedFunction { +import java.util.Calendar; +import java.util.GregorianCalendar; +import org.apache.poi.hssf.record.formula.eval.ErrorEval; +import org.apache.poi.hssf.record.formula.eval.Eval; +import org.apache.poi.hssf.record.formula.eval.NumberEval; +import org.apache.poi.hssf.usermodel.HSSFDateUtil; + +/** + * Implementation of Excel TODAY() Function
+ * + * @author Frank Taffelt + */ +public class Today implements Function { + + public Eval evaluate(Eval[] evals, int srcCellRow, short srcCellCol) { + if (evals.length > 0) { + return ErrorEval.VALUE_INVALID; + } + + Calendar now = new GregorianCalendar(); + now.set(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DATE),0,0,0); + now.set(Calendar.MILLISECOND, 0); + return new NumberEval(HSSFDateUtil.getExcelDate(now.getTime())); + } } + diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 9abcebcd7..e46729d3d 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -15,13 +15,6 @@ limitations under the License. ==================================================================== */ - - -/* - * Cell.java - * - * Created on September 30, 2001, 3:46 PM - */ package org.apache.poi.hssf.usermodel; import java.text.DateFormat; @@ -79,10 +72,7 @@ import org.apache.poi.ss.usermodel.RichTextString; * @author Yegor Kozlov cell comments support * @version 1.0-pre */ - -public class HSSFCell implements Cell -{ - +public class HSSFCell implements Cell { /** * Numeric Cell type (0) * @see #setCellType(int) @@ -157,8 +147,6 @@ public class HSSFCell implements Cell * * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short) */ - - //protected HSSFCell(Workbook book, Sheet sheet, short row, short col) protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col) { checkBounds(col); @@ -186,8 +174,6 @@ public class HSSFCell implements Cell * Type of cell * @see org.apache.poi.hssf.usermodel.HSSFRow#createCell(short,int) */ - - //protected HSSFCell(Workbook book, Sheet sheet, short row, short col, protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, short col, int type) { @@ -209,8 +195,6 @@ public class HSSFCell implements Cell * @param sheet - Sheet record of the sheet containing this cell * @param cval - the Cell Value Record we wish to represent */ - - //protected HSSFCell(Workbook book, Sheet sheet, short row, protected HSSFCell(HSSFWorkbook book, Sheet sheet, int row, CellValueRecordInterface cval) { @@ -234,15 +218,9 @@ public class HSSFCell implements Cell } ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(cval.getXFIndex()); - setCellStyle(new HSSFCellStyle(( short ) cval.getXFIndex(), xf, book)); + setCellStyle(new HSSFCellStyle(cval.getXFIndex(), xf, book)); } - /** - * private constructor to prevent blank construction - */ - private HSSFCell() - { - } /** * used internally -- given a cell value record, figure out its type @@ -351,11 +329,6 @@ public class HSSFCell implements Cell private void setCellType(int cellType, boolean setValue, int row,short col, short styleIndex) { - // if (cellType == CELL_TYPE_FORMULA) - // { - // throw new RuntimeException( - // "Formulas have not been implemented in this release"); - // } if (cellType > CELL_TYPE_ERROR) { throw new RuntimeException("I have no idea what type that is!"); @@ -506,10 +479,7 @@ public class HSSFCell implements Cell if (cellType != this.cellType && this.cellType!=-1 ) // Special Value to indicate an uninitialized Cell { - int loc = sheet.getLoc(); - sheet.replaceValueRecord(record); - sheet.setLoc(loc); } this.cellType = cellType; } @@ -545,7 +515,7 @@ public class HSSFCell implements Cell setCellType(CELL_TYPE_NUMERIC, false, row, col, styleIndex); } - // Save into the apropriate record + // Save into the appropriate record if(record instanceof FormulaRecordAggregate) { (( FormulaRecordAggregate ) record).getFormulaRecord().setValue(value); } else { @@ -679,9 +649,7 @@ public class HSSFCell implements Cell //only set to default if there is no extended format index already set if (rec.getXFIndex() == (short)0) rec.setXFIndex(( short ) 0x0f); - FormulaParser fp = new FormulaParser(formula, book); - fp.parse(); - Ptg[] ptg = fp.getRPNPtg(); + Ptg[] ptgs = FormulaParser.parse(formula, book); int size = 0; // clear the Ptg Stack @@ -690,9 +658,9 @@ public class HSSFCell implements Cell } // fill the Ptg Stack with Ptgs of new formula - for (int k = 0; k < ptg.length; k++) { - size += ptg[ k ].getSize(); - frec.pushExpressionToken(ptg[ k ]); + for (int k = 0; k < ptgs.length; k++) { + size += ptgs[ k ].getSize(); + frec.pushExpressionToken(ptgs[ k ]); } rec.getFormulaRecord().setExpressionLength(( short ) size); //Workbook.currentBook = null; @@ -967,38 +935,6 @@ public class HSSFCell implements Cell ExtendedFormatRecord xf = book.getWorkbook().getExFormatAt(styleIndex); return new HSSFCellStyle(styleIndex, xf, book); } - - /** - * used for internationalization, currently -1 for unchanged, 0 for compressed unicode or 1 for 16-bit - * - * @see #ENCODING_UNCHANGED - * @see #ENCODING_COMPRESSED_UNICODE - * @see #ENCODING_UTF_16 - * - * @return -1, 1 or 0 for unchanged, compressed or uncompressed (used only with String type) - * - * @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding. - */ - public short getEncoding() - { - return encoding; - } - - /** - * set the encoding to either 8 or 16 bit. (US/UK use 8-bit, rest of the western world use 16bit) - * - * @see #ENCODING_UNCHANGED - * @see #ENCODING_COMPRESSED_UNICODE - * @see #ENCODING_UTF_16 - * - * @param encoding either ENCODING_COMPRESSED_UNICODE (0) or ENCODING_UTF_16 (1) - * @deprecated As of 3-Jan-06 POI now automatically handles Unicode without forcing the encoding. - */ - - public void setEncoding(short encoding) - { - this.encoding = encoding; - } /** * Should only be used by HSSFSheet and friends. Returns the low level CellValueRecordInterface record diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java index 1d4100655..10d86015a 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFConditionalFormattingRule.java @@ -26,17 +26,16 @@ import org.apache.poi.hssf.record.cf.PatternFormatting; import org.apache.poi.hssf.record.formula.Ptg; /** - * + * * High level representation of Conditional Formatting Rule. * It allows to specify formula based conditions for the Conditional Formatting * and the formatting settings such as font, border and pattern. - * + * * @author Dmitriy Kumshayev */ - public final class HSSFConditionalFormattingRule { - private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS; + private static final byte CELL_COMPARISON = CFRuleRecord.CONDITION_TYPE_CELL_VALUE_IS; private final CFRuleRecord cfRuleRecord; private final HSSFWorkbook workbook; @@ -50,11 +49,11 @@ public final class HSSFConditionalFormattingRule { return cfRuleRecord; } - + private HSSFFontFormatting getFontFormatting(boolean create) { FontFormatting fontFormatting = cfRuleRecord.getFontFormatting(); - if ( fontFormatting != null) + if ( fontFormatting != null) { cfRuleRecord.setFontFormatting(fontFormatting); return new HSSFFontFormatting(cfRuleRecord); @@ -70,7 +69,7 @@ public final class HSSFConditionalFormattingRule return null; } } - + /** * @return - font formatting object if defined, null otherwise */ @@ -79,19 +78,19 @@ public final class HSSFConditionalFormattingRule return getFontFormatting(false); } /** - * create a new font formatting structure if it does not exist, + * create a new font formatting structure if it does not exist, * otherwise just return existing object. - * @return - font formatting object, never returns null. + * @return - font formatting object, never returns null. */ public HSSFFontFormatting createFontFormatting() { return getFontFormatting(true); } - + private HSSFBorderFormatting getBorderFormatting(boolean create) { BorderFormatting borderFormatting = cfRuleRecord.getBorderFormatting(); - if ( borderFormatting != null) + if ( borderFormatting != null) { cfRuleRecord.setBorderFormatting(borderFormatting); return new HSSFBorderFormatting(cfRuleRecord); @@ -115,19 +114,19 @@ public final class HSSFConditionalFormattingRule return getBorderFormatting(false); } /** - * create a new border formatting structure if it does not exist, + * create a new border formatting structure if it does not exist, * otherwise just return existing object. - * @return - border formatting object, never returns null. + * @return - border formatting object, never returns null. */ public HSSFBorderFormatting createBorderFormatting() { return getBorderFormatting(true); } - + private HSSFPatternFormatting getPatternFormatting(boolean create) { PatternFormatting patternFormatting = cfRuleRecord.getPatternFormatting(); - if ( patternFormatting != null) + if ( patternFormatting != null) { cfRuleRecord.setPatternFormatting(patternFormatting); return new HSSFPatternFormatting(cfRuleRecord); @@ -143,7 +142,7 @@ public final class HSSFConditionalFormattingRule return null; } } - + /** * @return - pattern formatting object if defined, null otherwise */ @@ -152,15 +151,29 @@ public final class HSSFConditionalFormattingRule return getPatternFormatting(false); } /** - * create a new pattern formatting structure if it does not exist, + * create a new pattern formatting structure if it does not exist, * otherwise just return existing object. - * @return - pattern formatting object, never returns null. + * @return - pattern formatting object, never returns null. */ public HSSFPatternFormatting createPatternFormatting() { return getPatternFormatting(true); } - + + /** + * @return - the conditiontype for the cfrule + */ + public byte getConditionType() { + return cfRuleRecord.getConditionType(); + } + + /** + * @return - the comparisionoperatation for the cfrule + */ + public byte getComparisonOperation() { + return cfRuleRecord.getComparisonOperation(); + } + public String getFormula1() { return toFormulaString(cfRuleRecord.getParsedExpression1()); diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java index 9ad89c34a..1a2b98f43 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java @@ -102,20 +102,17 @@ public final class HSSFRow implements Comparable, Row { } /** - * Use this to create new cells within the row and return it. - *

- * The cell that is returned is a CELL_TYPE_BLANK. The type can be changed - * either through calling setCellValue or setCellType. - * - * @param column - the column number this cell represents - * - * @return HSSFCell a high level representation of the created cell. + * @deprecated (Aug 2008) use {@link HSSFRow#createCell(int) } */ - public HSSFCell createCell(short column) - { - return this.createCell(column,HSSFCell.CELL_TYPE_BLANK); + public HSSFCell createCell(short columnIndex) { + return createCell((int)columnIndex); + } + /** + * @deprecated (Aug 2008) use {@link HSSFRow#createCell(int, int) } + */ + public HSSFCell createCell(short columnIndex, int type) { + return createCell((int)columnIndex, type); } - /** * Use this to create new cells within the row and return it. *

@@ -128,11 +125,7 @@ public final class HSSFRow implements Comparable, Row { */ public HSSFCell createCell(int column) { - short shortCellNum = (short)column; - if(column > 0x7FFF) { - shortCellNum = (short)(0xffff - column); - } - return this.createCell(shortCellNum,HSSFCell.CELL_TYPE_BLANK); + return this.createCell(column,HSSFCell.CELL_TYPE_BLANK); } /** @@ -141,14 +134,18 @@ public final class HSSFRow implements Comparable, Row { * The cell that is returned is a CELL_TYPE_BLANK. The type can be changed * either through calling setCellValue or setCellType. * - * @param column - the column number this cell represents + * @param columnIndex - the column number this cell represents * * @return HSSFCell a high level representation of the created cell. */ - public HSSFCell createCell(short column, int type) + public HSSFCell createCell(int columnIndex, int type) { - HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), column, type); + short shortCellNum = (short)columnIndex; + if(columnIndex > 0x7FFF) { + shortCellNum = (short)(0xffff - columnIndex); + } + HSSFCell cell = new HSSFCell(book, sheet, getRowNum(), shortCellNum, type); addCell(cell); sheet.addValueRecord(getRowNum(), cell.getCellValueRecord()); return cell; @@ -193,12 +190,12 @@ public final class HSSFRow implements Comparable, Row { * records too. */ protected void removeAllCells() { - for(int i=0; i 0) { rows.remove(row); @@ -263,15 +252,6 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { firstrow = findFirstRow(firstrow); } - Iterator iter = hrow.cellIterator(); - - while (iter.hasNext()) - { - HSSFCell cell = (HSSFCell) iter.next(); - - sheet.removeValueRecord(hrow.getRowNum(), - cell.getCellValueRecord()); - } sheet.removeRow(hrow.getRowRecord()); } } @@ -586,10 +566,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet public void setVerticallyCenter(boolean value) { - VCenterRecord record = - (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid); - - record.setVCenter(value); + sheet.getPageSettings().getVCenter().setVCenter(value); } /** @@ -605,10 +582,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public boolean getVerticallyCenter() { - VCenterRecord record = - (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid); - - return record.getVCenter(); + return sheet.getPageSettings().getVCenter().getVCenter(); } /** @@ -618,10 +592,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet public void setHorizontallyCenter(boolean value) { - HCenterRecord record = - (HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid); - - record.setHCenter(value); + sheet.getPageSettings().getHCenter().setHCenter(value); } /** @@ -630,10 +601,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet public boolean getHorizontallyCenter() { - HCenterRecord record = - (HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid); - return record.getHCenter(); + return sheet.getPageSettings().getHCenter().getHCenter(); } @@ -664,8 +633,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet public Region getMergedRegionAt(int index) { CellRangeAddress cra = getMergedRegion(index); - return new Region(cra.getFirstRow(), (short)cra.getFirstColumn(), - cra.getLastRow(), (short)cra.getLastColumn()); + return new Region(cra.getFirstRow(), (short)cra.getFirstColumn(), + cra.getLastRow(), (short)cra.getLastColumn()); } /** * @return the merged region at the specified index @@ -921,7 +890,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public HSSFPrintSetup getPrintSetup() { - return new HSSFPrintSetup( getSheet().getPrintSetup() ); + return new HSSFPrintSetup( sheet.getPageSettings().getPrintSetup() ); } /** @@ -930,7 +899,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public HSSFHeader getHeader() { - return new HSSFHeader( getSheet().getHeader() ); + return new HSSFHeader( sheet.getPageSettings().getHeader() ); } /** @@ -939,7 +908,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public HSSFFooter getFooter() { - return new HSSFFooter( getSheet().getFooter() ); + return new HSSFFooter( sheet.getPageSettings().getFooter() ); } /** @@ -979,7 +948,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public double getMargin( short margin ) { - return getSheet().getMargin( margin ); + return sheet.getPageSettings().getMargin( margin ); } /** @@ -989,7 +958,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public void setMargin( short margin, double size ) { - getSheet().setMargin( margin, size ); + sheet.getPageSettings().setMargin( margin, size ); } /** @@ -1112,8 +1081,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet //don't check if it's not within the shifted area if (!inStart || !inEnd) { - continue; - } + continue; + } //only shift if the region outside the shifted rows is not merged too if (!containsCell(merged, startRow-1, 0) && !containsCell(merged, endRow+1, 0)){ @@ -1129,7 +1098,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet //read so it doesn't get shifted again Iterator iterator = shiftedRegions.iterator(); while (iterator.hasNext()) { - CellRangeAddress region = (CellRangeAddress)iterator.next(); + CellRangeAddress region = (CellRangeAddress)iterator.next(); this.addMergedRegion(region); } @@ -1179,7 +1148,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public void shiftRows( int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) { - shiftRows(startRow, endRow, n, copyRowHeight, resetOriginalRowHeight, true); + shiftRows(startRow, endRow, n, copyRowHeight, resetOriginalRowHeight, true); } /** @@ -1216,7 +1185,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet } shiftMerged(startRow, endRow, n, true); - sheet.shiftRowBreaks(startRow, endRow, n); + sheet.getPageSettings().shiftRowBreaks(startRow, endRow, n); for ( int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc ) { @@ -1241,8 +1210,8 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet // Fetch the first and last columns of the // row now, so we still have them to hand // once we start removing cells - short firstCol = row.getFirstCellNum(); - short lastCol = row.getLastCellNum(); + short firstCol = row.getFirstCellNum(); + short lastCol = row.getLastCellNum(); // Fix up row heights if required if (copyRowHeight) { @@ -1255,7 +1224,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet // Copy each cell from the source row to // the destination row for(Iterator cells = row.cellIterator(); cells.hasNext(); ) { - cell = (HSSFCell)cells.next(); + cell = (HSSFCell)cells.next(); row.removeCell( cell ); CellValueRecordInterface cellRecord = cell.getCellValueRecord(); cellRecord.setRow( rowNum + n ); @@ -1269,12 +1238,12 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet // destination row. Note that comments can // exist for cells which are null if(moveComments) { - for( short col = firstCol; col <= lastCol; col++ ) { - HSSFComment comment = getCellComment(rowNum, col); - if (comment != null) { - comment.setRow(rowNum + n); - } - } + for( short col = firstCol; col <= lastCol; col++ ) { + HSSFComment comment = getCellComment(rowNum, col); + if (comment != null) { + comment.setRow(rowNum + n); + } + } } } if ( endRow == lastrow || endRow + n > lastrow ) lastrow = Math.min( endRow + n, 65535 ); @@ -1443,24 +1412,21 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public void setRowBreak(int row) { validateRow(row); - sheet.setRowBreak(row, (short)0, (short)255); + sheet.getPageSettings().setRowBreak(row, (short)0, (short)255); } /** - * Determines if there is a page break at the indicated row - * @param row FIXME: Document this! - * @return FIXME: Document this! + * @return true if there is a page break at the indicated row */ public boolean isRowBroken(int row) { - return sheet.isRowBroken(row); + return sheet.getPageSettings().isRowBroken(row); } /** * Removes the page break at the indicated row - * @param row */ public void removeRowBreak(int row) { - sheet.removeRowBreak(row); + sheet.getPageSettings().removeRowBreak(row); } /** @@ -1468,7 +1434,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public int[] getRowBreaks(){ //we can probably cache this information, but this should be a sparsely used function - return sheet.getRowBreaks(); + return sheet.getPageSettings().getRowBreaks(); } /** @@ -1476,7 +1442,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public int[] getColumnBreaks(){ //we can probably cache this information, but this should be a sparsely used function - return sheet.getColumnBreaks(); + return sheet.getPageSettings().getColumnBreaks(); } @@ -1486,7 +1452,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet */ public void setColumnBreak(short column) { validateColumn(column); - sheet.setColumnBreak(column, (short)0, (short)65535); + sheet.getPageSettings().setColumnBreak(column, (short)0, (short)65535); } /** @@ -1495,7 +1461,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet * @return FIXME: Document this! */ public boolean isColumnBroken(short column) { - return sheet.isColumnBroken(column); + return sheet.getPageSettings().isColumnBroken(column); } /** @@ -1503,7 +1469,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet * @param column */ public void removeColumnBreak(short column) { - sheet.removeColumnBreak(column); + sheet.getPageSettings().removeColumnBreak(column); } /** @@ -1610,9 +1576,9 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet * start from scratch! */ public HSSFPatriarch getDrawingPatriarch() { - EscherAggregate agg = getDrawingEscherAggregate(); - if(agg == null) return null; - + EscherAggregate agg = getDrawingEscherAggregate(); + if(agg == null) return null; + HSSFPatriarch patriarch = new HSSFPatriarch(this, agg); agg.setPatriarch(patriarch); @@ -1687,7 +1653,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet * @param column the column index */ public void autoSizeColumn(short column) { - autoSizeColumn(column, false); + autoSizeColumn(column, false); } /** @@ -1736,19 +1702,19 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet HSSFCell cell = row.getCell(column); if (cell == null) { - continue; - } + continue; + } int colspan = 1; for (int i = 0 ; i < getNumMergedRegions(); i++) { CellRangeAddress region = getMergedRegion(i); - if (containsCell(region, row.getRowNum(), column)) { - if (!useMergedCells) { - // If we're not using merged cells, skip this one and move on to the next. - continue rows; - } - cell = row.getCell(region.getFirstColumn()); - colspan = 1 + region.getLastColumn() - region.getFirstColumn(); + if (containsCell(region, row.getRowNum(), column)) { + if (!useMergedCells) { + // If we're not using merged cells, skip this one and move on to the next. + continue rows; + } + cell = row.getCell(region.getFirstColumn()); + colspan = 1 + region.getLastColumn() - region.getFirstColumn(); } } @@ -1839,7 +1805,7 @@ public class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet } if (width != -1) { if (width > Short.MAX_VALUE) { //width can be bigger that Short.MAX_VALUE! - width = Short.MAX_VALUE; + width = Short.MAX_VALUE; } sheet.setColumnWidth(column, (short) (width * 256)); } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index 5422776fc..e663f38f2 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -272,21 +272,11 @@ public class HSSFWorkbook extends POIDocument implements org.apache.poi.ss.userm // convert all LabelRecord records to LabelSSTRecord convertLabelRecords(records, recOffset); - while (recOffset < records.size()) - { + while (recOffset < records.size()) { Sheet sheet = Sheet.createSheet(records, sheetNum++, recOffset ); - recOffset = sheet.getEofLoc()+1; - if (recOffset == 1) - { - break; - } - - HSSFSheet hsheet = new HSSFSheet(this, sheet); - - _sheets.add(hsheet); - - // workbook.setSheetName(sheets.size() -1, "Sheet"+sheets.size()); + recOffset = sheet.getEofLoc()+1; // TODO - use better technique to keep track of the used records + _sheets.add(new HSSFSheet(this, sheet)); } for (int i = 0 ; i < workbook.getNumNames() ; ++i){ diff --git a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java index 0c46c5863..bbed1cfdb 100644 --- a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java +++ b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java @@ -59,8 +59,7 @@ public interface Row extends Iterable { * * @return HSSFCell a high level representation of the created cell. */ - - Cell createCell(short column, int type); + Cell createCell(int column, int type); /** * remove the HSSFCell from this row. diff --git a/src/testcases/org/apache/poi/hssf/model/TestSheet.java b/src/testcases/org/apache/poi/hssf/model/TestSheet.java index 40b349a54..0b245c0a7 100644 --- a/src/testcases/org/apache/poi/hssf/model/TestSheet.java +++ b/src/testcases/org/apache/poi/hssf/model/TestSheet.java @@ -39,8 +39,8 @@ import org.apache.poi.hssf.record.RowRecord; import org.apache.poi.hssf.record.StringRecord; import org.apache.poi.hssf.record.UncalcedRecord; import org.apache.poi.hssf.record.aggregates.ColumnInfoRecordsAggregate; +import org.apache.poi.hssf.record.aggregates.PageSettingsBlock; import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; -import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate; import org.apache.poi.hssf.util.CellRangeAddress; /** @@ -62,7 +62,6 @@ public final class TestSheet extends TestCase { assertTrue( sheet.records.get(pos++) instanceof ColumnInfoRecordsAggregate ); assertTrue( sheet.records.get(pos++) instanceof DimensionsRecord ); assertTrue( sheet.records.get(pos++) instanceof RowRecordsAggregate ); - assertTrue( sheet.records.get(pos++) instanceof ValueRecordsAggregate ); assertTrue( sheet.records.get(pos++) instanceof EOFRecord ); } @@ -209,7 +208,8 @@ public final class TestSheet extends TestCase { short colFrom = 0; short colTo = 255; - Sheet sheet = Sheet.createSheet(); + Sheet worksheet = Sheet.createSheet(); + PageSettingsBlock sheet = worksheet.getPageSettings(); sheet.setRowBreak(0, colFrom, colTo); assertTrue("no row break at 0", sheet.isRowBroken(0)); @@ -264,24 +264,25 @@ public final class TestSheet extends TestCase { short rowFrom = 0; short rowTo = (short)65535; - Sheet sheet = Sheet.createSheet(); + Sheet worksheet = Sheet.createSheet(); + PageSettingsBlock sheet = worksheet.getPageSettings(); sheet.setColumnBreak((short)0, rowFrom, rowTo); - assertTrue("no col break at 0", sheet.isColumnBroken((short)0)); + assertTrue("no col break at 0", sheet.isColumnBroken(0)); assertEquals("1 col break available", 1, sheet.getNumColumnBreaks()); sheet.setColumnBreak((short)0, rowFrom, rowTo); - assertTrue("no col break at 0", sheet.isColumnBroken((short)0)); + assertTrue("no col break at 0", sheet.isColumnBroken(0)); assertEquals("1 col break available", 1, sheet.getNumColumnBreaks()); sheet.setColumnBreak((short)1, rowFrom, rowTo); sheet.setColumnBreak((short)10, rowFrom, rowTo); sheet.setColumnBreak((short)15, rowFrom, rowTo); - assertTrue("no col break at 1", sheet.isColumnBroken((short)1)); - assertTrue("no col break at 10", sheet.isColumnBroken((short)10)); - assertTrue("no col break at 15", sheet.isColumnBroken((short)15)); + assertTrue("no col break at 1", sheet.isColumnBroken(1)); + assertTrue("no col break at 10", sheet.isColumnBroken(10)); + assertTrue("no col break at 15", sheet.isColumnBroken(15)); assertEquals("4 col break available", 4, sheet.getNumColumnBreaks()); boolean is10 = false; @@ -301,17 +302,17 @@ public final class TestSheet extends TestCase { assertTrue("one of the breaks didnt make it", is0 && is1 && is10 && is15); - sheet.removeColumnBreak((short)15); - assertFalse("column break should not be there", sheet.isColumnBroken((short)15)); + sheet.removeColumnBreak(15); + assertFalse("column break should not be there", sheet.isColumnBroken(15)); - sheet.removeColumnBreak((short)0); - assertFalse("column break should not be there", sheet.isColumnBroken((short)0)); + sheet.removeColumnBreak(0); + assertFalse("column break should not be there", sheet.isColumnBroken(0)); - sheet.removeColumnBreak((short)1); - assertFalse("column break should not be there", sheet.isColumnBroken((short)1)); + sheet.removeColumnBreak(1); + assertFalse("column break should not be there", sheet.isColumnBroken(1)); - sheet.removeColumnBreak((short)10); - assertFalse("column break should not be there", sheet.isColumnBroken((short)10)); + sheet.removeColumnBreak(10); + assertFalse("column break should not be there", sheet.isColumnBroken(10)); assertEquals("no more breaks", 0, sheet.getNumColumnBreaks()); } @@ -434,12 +435,12 @@ public final class TestSheet extends TestCase { throw new AssertionFailedError("Identified bug 45145"); } - // make sure that RRA and VRA are in the right place - int rraIx = sheet.getDimsLoc()+1; - List recs = sheet.getRecords(); - assertEquals(RowRecordsAggregate.class, recs.get(rraIx).getClass()); - assertEquals(ValueRecordsAggregate.class, recs.get(rraIx+1).getClass()); - + if (false) { + // make sure that RRA and VRA are in the right place + // (Aug 2008) since the VRA is now part of the RRA, there is much less chance that + // they could get out of order. Still, one could write serialize the sheet here, + // and read back with EventRecordFactory to make sure... + } assertEquals(242, dbCellRecordPos); } diff --git a/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java b/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java index 5c14b70e1..2ae2eebc4 100755 --- a/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java +++ b/src/testcases/org/apache/poi/hssf/record/aggregates/TestValueRecordsAggregate.java @@ -106,9 +106,7 @@ public class TestValueRecordsAggregate extends TestCase assertTrue( iterator.hasNext() ); } - public void testRemoveCell() - throws Exception - { + public void testRemoveCell() { BlankRecord blankRecord1 = newBlankRecord(); valueRecord.insertCell( blankRecord1 ); BlankRecord blankRecord2 = newBlankRecord(); @@ -118,10 +116,6 @@ public class TestValueRecordsAggregate extends TestCase // removing an already empty cell just falls through valueRecord.removeCell( blankRecord2 ); - - // even trying to remove null just falls through silently. - valueRecord.removeCell( null ); - } public void testGetPhysicalNumberOfCells() throws Exception @@ -204,22 +198,6 @@ public class TestValueRecordsAggregate extends TestCase return blankRecord; } - public void testGetRecordSize() throws Exception - { - List records = testData(); - valueRecord.construct( 0, records ); - assertEquals( 36, valueRecord.getRecordSize() ); - } - - public void testClone() throws Exception - { - List records = testData(); - valueRecord.construct( 0, records ); - valueRecord = (ValueRecordsAggregate) valueRecord.clone(); - assertEquals( 36, valueRecord.getRecordSize() ); - } - - /** * Sometimes the 'shared formula' flag (FormulaRecord.isSharedFormula()) is set when * there is no corresponding SharedFormulaRecord available. SharedFormulaRecord definitions do diff --git a/src/testcases/org/apache/poi/hssf/usermodel/SanityChecker.java b/src/testcases/org/apache/poi/hssf/usermodel/SanityChecker.java index 0235564b3..0d5fbdc9b 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/SanityChecker.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/SanityChecker.java @@ -23,6 +23,7 @@ import junit.framework.Assert; 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.aggregates.PageSettingsBlock; import java.util.List; @@ -106,7 +107,6 @@ public class SanityChecker } return matchOneOrMany( records, firstRecord ); -// return matchOneOrMany( records, recordIdx ); } private int matchRequired( int firstRecord, List records, int recordIdx ) @@ -117,7 +117,6 @@ public class SanityChecker } return matchOneOrMany( records, firstRecord ); -// return matchOneOrMany( records, recordIdx ); } private int matchOneOrMany( List records, int recordIdx ) @@ -204,11 +203,7 @@ public class SanityChecker new CheckRecord(GutsRecord.class, '1'), new CheckRecord(DefaultRowHeightRecord.class, '1'), new CheckRecord(WSBoolRecord.class, '1'), - new CheckRecord(HeaderRecord.class, '1'), - new CheckRecord(FooterRecord.class, '1'), - new CheckRecord(HCenterRecord.class, '1'), - new CheckRecord(VCenterRecord.class, '1'), - new CheckRecord(PrintSetupRecord.class, '1'), + new CheckRecord(PageSettingsBlock.class, '1'), new CheckRecord(DefaultColWidthRecord.class, '1'), new CheckRecord(DimensionsRecord.class, '1'), new CheckRecord(WindowTwoRecord.class, '1'), @@ -275,7 +270,7 @@ public class SanityChecker } } */ - private static int findFirstRecord( List records, Class record, int startIndex ) + /* package */ static int findFirstRecord( List records, Class record, int startIndex ) { for (int i = startIndex; i < records.size(); i++) { @@ -285,11 +280,6 @@ public class SanityChecker return -1; } -// private static int findFirstRecord( List records, Class record ) -// { -// return findFirstRecord ( records, record, 0 ); -// } - void checkRecordOrder(List records, CheckRecord[] check) { int recordIdx = 0; diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 646321d3d..3343757ad 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -34,7 +34,6 @@ import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.CellValueRecordInterface; import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord; -import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.NameRecord; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.formula.DeletedArea3DPtg; @@ -992,8 +991,8 @@ public final class TestBugs extends TestCase { assertEquals("Forms.CheckBox.1", obj.getOLE2ClassName()); try { - obj.getDirectory(); - fail(); + obj.getDirectory(); + fail(); } catch(FileNotFoundException e) {} } @@ -1012,12 +1011,12 @@ public final class TestBugs extends TestCase { // DeletedArea3DPtg Workbook w = wb.getWorkbook(); for(int i=0; i 0; x=(short)(x*2)) { - r = s.createRow((short) x); + for (int x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) { + r = s.createRow(x); - for (short y = 1; y < 256 && y > 0; y++) { + for (int y = 1; y < 256 && y > 0; y++) { String ref=null; String ref2=null; @@ -296,13 +296,13 @@ public final class TestFormulas extends TestCase { refy2=(short)(y-3); } - c = r.getCell((short) y); + c = r.getCell(y); CellReference cr= new CellReference(refx1,refy1, false, false); ref=cr.formatAsString(); cr=new CellReference(refx2,refy2, false, false); ref2=cr.formatAsString(); - c = r.createCell((short) y); + c = r.createCell(y); c.setCellFormula("" + ref + operator + ref2); @@ -312,8 +312,8 @@ public final class TestFormulas extends TestCase { //make sure we do the maximum value of the Int operator if (s.getLastRowNum() < Short.MAX_VALUE) { - r = s.createRow((short)0); - c = r.createCell((short)0); + r = s.getRow(0); + c = r.createCell(0); c.setCellFormula("" + "B1" + operator + "IV255"); } @@ -453,16 +453,16 @@ public final class TestFormulas extends TestCase { HSSFCell c = null; //get our minimum values - r = s.createRow((short)0); - c = r.createCell((short)1); + r = s.createRow(0); + c = r.createCell(1); c.setCellFormula(1 + operator + 1); - for (short x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) { - r = s.createRow((short) x); + for (int x = 1; x < Short.MAX_VALUE && x > 0; x=(short)(x*2)) { + r = s.createRow(x); - for (short y = 1; y < 256 && y > 0; y++) { + for (int y = 1; y < 256 && y > 0; y++) { - c = r.createCell((short) y); + c = r.createCell(y); c.setCellFormula("" + x + operator + y); } @@ -470,8 +470,8 @@ public final class TestFormulas extends TestCase { //make sure we do the maximum value of the Int operator if (s.getLastRowNum() < Short.MAX_VALUE) { - r = s.createRow((short)0); - c = r.createCell((short)0); + r = s.getRow(0); + c = r.createCell(0); c.setCellFormula("" + Short.MAX_VALUE + operator + Short.MAX_VALUE); } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java index 2c8287f4b..a24e5e797 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java @@ -71,8 +71,7 @@ public final class TestHSSFSheet extends TestCase { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet s = wb.createSheet(); Sheet sheet = s.getSheet(); - VCenterRecord record = - (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid); + VCenterRecord record = sheet.getPageSettings().getVCenter(); assertEquals(false, record.getVCenter()); s.setVerticallyCenter(true); @@ -88,8 +87,7 @@ public final class TestHSSFSheet extends TestCase { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet s = wb.createSheet(); Sheet sheet = s.getSheet(); - HCenterRecord record = - (HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid); + HCenterRecord record = sheet.getPageSettings().getHCenter(); assertEquals(false, record.getHCenter()); s.setHorizontallyCenter(true); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestWorkbook.java b/src/testcases/org/apache/poi/hssf/usermodel/TestWorkbook.java index 916f6f4f0..c0231cdfe 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestWorkbook.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestWorkbook.java @@ -17,6 +17,7 @@ package org.apache.poi.hssf.usermodel; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -26,11 +27,13 @@ import java.util.Iterator; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.hssf.eventmodel.ERFListener; +import org.apache.poi.hssf.eventmodel.EventRecordFactory; import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.BackupRecord; import org.apache.poi.hssf.record.LabelSSTRecord; import org.apache.poi.hssf.record.Record; -import org.apache.poi.hssf.record.aggregates.ValueRecordsAggregate; +import org.apache.poi.hssf.record.aggregates.RowRecordsAggregate; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.Region; @@ -94,7 +97,7 @@ public final class TestWorkbook extends TestCase { + ((( double ) rownum / 1000) + (( double ) cellnum / 10000))); c = r.createCell(( short ) (cellnum + 1)); - c.setCellValue("TEST"); + c.setCellValue(new HSSFRichTextString("TEST")); } } wb.write(out); @@ -140,7 +143,7 @@ public final class TestWorkbook extends TestCase { + ((( double ) rownum / 1000) + (( double ) cellnum / 10000))); c = r.createCell(( short ) (cellnum + 1)); - c.setCellValue("TEST"); + c.setCellValue(new HSSFRichTextString("TEST")); } } for (short rownum = ( short ) 0; rownum < 25; rownum++) @@ -311,9 +314,9 @@ public final class TestWorkbook extends TestCase { HSSFSheet sheet = workbook.getSheetAt(0); HSSFCell cell = sheet.getRow(0).getCell(1); - cell.setCellValue(REPLACED); + cell.setCellValue(new HSSFRichTextString(REPLACED)); cell = sheet.getRow(1).getCell(0); - cell.setCellValue(REPLACED); + cell.setCellValue(new HSSFRichTextString(REPLACED)); workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook); @@ -381,11 +384,11 @@ public final class TestWorkbook extends TestCase { HSSFSheet sheet = workbook.getSheetAt(0); HSSFCell cell = sheet.getRow(3).getCell(2); - cell.setCellValue(LAST_NAME_VALUE); + cell.setCellValue(new HSSFRichTextString(LAST_NAME_VALUE)); cell = sheet.getRow(4).getCell(2); - cell.setCellValue(FIRST_NAME_VALUE); + cell.setCellValue(new HSSFRichTextString(FIRST_NAME_VALUE)); cell = sheet.getRow(5).getCell(2); - cell.setCellValue(SSN_VALUE); + cell.setCellValue(new HSSFRichTextString(SSN_VALUE)); workbook = HSSFTestDataSamples.writeOutAndReadBack(workbook); sheet = workbook.getSheetAt(0); @@ -454,13 +457,13 @@ public final class TestWorkbook extends TestCase { } private static void confirmRegion(CellRangeAddress ra, CellRangeAddress rb) { - assertEquals(ra.getFirstRow(), rb.getFirstRow()); - assertEquals(ra.getLastRow(), rb.getLastRow()); - assertEquals(ra.getFirstColumn(), rb.getFirstColumn()); - assertEquals(ra.getLastColumn(), rb.getLastColumn()); - } + assertEquals(ra.getFirstRow(), rb.getFirstRow()); + assertEquals(ra.getLastRow(), rb.getLastRow()); + assertEquals(ra.getFirstColumn(), rb.getFirstColumn()); + assertEquals(ra.getLastColumn(), rb.getLastColumn()); + } - /** + /** * Test the backup field gets set as expected. */ @@ -477,51 +480,52 @@ public final class TestWorkbook extends TestCase { assertEquals(1, record.getBackup()); } + private static final class RecordCounter implements ERFListener { + private int _count; + + public RecordCounter() { + _count=0; + } + public int getCount() { + return _count; + } + public boolean processRecord(Record rec) { + _count++; + return true; + } + } + /** * This tests is for bug [ #506658 ] Repeating output. * * We need to make sure only one LabelSSTRecord is produced. */ - public void testRepeatingBug() throws Exception { HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet("Design Variants"); - HSSFRow row = sheet.createRow(( short ) 2); - HSSFCell cell = row.createCell(( short ) 1); + HSSFRow row = sheet.createRow(2); + HSSFCell cell = row.createCell(1); cell.setCellValue(new HSSFRichTextString("Class")); - cell = row.createCell(( short ) 2); + cell = row.createCell(2); - // workbook.write(new FileOutputStream("/a2.xls")); - ValueRecordsAggregate valueAggregate = - ( ValueRecordsAggregate ) sheet.getSheet() - .findFirstRecordBySid(ValueRecordsAggregate.sid); - int sstRecords = 0; - Iterator iterator = valueAggregate.getIterator(); - - while (iterator.hasNext()) - { - if ((( Record ) iterator.next()).getSid() == LabelSSTRecord.sid) - { - sstRecords++; - } - } - assertEquals(1, sstRecords); + byte[] data = new byte[sheet.getSheet().getSize()]; + sheet.getSheet().serialize(0, data); + RecordCounter rc = new RecordCounter(); + EventRecordFactory erf = new EventRecordFactory(rc, new short[] { LabelSSTRecord.sid, }); + erf.processRecords(new ByteArrayInputStream(data)); + + assertEquals(1, rc.getCount()); } - public void testManyRows() - throws Exception - { - String testName = "TestManyRows"; - File file = TempFile.createTempFile(testName, ".xls"); - FileOutputStream out = new FileOutputStream(file); + public void testManyRows() { HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet(); - HSSFRow row = null; - HSSFCell cell = null; + HSSFRow row; + HSSFCell cell; int i, j; for ( i = 0, j = 32771; j > 0; i++, j-- ) { @@ -529,22 +533,17 @@ public final class TestWorkbook extends TestCase { cell = row.createCell((short) 0); cell.setCellValue(i); } - workbook.write(out); - out.close(); sanityChecker.checkHSSFWorkbook(workbook); assertEquals("LAST ROW == 32770", 32770, sheet.getLastRowNum()); + cell = sheet.getRow(32770).getCell(0); double lastVal = cell.getNumericCellValue(); - FileInputStream in = new FileInputStream(file); - POIFSFileSystem fs = new POIFSFileSystem(in); - HSSFWorkbook wb = new HSSFWorkbook(fs); + HSSFWorkbook wb = HSSFTestDataSamples.writeOutAndReadBack(workbook); HSSFSheet s = wb.getSheetAt(0); row = s.getRow(32770); - cell = row.getCell(( short ) 0); + cell = row.getCell(0); assertEquals("Value from last row == 32770", lastVal, cell.getNumericCellValue(), 0); assertEquals("LAST ROW == 32770", 32770, s.getLastRowNum()); - in.close(); - file.deleteOnExit(); } /** @@ -571,10 +570,4 @@ public final class TestWorkbook extends TestCase { assertTrue("file exists",file.exists()); } - - - public static void main(String [] ignored_args) - { - junit.textui.TestRunner.run(TestWorkbook.class); - } }