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 11ee42b6a..d49c0f72d 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; @@ -40,17 +39,12 @@ 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; @@ -60,17 +54,13 @@ 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.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; @@ -78,6 +68,7 @@ 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.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.RecordAggregate.RecordVisitor; @@ -119,33 +110,32 @@ public final class Sheet implements Model { protected ArrayList records = null; int preoffset = 0; // offset of the sheet in a new file protected int dimsloc = -1; // TODO - is it legal for dims record to be missing? - protected DimensionsRecord dims; - protected DefaultColWidthRecord defaultcolwidth = null; - protected DefaultRowHeightRecord defaultrowheight = null; + protected PrintGridlinesRecord printGridlines = 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 RowRecordsAggregate _rowsAggregate = null; - private Iterator rowRecIterator = null; - protected int eofLoc = 0; + protected DefaultColWidthRecord defaultcolwidth = null; + protected DefaultRowHeightRecord defaultrowheight = null; + 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; @@ -247,13 +237,28 @@ public final class Sheet implements Model { } 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) @@ -304,34 +309,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; @@ -356,14 +333,6 @@ 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; - } records.add(rec); } @@ -463,20 +432,9 @@ public final class Sheet implements Model { records.add( retval.createWSBool() ); // 'Page Settings Block' - retval._rowBreaksRecord = new HorizontalPageBreakRecord(); - records.add(retval._rowBreaksRecord); - retval._columnBreaksRecord = new VerticalPageBreakRecord(); - records.add(retval._columnBreaksRecord); - - retval.header = createHeader(); - records.add( retval.header ); - retval.footer = createFooter(); - records.add( retval.footer ); - records.add(createHCenter() ); - records.add(createVCenter() ); - retval.printSetup = createPrintSetup(); - records.add( retval.printSetup ); - + retval._psBlock = new PageSettingsBlock(); + records.add(retval._psBlock); + // 'Worksheet Protection Block' (after 'Page Settings Block' and before DEFCOLWIDTH) // PROTECT record normally goes here, don't add yet since the flag is initially false @@ -1061,70 +1019,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 @@ -1563,7 +1457,7 @@ public final class Sheet implements Model { */ public HeaderRecord getHeader () { - return header; + return getPageSettings().getHeader(); } public WindowTwoRecord getWindowTwo() { @@ -1575,7 +1469,7 @@ public final class Sheet implements Model { */ public void setHeader (HeaderRecord newHeader) { - header = newHeader; + getPageSettings().setHeader(newHeader); } /** @@ -1584,7 +1478,7 @@ public final class Sheet implements Model { */ public FooterRecord getFooter () { - return footer; + return getPageSettings().getFooter(); } /** @@ -1593,7 +1487,7 @@ public final class Sheet implements Model { */ public void setFooter (FooterRecord newFooter) { - footer = newFooter; + getPageSettings().setFooter(newFooter); } /** @@ -1602,7 +1496,7 @@ public final class Sheet implements Model { */ public PrintSetupRecord getPrintSetup () { - return printSetup; + return getPageSettings().getPrintSetup(); } /** @@ -1611,7 +1505,7 @@ public final class Sheet implements Model { */ public void setPrintSetup (PrintSetupRecord newPrintSetup) { - printSetup = newPrintSetup; + getPageSettings().setPrintSetup(newPrintSetup); } /** @@ -1646,23 +1540,7 @@ public final class Sheet implements Model { * @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 ); - } - } + return getPageSettings().getMargin(margin); } /** @@ -1671,32 +1549,7 @@ public final class Sheet implements Model { * @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 ); + getPageSettings().setMargin(margin, size); } public int getEofLoc() @@ -1947,17 +1800,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 @@ -2026,60 +1868,22 @@ 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); - } - } - - private PageBreakRecord getRowBreaksRecord() { - if (_rowBreaksRecord == null) { - _rowBreaksRecord = new HorizontalPageBreakRecord(); - RecordOrderer.addNewSheetRecord(records, _rowBreaksRecord); + + public PageSettingsBlock getPageSettings() { + if (_psBlock == null) { + _psBlock = new PageSettingsBlock(); + RecordOrderer.addNewSheetRecord(records, _psBlock); dimsloc++; } - return _rowBreaksRecord; + return _psBlock; } - - 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); + getPageSettings().setRowBreak(row, fromCol, toCol); } /** @@ -2087,9 +1891,7 @@ public final class Sheet implements Model { * @param row */ public void removeRowBreak(int row) { - if (getRowBreaks() == null) - throw new IllegalArgumentException("Sheet does not define any row breaks"); - getRowBreaksRecord().removeBreak((short)row); + getPageSettings().removeRowBreak(row); } /** @@ -2098,7 +1900,7 @@ public final class Sheet implements Model { * @return true if the specified row has a page break */ public boolean isRowBroken(int row) { - return getRowBreaksRecord().getBreak(row) != null; + return getPageSettings().isRowBroken(row); } /** @@ -2106,7 +1908,7 @@ public final class Sheet implements Model { * */ public void setColumnBreak(short column, short fromRow, short toRow) { - getColumnBreaksRecord().addBreak(column, fromRow, toRow); + getPageSettings().setColumnBreak(column, fromRow, toRow); } /** @@ -2114,7 +1916,7 @@ public final class Sheet implements Model { * */ public void removeColumnBreak(short column) { - getColumnBreaksRecord().removeBreak(column); + getPageSettings().removeColumnBreak(column); } /** @@ -2123,7 +1925,7 @@ public final class Sheet implements Model { * @returntrue
if the specified column has a page break
*/
public boolean isColumnBroken(short column) {
- return getColumnBreaksRecord().getBreak(column) != null;
+ return getPageSettings().isColumnBroken(column);
}
/**
@@ -2133,7 +1935,7 @@ public final class Sheet implements Model {
* @param count
*/
public void shiftRowBreaks(int startingRow, int endingRow, int count) {
- shiftBreaks(getRowBreaksRecord(), startingRow, endingRow, count);
+ getPageSettings().shiftRowBreaks(startingRow, endingRow, count);
}
/**
@@ -2143,35 +1945,35 @@ public final class Sheet implements Model {
* @param count
*/
public void shiftColumnBreaks(short startingCol, short endingCol, short count) {
- shiftBreaks(getColumnBreaksRecord(), startingCol, endingCol, count);
+ getPageSettings().shiftColumnBreaks(startingCol, endingCol, count);
}
/**
* @return all the horizontal page breaks, never null
*/
public int[] getRowBreaks() {
- return getRowBreaksRecord().getBreaks();
+ return getPageSettings().getRowBreaks();
}
/**
* @return the number of row page breaks
*/
public int getNumRowBreaks(){
- return getRowBreaksRecord().getNumBreaks();
+ return getPageSettings().getNumRowBreaks();
}
/**
* @return all the column page breaks, never null
*/
public int[] getColumnBreaks(){
- return getColumnBreaksRecord().getBreaks();
+ return getPageSettings().getColumnBreaks();
}
/**
* @return the number of column page breaks
*/
public int getNumColumnBreaks(){
- return getColumnBreaksRecord().getNumBreaks();
+ return getPageSettings().getNumColumnBreaks();
}
public void setColumnGroupCollapsed( short columnNumber, boolean collapsed )
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/aggregates/PageSettingsBlock.java b/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java new file mode 100644 index 000000000..04f508967 --- /dev/null +++ b/src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java @@ -0,0 +1,526 @@ +/* ==================================================================== + 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(); + } + + /** + * @returntrue
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(short 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(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 VCenterRecord getVCenter() {
+ return _vCenter;
+ }
+
+ public HCenterRecord getHCenter() {
+ return _hCenter;
+ }
+
+}
diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
index 746b2d2f1..13f942c29 100644
--- a/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
+++ b/src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
@@ -547,10 +547,7 @@ public final class HSSFSheet {
public void setVerticallyCenter(boolean value)
{
- VCenterRecord record =
- (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid);
-
- record.setVCenter(value);
+ sheet.getPageSettings().getVCenter().setVCenter(value);
}
/**
@@ -566,10 +563,7 @@ public final class HSSFSheet {
*/
public boolean getVerticallyCenter()
{
- VCenterRecord record =
- (VCenterRecord) sheet.findFirstRecordBySid(VCenterRecord.sid);
-
- return record.getVCenter();
+ return sheet.getPageSettings().getVCenter().getVCenter();
}
/**
@@ -579,10 +573,7 @@ public final class HSSFSheet {
public void setHorizontallyCenter(boolean value)
{
- HCenterRecord record =
- (HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid);
-
- record.setHCenter(value);
+ sheet.getPageSettings().getHCenter().setHCenter(value);
}
/**
@@ -591,10 +582,8 @@ public final class HSSFSheet {
public boolean getHorizontallyCenter()
{
- HCenterRecord record =
- (HCenterRecord) sheet.findFirstRecordBySid(HCenterRecord.sid);
- return record.getHCenter();
+ return sheet.getPageSettings().getHCenter().getHCenter();
}
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/TestHSSFSheet.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
index 1a678af68..1550f7721 100644
--- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
+++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java
@@ -70,8 +70,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);
@@ -87,8 +86,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);