]> source.dussan.org Git - poi.git/commitdiff
merged with trunk
authorEvgeniy Berlog <berlog@apache.org>
Sun, 5 Aug 2012 13:05:44 +0000 (13:05 +0000)
committerEvgeniy Berlog <berlog@apache.org>
Sun, 5 Aug 2012 13:05:44 +0000 (13:05 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/gsoc2012@1369572 13f79535-47bb-0310-9956-ffa450edef68

1  2 
src/java/org/apache/poi/hssf/model/InternalSheet.java
src/java/org/apache/poi/hssf/record/aggregates/PageSettingsBlock.java
src/java/org/apache/poi/hssf/usermodel/HSSFSheet.java
src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java
src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java

index 5236e184b8912beb961a190f60e6c461d0788074,30d3fc62957c97b7f4d01f1d22e858be5e7eb236..c183b5070a47b37ffa73c4e2805ed7efb5de6db2
@@@ -210,432 -212,432 +212,432 @@@ public final class PageSettingsBlock ex
                      _sviewHeaderFooters.add(hf);
                  }
                  break;
-                       default:
-                               // all other record types are not part of the PageSettingsBlock
-                               return false;
-               }
-               return true;
-       }
-       private void checkNotPresent(Record rec) {
-               if (rec != null) {
-                       throw new RecordFormatException("Duplicate PageSettingsBlock record (sid=0x"
-                                       + Integer.toHexString(rec.getSid()) + ")");
-               }
-       }
-       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) {
-               // Replicates record order from Excel 2007, though this is not critical
-               visitIfPresent(_rowBreaksRecord, rv);
-               visitIfPresent(_columnBreaksRecord, rv);
-               // Write out empty header / footer records if these are missing
-               if (_header == null) {
-                       rv.visitRecord(new HeaderRecord(""));
-               } else {
-                       rv.visitRecord(_header);
-               }
-               if (_footer == null) {
-                       rv.visitRecord(new FooterRecord(""));
-               } else {
-                       rv.visitRecord(_footer);
-               }
-               visitIfPresent(_hCenter, rv);
-               visitIfPresent(_vCenter, rv);
-               visitIfPresent(_leftMargin, rv);
-               visitIfPresent(_rightMargin, rv);
-               visitIfPresent(_topMargin, rv);
-               visitIfPresent(_bottomMargin, rv);
-               for (RecordAggregate pls : _plsRecords) {
-                       pls.visitContainedRecords(rv);
-               }
-               visitIfPresent(_printSetup, rv);
-               visitIfPresent(_printSize, rv);
-               visitIfPresent(_headerFooter, rv);
+             default:
+                 // all other record types are not part of the PageSettingsBlock
+                 return false;
+         }
+         return true;
+     }
+     private void checkNotPresent(Record rec) {
+         if (rec != null) {
+             throw new RecordFormatException("Duplicate PageSettingsBlock record (sid=0x"
+                     + Integer.toHexString(rec.getSid()) + ")");
+         }
+     }
+     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) {
+         // Replicates record order from Excel 2007, though this is not critical
+         visitIfPresent(_rowBreaksRecord, rv);
+         visitIfPresent(_columnBreaksRecord, rv);
+         // Write out empty header / footer records if these are missing
+         if (_header == null) {
+             rv.visitRecord(new HeaderRecord(""));
+         } else {
+             rv.visitRecord(_header);
+         }
+         if (_footer == null) {
+             rv.visitRecord(new FooterRecord(""));
+         } else {
+             rv.visitRecord(_footer);
+         }
+         visitIfPresent(_hCenter, rv);
+         visitIfPresent(_vCenter, rv);
+         visitIfPresent(_leftMargin, rv);
+         visitIfPresent(_rightMargin, rv);
+         visitIfPresent(_topMargin, rv);
+         visitIfPresent(_bottomMargin, rv);
+         for (RecordAggregate pls : _plsRecords) {
+             pls.visitContainedRecords(rv);
+         }
+         visitIfPresent(_printSetup, rv);
 -        visitIfPresent(_bitmap, rv);
+         visitIfPresent(_printSize, rv);
+         visitIfPresent(_headerFooter, rv);
 +        visitIfPresent(_bitmap, rv);
-       }
-       private static void visitIfPresent(Record r, RecordVisitor rv) {
-               if (r != null) {
-                       rv.visitRecord(r);
-               }
-       }
-       private static void visitIfPresent(PageBreakRecord r, RecordVisitor rv) {
-               if (r != null) {
-                       if (r.isEmpty()) {
-                               // its OK to not serialize empty page break records
-                               return;
-                       }
-                       rv.visitRecord(r);
-               }
-       }
-       /**
-        * 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 ) 1);
-               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 InternalSheet.LeftMargin:   return _leftMargin;
-                       case InternalSheet.RightMargin:  return _rightMargin;
-                       case InternalSheet.TopMargin:    return _topMargin;
-                       case InternalSheet.BottomMargin: return _bottomMargin;
-               }
-               throw new IllegalArgumentException( "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();
-               }
-               switch (margin) {
-                       case InternalSheet.LeftMargin:   return .75;
-                       case InternalSheet.RightMargin:  return .75;
-                       case InternalSheet.TopMargin:    return 1.0;
-                       case InternalSheet.BottomMargin: return 1.0;
-               }
-               throw new IllegalArgumentException( "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 InternalSheet.LeftMargin:
-                                       _leftMargin = new LeftMarginRecord();
-                                       m = _leftMargin;
-                                       break;
-                               case InternalSheet.RightMargin:
-                                       _rightMargin = new RightMarginRecord();
-                                       m = _rightMargin;
-                                       break;
-                               case InternalSheet.TopMargin:
-                                       _topMargin = new TopMarginRecord();
-                                       m = _topMargin;
-                                       break;
-                               case InternalSheet.BottomMargin:
-                                       _bottomMargin = new BottomMarginRecord();
-                                       m = _bottomMargin;
-                                       break;
-                               default :
-                                       throw new IllegalArgumentException( "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<PageBreakRecord.Break> iterator = breaks.getBreaksIterator();
-               List<PageBreakRecord.Break> shiftedBreak = new ArrayList<PageBreakRecord.Break>();
-               while(iterator.hasNext())
-               {
-                       PageBreakRecord.Break breakItem = 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 = 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 <code>true</code> 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 <code>null</code>
-        */
-       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 <code>null</code>
-        */
-       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;
-       }
-       /**
-        * HEADERFOOTER is new in 2007.  Some apps seem to have scattered this record long after
-        * the {@link PageSettingsBlock} where it belongs.
-        */
-       public void addLateHeaderFooter(HeaderFooterRecord rec) {
-               if (_headerFooter != null) {
-                       throw new IllegalStateException("This page settings block already has a header/footer record");
-               }
-               if (rec.getSid() != HeaderFooterRecord.sid) {
-                       throw new RecordFormatException("Unexpected header-footer record sid: 0x" + Integer.toHexString(rec.getSid()));
-               }
-               _headerFooter = rec;
-       }
-       /**
-        * This method reads PageSettingsBlock records from the supplied RecordStream until the first
-        * non-PageSettingsBlock record is encountered.  As each record is read, it is incorporated
-        * into this PageSettingsBlock.
-        * <p/>
-        * The latest Excel version seems to write the PageSettingsBlock uninterrupted. However there
-        * are several examples (that Excel reads OK) where these records are not written together:
-        * <ul>
-        * <li><b>HEADER_FOOTER(0x089C) after WINDOW2</b> - This record is new in 2007.  Some apps
-        * seem to have scattered this record long after the PageSettingsBlock where it belongs
-        * test samples: SharedFormulaTest.xls, ex44921-21902.xls, ex42570-20305.xls</li>
-        * <li><b>PLS, WSBOOL, PageSettingsBlock</b> - WSBOOL is not a PSB record.
-        * This happens in the test sample file "NoGutsRecords.xls" and "WORKBOOK_in_capitals.xls"</li>
-        * <li><b>Margins after DIMENSION</b> - All of PSB should be before DIMENSION. (Bug-47199)</li>
-        * </ul>
-        * These were probably written by other applications (or earlier versions of Excel). It was
-        * decided to not write specific code for detecting each of these cases.  POI now tolerates
-        * PageSettingsBlock records scattered all over the sheet record stream, and in any order, but
-        * does not allow duplicates of any of those records.
-        *
-        * <p/>
-        * <b>Note</b> - when POI writes out this PageSettingsBlock, the records will always be written
-        * in one consolidated block (in the standard ordering) regardless of how scattered the records
-        * were when they were originally read.
-        *
-        * @throws  RecordFormatException if any PSB record encountered has the same type (sid) as
-        * a record that is already part of this PageSettingsBlock
-        */
-       public void addLateRecords(RecordStream rs) {
-               while(true) {
-                       if (!readARecord(rs)) {
-                               break;
-                       }
-               }
-       }
+     }
+     private static void visitIfPresent(Record r, RecordVisitor rv) {
+         if (r != null) {
+             rv.visitRecord(r);
+         }
+     }
+     private static void visitIfPresent(PageBreakRecord r, RecordVisitor rv) {
+         if (r != null) {
+             if (r.isEmpty()) {
+                 // its OK to not serialize empty page break records
+                 return;
+             }
+             rv.visitRecord(r);
+         }
+     }
+     /**
+      * 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 ) 1);
+         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 InternalSheet.LeftMargin:   return _leftMargin;
+             case InternalSheet.RightMargin:  return _rightMargin;
+             case InternalSheet.TopMargin:    return _topMargin;
+             case InternalSheet.BottomMargin: return _bottomMargin;
+         }
+         throw new IllegalArgumentException( "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();
+         }
+         switch (margin) {
+             case InternalSheet.LeftMargin:   return .75;
+             case InternalSheet.RightMargin:  return .75;
+             case InternalSheet.TopMargin:    return 1.0;
+             case InternalSheet.BottomMargin: return 1.0;
+         }
+         throw new IllegalArgumentException( "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 InternalSheet.LeftMargin:
+                     _leftMargin = new LeftMarginRecord();
+                     m = _leftMargin;
+                     break;
+                 case InternalSheet.RightMargin:
+                     _rightMargin = new RightMarginRecord();
+                     m = _rightMargin;
+                     break;
+                 case InternalSheet.TopMargin:
+                     _topMargin = new TopMarginRecord();
+                     m = _topMargin;
+                     break;
+                 case InternalSheet.BottomMargin:
+                     _bottomMargin = new BottomMarginRecord();
+                     m = _bottomMargin;
+                     break;
+                 default :
+                     throw new IllegalArgumentException( "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<PageBreakRecord.Break> iterator = breaks.getBreaksIterator();
+         List<PageBreakRecord.Break> shiftedBreak = new ArrayList<PageBreakRecord.Break>();
+         while(iterator.hasNext())
+         {
+             PageBreakRecord.Break breakItem = 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 = 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 <code>true</code> 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 <code>null</code>
+      */
+     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 <code>null</code>
+      */
+     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;
+     }
+     /**
+      * HEADERFOOTER is new in 2007.  Some apps seem to have scattered this record long after
+      * the {@link PageSettingsBlock} where it belongs.
+      */
+     public void addLateHeaderFooter(HeaderFooterRecord rec) {
+         if (_headerFooter != null) {
+             throw new IllegalStateException("This page settings block already has a header/footer record");
+         }
+         if (rec.getSid() != HeaderFooterRecord.sid) {
+             throw new RecordFormatException("Unexpected header-footer record sid: 0x" + Integer.toHexString(rec.getSid()));
+         }
+         _headerFooter = rec;
+     }
+     /**
+      * This method reads PageSettingsBlock records from the supplied RecordStream until the first
+      * non-PageSettingsBlock record is encountered.  As each record is read, it is incorporated
+      * into this PageSettingsBlock.
+      * <p/>
+      * The latest Excel version seems to write the PageSettingsBlock uninterrupted. However there
+      * are several examples (that Excel reads OK) where these records are not written together:
+      * <ul>
+      * <li><b>HEADER_FOOTER(0x089C) after WINDOW2</b> - This record is new in 2007.  Some apps
+      * seem to have scattered this record long after the PageSettingsBlock where it belongs
+      * test samples: SharedFormulaTest.xls, ex44921-21902.xls, ex42570-20305.xls</li>
+      * <li><b>PLS, WSBOOL, PageSettingsBlock</b> - WSBOOL is not a PSB record.
+      * This happens in the test sample file "NoGutsRecords.xls" and "WORKBOOK_in_capitals.xls"</li>
+      * <li><b>Margins after DIMENSION</b> - All of PSB should be before DIMENSION. (Bug-47199)</li>
+      * </ul>
+      * These were probably written by other applications (or earlier versions of Excel). It was
+      * decided to not write specific code for detecting each of these cases.  POI now tolerates
+      * PageSettingsBlock records scattered all over the sheet record stream, and in any order, but
+      * does not allow duplicates of any of those records.
+      *
+      * <p/>
+      * <b>Note</b> - when POI writes out this PageSettingsBlock, the records will always be written
+      * in one consolidated block (in the standard ordering) regardless of how scattered the records
+      * were when they were originally read.
+      *
+      * @throws  RecordFormatException if any PSB record encountered has the same type (sid) as
+      * a record that is already part of this PageSettingsBlock
+      */
+     public void addLateRecords(RecordStream rs) {
+         while(true) {
+             if (!readARecord(rs)) {
+                 break;
+             }
+         }
+     }
  
      /**
       * Some apps can define multiple HeaderFooterRecord records for a sheet.
index f0ec2d6804b116472ed7588be5f0e1bad2e03dc0,40f85033cf97e762bece720d2e6b0c5a9a2bf5e6..bb3c92ced07b617a62afa2c58fe105973ad649eb
@@@ -371,6 -363,6 +373,7 @@@ public final class HSSFSheet implement
  
      /**
       * Creates a data validation object
++     *
       * @param dataValidation The Data validation object settings
       */
      public void addValidationData(DataValidation dataValidation) {
      /**
       * get the default row height for the sheet (if the rows do not define their own height) in
       * twips (1/20 of  a point)
 -     * @return  default row height
++     *
 +     * @return default row height
       */
      public short getDefaultRowHeight() {
          return _sheet.getDefaultRowHeight();
      /**
       * get the default row height for the sheet (if the rows do not define their own height) in
       * points.
 -     * @return  default row height in points
++     *
 +     * @return default row height in points
       */
  
 -    public float getDefaultRowHeightInPoints()
 -    {
 -        return ((float)_sheet.getDefaultRowHeight() / 20);
 +    public float getDefaultRowHeightInPoints() {
 +        return ((float) _sheet.getDefaultRowHeight() / 20);
      }
  
      /**
      /**
       * used internally in the API to get the low level Sheet record represented by this
       * Object.
++     *
       * @return Sheet - low level representation of this HSSFSheet.
       */
      InternalSheet getSheet() {
  
      /**
       * whether alternate expression evaluation is on
 -     * @param b  alternative expression evaluation or not
++     *
 +     * @param b alternative expression evaluation or not
       */
      public void setAlternativeExpression(boolean b) {
          WSBoolRecord record =
  
      /**
       * whether alternative formula entry is on
 -     * @param b  alternative formulas or not
++     *
 +     * @param b alternative formulas or not
       */
      public void setAlternativeFormula(boolean b) {
          WSBoolRecord record =
  
      /**
       * show automatic page breaks or not
 -     * @param b  whether to show auto page breaks
++     *
 +     * @param b whether to show auto page breaks
       */
      public void setAutobreaks(boolean b) {
          WSBoolRecord record =
  
      /**
       * set whether sheet is a dialog sheet or not
 -     * @param b  isDialog or not
++     *
 +     * @param b isDialog or not
       */
      public void setDialog(boolean b) {
          WSBoolRecord record =
  
      /**
       * fit to page option is on
 -     * @param b  fit or not
++     *
 +     * @param b fit or not
       */
      public void setFitToPage(boolean b) {
          WSBoolRecord record =
  
      /**
       * set if row summaries appear below detail in the outline
 -     * @param b  below or not
++     *
 +     * @param b below or not
       */
      public void setRowSumsBelow(boolean b) {
          WSBoolRecord record =
  
      /**
       * set if col summaries appear right of the detail in the outline
 -     * @param b  right or not
++     *
 +     * @param b right or not
       */
      public void setRowSumsRight(boolean b) {
          WSBoolRecord record =
  
      /**
       * whether alternate expression evaluation is on
++     *
       * @return alternative expression evaluation or not
       */
      public boolean getAlternateExpression() {
  
      /**
       * whether alternative formula entry is on
++     *
       * @return alternative formulas or not
       */
      public boolean getAlternateFormula() {
  
      /**
       * show automatic page breaks or not
++     *
       * @return whether to show auto page breaks
       */
      public boolean getAutobreaks() {
  
      /**
       * get whether sheet is a dialog sheet or not
++     *
       * @return isDialog or not
       */
      public boolean getDialog() {
       * <p>
       * In Excel 2003 this option can be changed in the Options dialog on the View tab.
       * </p>
++     *
       * @return whether all zero values on the worksheet are displayed
       */
 -    public boolean isDisplayZeros(){
 +    public boolean isDisplayZeros() {
          return _sheet.getWindowTwo().getDisplayZeros();
      }
  
       * <p>
       * In Excel 2003 this option can be set in the Options dialog on the View tab.
       * </p>
++     *
       * @param value whether to display or hide all zero values on the worksheet
       */
 -    public void setDisplayZeros(boolean value){
 +    public void setDisplayZeros(boolean value) {
          _sheet.getWindowTwo().setDisplayZeros(value);
      }
  
      /**
       * fit to page option is on
++     *
       * @return fit or not
       */
      public boolean getFitToPage() {
  
      /**
       * get if row summaries appear below detail in the outline
++     *
       * @return below or not
       */
      public boolean getRowSumsBelow() {
  
      /**
       * get if col summaries appear right of the detail in the outline
++     *
       * @return right or not
       */
      public boolean getRowSumsRight() {
  
      /**
       * Returns whether gridlines are printed.
++     *
       * @return Gridlines are printed
       */
      public boolean isPrintGridlines() {
  
      /**
       * Turns on or off the printing of gridlines.
++     *
       * @param newPrintGridlines boolean to turn on or off the printing of
--     * gridlines
++     *                          gridlines
       */
      public void setPrintGridlines(boolean newPrintGridlines) {
          getSheet().getPrintGridlines().setPrintGridlines(newPrintGridlines);
  
      /**
       * Gets the print setup object.
++     *
       * @return The user model for the print setup object.
       */
      public HSSFPrintSetup getPrintSetup() {
          return _patriarch;
      }
  
-         /**
-          * @deprecated (Sep 2008) use {@link #setColumnGroupCollapsed(int, boolean)}
-          */
 +    private HSSFPatriarch getPatriarch(boolean createIfMissing) {
 +        HSSFPatriarch patriarch = null;
 +        if (_patriarch != null) {
 +            return _patriarch;
 +        }
 +        DrawingManager2 dm = _book.findDrawingGroup();
 +        if (null == dm) {
 +            if (!createIfMissing) {
 +                return null;
 +            } else {
 +                _book.createDrawingGroup();
 +                dm = _book.getDrawingManager();
 +            }
 +        }
 +        EscherAggregate agg = (EscherAggregate) _sheet.findFirstRecordBySid(EscherAggregate.sid);
 +        if (null == agg) {
 +            int pos = _sheet.aggregateDrawingRecords(dm, false);
 +            if (-1 == pos) {
 +                if (createIfMissing) {
 +                    pos = _sheet.aggregateDrawingRecords(dm, true);
 +                    agg = (EscherAggregate) _sheet.getRecords().get(pos);
 +                    patriarch = new HSSFPatriarch(this, agg);
 +                    patriarch.afterCreate();
 +                    return patriarch;
 +                } else {
 +                    return null;
 +                }
 +            }
 +            agg = (EscherAggregate) _sheet.getRecords().get(pos);
 +        }
 +        return new HSSFPatriarch(this, agg);
 +    }
 +
+     /**
+      * @deprecated (Sep 2008) use {@link #setColumnGroupCollapsed(int, boolean)}
+      */
      public void setColumnGroupCollapsed(short columnNumber, boolean collapsed) {
          setColumnGroupCollapsed(columnNumber & 0xFFFF, collapsed);
      }
          return new HSSFAutoFilter(this);
      }
  
 -  @Override
 -  public CellRangeAddress getRepeatingRows() {
 -    return getRepeatingRowsOrColums(true);
 -  }
 -
 -
 -  @Override
 -  public CellRangeAddress getRepeatingColumns() {
 -    return getRepeatingRowsOrColums(false);
 -  }
 -
 -  
 -  @Override
 -  public void setRepeatingRows(CellRangeAddress rowRangeRef) {
 -    CellRangeAddress columnRangeRef = getRepeatingColumns();
 -    setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef);
 -  }
 -
 -  
 -  @Override
 -  public void setRepeatingColumns(CellRangeAddress columnRangeRef) {
 -    CellRangeAddress rowRangeRef = getRepeatingRows();
 -    setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef);
 -  }
 -
 -  
 -  private void setRepeatingRowsAndColumns(
 -      CellRangeAddress rowDef, CellRangeAddress colDef) {
 -    int sheetIndex = _workbook.getSheetIndex(this);
 -    int maxRowIndex = SpreadsheetVersion.EXCEL97.getLastRowIndex();
 -    int maxColIndex = SpreadsheetVersion.EXCEL97.getLastColumnIndex();
 -
 -    int col1 = -1; 
 -    int col2 =  -1;
 -    int row1 = -1; 
 -    int row2 =  -1;
 -    
 -    if (rowDef != null) {
 -      row1 = rowDef.getFirstRow();
 -      row2 = rowDef.getLastRow();
 -      if ((row1 == -1 && row2 != -1) || (row1 > row2)
 -           || (row1 < 0 || row1 > maxRowIndex) 
 -           || (row2 < 0 || row2 > maxRowIndex)) {
 -        throw new IllegalArgumentException("Invalid row range specification");
 -      }
 -    }
 -    if (colDef != null) {
 -      col1 = colDef.getFirstColumn();
 -      col2 = colDef.getLastColumn();
 -      if ((col1 == -1 && col2 != -1) || (col1 > col2)
 -          || (col1 < 0 || col1 > maxColIndex) 
 -          || (col2 < 0 || col2 > maxColIndex)) {
 -       throw new IllegalArgumentException("Invalid column range specification");
 -     }
 -    }
 -
 -    short externSheetIndex = 
 -      _workbook.getWorkbook().checkExternSheet(sheetIndex);
 -
 -    boolean setBoth = rowDef != null && colDef != null;
 -    boolean removeAll = rowDef == null && colDef == null;
 -
 -    HSSFName name = _workbook.getBuiltInName(
 -        NameRecord.BUILTIN_PRINT_TITLE, sheetIndex);
 -    if (removeAll) {
 -        if (name != null) {
 -          _workbook.removeName(name);
 +    protected HSSFComment findCellComment(int row, int column) {
 +        HSSFPatriarch patriarch = getDrawingPatriarch();
 +        if (null == patriarch) {
 +            patriarch = createDrawingPatriarch();
 +        }
 +        return lookForComment(patriarch, row, column);
 +    }
 +
 +    private HSSFComment lookForComment(HSSFShapeContainer container, int row, int column) {
 +        for (Object object : container.getChildren()) {
 +            HSSFShape shape = (HSSFShape) object;
 +            if (shape instanceof HSSFShapeGroup) {
 +                HSSFShape res = lookForComment((HSSFShapeContainer) shape, row, column);
 +                if (null != res) {
 +                    return (HSSFComment) res;
 +                }
 +                continue;
 +            }
 +            if (shape instanceof HSSFComment) {
 +                HSSFComment comment = (HSSFComment) shape;
 +                if (comment.getColumn() == column && comment.getRow() == row) {
 +                    return comment;
 +                }
 +            }
 +        }
 +        return null;
 +    }
++
++
++    public CellRangeAddress getRepeatingRows() {
++        return getRepeatingRowsOrColums(true);
++    }
++
++
++    public CellRangeAddress getRepeatingColumns() {
++        return getRepeatingRowsOrColums(false);
++    }
++
++
++    public void setRepeatingRows(CellRangeAddress rowRangeRef) {
++        CellRangeAddress columnRangeRef = getRepeatingColumns();
++        setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef);
++    }
++
++
++    public void setRepeatingColumns(CellRangeAddress columnRangeRef) {
++        CellRangeAddress rowRangeRef = getRepeatingRows();
++        setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef);
++    }
++
++
++    private void setRepeatingRowsAndColumns(
++            CellRangeAddress rowDef, CellRangeAddress colDef) {
++        int sheetIndex = _workbook.getSheetIndex(this);
++        int maxRowIndex = SpreadsheetVersion.EXCEL97.getLastRowIndex();
++        int maxColIndex = SpreadsheetVersion.EXCEL97.getLastColumnIndex();
++
++        int col1 = -1;
++        int col2 = -1;
++        int row1 = -1;
++        int row2 = -1;
++
++        if (rowDef != null) {
++            row1 = rowDef.getFirstRow();
++            row2 = rowDef.getLastRow();
++            if ((row1 == -1 && row2 != -1) || (row1 > row2)
++                    || (row1 < 0 || row1 > maxRowIndex)
++                    || (row2 < 0 || row2 > maxRowIndex)) {
++                throw new IllegalArgumentException("Invalid row range specification");
++            }
++        }
++        if (colDef != null) {
++            col1 = colDef.getFirstColumn();
++            col2 = colDef.getLastColumn();
++            if ((col1 == -1 && col2 != -1) || (col1 > col2)
++                    || (col1 < 0 || col1 > maxColIndex)
++                    || (col2 < 0 || col2 > maxColIndex)) {
++                throw new IllegalArgumentException("Invalid column range specification");
++            }
++        }
++
++        short externSheetIndex =
++                _workbook.getWorkbook().checkExternSheet(sheetIndex);
++
++        boolean setBoth = rowDef != null && colDef != null;
++        boolean removeAll = rowDef == null && colDef == null;
++
++        HSSFName name = _workbook.getBuiltInName(
++                NameRecord.BUILTIN_PRINT_TITLE, sheetIndex);
++        if (removeAll) {
++            if (name != null) {
++                _workbook.removeName(name);
++            }
++            return;
++        }
++        if (name == null) {
++            name = _workbook.createBuiltInName(
++                    NameRecord.BUILTIN_PRINT_TITLE, sheetIndex);
++        }
 -        return;
 -    }
 -    if (name == null) {
 -        name = _workbook.createBuiltInName(
 -            NameRecord.BUILTIN_PRINT_TITLE, sheetIndex);
 -    }
 -    
 -    List<Ptg> ptgList = new ArrayList<Ptg>();
 -    if (setBoth) {
 -      final int exprsSize = 2 * 11 + 1; // 2 * Area3DPtg.SIZE + UnionPtg.SIZE
 -      ptgList.add(new MemFuncPtg(exprsSize));
 -    }
 -    if (colDef != null) {
 -      Area3DPtg colArea = new Area3DPtg(0, maxRowIndex, col1, col2,
 -              false, false, false, false, externSheetIndex);
 -      ptgList.add(colArea);
 -    }
 -    if (rowDef != null) {
 -      Area3DPtg rowArea = new Area3DPtg(row1, row2, 0, maxColIndex,
 -              false, false, false, false, externSheetIndex);
 -      ptgList.add(rowArea);
 -    }
 -    if (setBoth) {
 -      ptgList.add(UnionPtg.instance);
 -    }
 -
 -    Ptg[] ptgs = new Ptg[ptgList.size()];
 -    ptgList.toArray(ptgs);
 -    name.setNameDefinition(ptgs);
 -
 -    HSSFPrintSetup printSetup = getPrintSetup();
 -    printSetup.setValidSettings(false);
 -    setActive(true);
 -  }
 -
 -  
 -  private CellRangeAddress getRepeatingRowsOrColums(boolean rows) {
 -    NameRecord rec = getBuiltinNameRecord(NameRecord.BUILTIN_PRINT_TITLE);
 -    if (rec == null) {
 -      return null;
 -    }
 -    
 -    Ptg[] nameDefinition = rec.getNameDefinition();
 -    if (nameDefinition == null) {
 -      return null;
 -    }
 -    
 -    int maxRowIndex = SpreadsheetVersion.EXCEL97.getLastRowIndex();
 -    int maxColIndex = SpreadsheetVersion.EXCEL97.getLastColumnIndex();
 -    
 -    for (Ptg ptg :nameDefinition) {
 -      
 -      if (ptg instanceof Area3DPtg) {
 -        Area3DPtg areaPtg = (Area3DPtg) ptg;
 -        
 -        if (areaPtg.getFirstColumn() == 0 
 -            && areaPtg.getLastColumn() == maxColIndex) {
 -          if (rows) {
 -            CellRangeAddress rowRange = new CellRangeAddress(
 -                areaPtg.getFirstRow(), areaPtg.getLastRow(), -1, -1);
 -            return rowRange;
 -          }
 -        } else if (areaPtg.getFirstRow() == 0 
 -            && areaPtg.getLastRow() == maxRowIndex) {
 -          if (!rows) {
 -            CellRangeAddress columnRange = new CellRangeAddress(-1, -1, 
 -                areaPtg.getFirstColumn(), areaPtg.getLastColumn());
 -            return columnRange;
 -          }
++        List<Ptg> ptgList = new ArrayList<Ptg>();
++        if (setBoth) {
++            final int exprsSize = 2 * 11 + 1; // 2 * Area3DPtg.SIZE + UnionPtg.SIZE
++            ptgList.add(new MemFuncPtg(exprsSize));
+         }
 -        
 -      }
 -      
++        if (colDef != null) {
++            Area3DPtg colArea = new Area3DPtg(0, maxRowIndex, col1, col2,
++                    false, false, false, false, externSheetIndex);
++            ptgList.add(colArea);
+         }
 -    
 -    return null;
 -  }
++        if (rowDef != null) {
++            Area3DPtg rowArea = new Area3DPtg(row1, row2, 0, maxColIndex,
++                    false, false, false, false, externSheetIndex);
++            ptgList.add(rowArea);
++        }
++        if (setBoth) {
++            ptgList.add(UnionPtg.instance);
++        }
++
++        Ptg[] ptgs = new Ptg[ptgList.size()];
++        ptgList.toArray(ptgs);
++        name.setNameDefinition(ptgs);
++
++        HSSFPrintSetup printSetup = getPrintSetup();
++        printSetup.setValidSettings(false);
++        setActive(true);
+     }
 -  private NameRecord getBuiltinNameRecord(byte builtinCode) {
 -    int sheetIndex = _workbook.getSheetIndex(this);
 -    int recIndex = 
 -      _workbook.findExistingBuiltinNameRecordIdx(sheetIndex, builtinCode);
 -    if (recIndex == -1) {
 -      return null;
 -    return _workbook.getNameRecord(recIndex);
 -  }
++    private CellRangeAddress getRepeatingRowsOrColums(boolean rows) {
++        NameRecord rec = getBuiltinNameRecord(NameRecord.BUILTIN_PRINT_TITLE);
++        if (rec == null) {
++            return null;
++        }
++
++        Ptg[] nameDefinition = rec.getNameDefinition();
++        if (nameDefinition == null) {
++            return null;
++        }
++
++        int maxRowIndex = SpreadsheetVersion.EXCEL97.getLastRowIndex();
++        int maxColIndex = SpreadsheetVersion.EXCEL97.getLastColumnIndex();
++
++        for (Ptg ptg : nameDefinition) {
++
++            if (ptg instanceof Area3DPtg) {
++                Area3DPtg areaPtg = (Area3DPtg) ptg;
++
++                if (areaPtg.getFirstColumn() == 0
++                        && areaPtg.getLastColumn() == maxColIndex) {
++                    if (rows) {
++                        CellRangeAddress rowRange = new CellRangeAddress(
++                                areaPtg.getFirstRow(), areaPtg.getLastRow(), -1, -1);
++                        return rowRange;
++                    }
++                } else if (areaPtg.getFirstRow() == 0
++                        && areaPtg.getLastRow() == maxRowIndex) {
++                    if (!rows) {
++                        CellRangeAddress columnRange = new CellRangeAddress(-1, -1,
++                                areaPtg.getFirstColumn(), areaPtg.getLastColumn());
++                        return columnRange;
++                    }
++                }
++
++            }
++
++        }
++
++        return null;
+     }
 -  
++
++    private NameRecord getBuiltinNameRecord(byte builtinCode) {
++        int sheetIndex = _workbook.getSheetIndex(this);
++        int recIndex =
++                _workbook.findExistingBuiltinNameRecordIdx(sheetIndex, builtinCode);
++        if (recIndex == -1) {
++            return null;
++        }
++        return _workbook.getNameRecord(recIndex);
++    }
++
++
  }
index afe8612002db59e0b35c11d217048f6918a1b2da,84589a6fdcad1f8a7e1c576ebed8898c58a82e66..77ae26f76ab0e694f1192ef1458ba44f02d3ae32
@@@ -1263,7 -1276,31 +1276,27 @@@ public class SXSSFSheet implements Shee
      public SheetConditionalFormatting getSheetConditionalFormatting(){
          return _sh.getSheetConditionalFormatting();
      }
+     
+     
 -    @Override
+     public CellRangeAddress getRepeatingRows() {
+       return _sh.getRepeatingRows();
+     }
+     
+     
 -    @Override
+     public CellRangeAddress getRepeatingColumns() {
+       return _sh.getRepeatingColumns();
+     }
+     
 -    @Override
+     public void setRepeatingRows(CellRangeAddress rowRangeRef) {
+       _sh.setRepeatingRows(rowRangeRef);
+     }
+     
 -    @Override
+     public void setRepeatingColumns(CellRangeAddress columnRangeRef) {
+       _sh.setRepeatingColumns(columnRangeRef);
+     }
+     
+     
+     
  //end of interface implementation
      /**
       * Specifies how many rows can be accessed at most via getRow().
index fbed5b06ddfba3beb167a3e62be1760c16cb0989,a69bf09f439fecd4f6f2e80ef070f6c377ced1f1..ccf2419873a4d9bc93812e2b566eb6002af06c75
@@@ -3185,4 -3186,166 +3186,162 @@@ public class XSSFSheet extends POIXMLDo
          color.setIndexed(colorIndex);
          pr.setTabColor(color);
      }
 -    @Override
+     
+     
 -    @Override
+     public CellRangeAddress getRepeatingRows() {
+       return getRepeatingRowsOrColums(true);
+     }
 -    @Override
+     public CellRangeAddress getRepeatingColumns() {
+       return getRepeatingRowsOrColums(false);
+     }
 -    @Override
+     public void setRepeatingRows(CellRangeAddress rowRangeRef) {
+       CellRangeAddress columnRangeRef = getRepeatingColumns();
+       setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef);
+     }
+     
+     public void setRepeatingColumns(CellRangeAddress columnRangeRef) {
+       CellRangeAddress rowRangeRef = getRepeatingRows();
+       setRepeatingRowsAndColumns(rowRangeRef, columnRangeRef);
+     }
+     
+     private void setRepeatingRowsAndColumns(
+         CellRangeAddress rowDef, CellRangeAddress colDef) {
+       int col1 = -1; 
+       int col2 =  -1;
+       int row1 = -1; 
+       int row2 =  -1;
+       
+       if (rowDef != null) {
+         row1 = rowDef.getFirstRow();
+         row2 = rowDef.getLastRow();
+         if ((row1 == -1 && row2 != -1) 
+             || row1 < -1 || row2 < -1 || row1 > row2) {
+           throw new IllegalArgumentException("Invalid row range specification");
+         }
+       }
+       if (colDef != null) {
+         col1 = colDef.getFirstColumn();
+         col2 = colDef.getLastColumn();
+         if ((col1 == -1 && col2 != -1) 
+             || col1 < -1 || col2 < -1 || col1 > col2) {
+           throw new IllegalArgumentException(
+               "Invalid column range specification");
+         }
+       }
+       
+       int sheetIndex = getWorkbook().getSheetIndex(this);
+       boolean removeAll = rowDef == null && colDef == null;
+       XSSFName name = getWorkbook().getBuiltInName(
+           XSSFName.BUILTIN_PRINT_TITLE, sheetIndex);
+       if (removeAll) {
+           if (name != null) {
+             getWorkbook().removeName(name);
+           }
+           return;
+       }
+       if (name == null) {
+           name = getWorkbook().createBuiltInName(
+               XSSFName.BUILTIN_PRINT_TITLE, sheetIndex);
+       }
+       String reference = getReferenceBuiltInRecord(
+           name.getSheetName(), col1, col2, row1, row2);
+       name.setRefersToFormula(reference);
+       // If the print setup isn't currently defined, then add it
+       //  in but without printer defaults
+       // If it's already there, leave it as-is!
+       if (worksheet.isSetPageSetup() && worksheet.isSetPageMargins()) {
+          // Everything we need is already there
+       } else {
+         // Have initial ones put in place
+         getPrintSetup().setValidSettings(false);
+       }
+     }
+     private static String getReferenceBuiltInRecord(
+         String sheetName, int startC, int endC, int startR, int endR) {
+         // Excel example for built-in title: 
+         //   'second sheet'!$E:$F,'second sheet'!$2:$3
+       
+         CellReference colRef = 
+           new CellReference(sheetName, 0, startC, true, true);
+         CellReference colRef2 = 
+           new CellReference(sheetName, 0, endC, true, true);
+         CellReference rowRef = 
+           new CellReference(sheetName, startR, 0, true, true);
+         CellReference rowRef2 = 
+           new CellReference(sheetName, endR, 0, true, true);
+         String escapedName = SheetNameFormatter.format(sheetName);
+         String c = "";
+         String r = "";
+         if(startC == -1 && endC == -1) {
+         } else {
+           c = escapedName + "!$" + colRef.getCellRefParts()[2] 
+               + ":$" + colRef2.getCellRefParts()[2];
+         }
+         if (startR == -1 && endR == -1) {
+           
+         } else if (!rowRef.getCellRefParts()[1].equals("0") 
+             && !rowRef2.getCellRefParts()[1].equals("0")) {
+            r = escapedName + "!$" + rowRef.getCellRefParts()[1] 
+                  + ":$" + rowRef2.getCellRefParts()[1];
+         }
+         StringBuffer rng = new StringBuffer();
+         rng.append(c);
+         if(rng.length() > 0 && r.length() > 0) {
+           rng.append(',');
+         }
+         rng.append(r);
+         return rng.toString();
+     }
+     private CellRangeAddress getRepeatingRowsOrColums(boolean rows) {
+       int sheetIndex = getWorkbook().getSheetIndex(this);
+       XSSFName name = getWorkbook().getBuiltInName(
+           XSSFName.BUILTIN_PRINT_TITLE, sheetIndex);
+       if (name == null ) {
+         return null;
+       }
+       String refStr = name.getRefersToFormula();
+       if (refStr == null) {
+         return null;
+       }
+       String[] parts = refStr.split(",");
+       int maxRowIndex = SpreadsheetVersion.EXCEL2007.getLastRowIndex();
+       int maxColIndex = SpreadsheetVersion.EXCEL2007.getLastColumnIndex();
+       for (String part : parts) {
+         CellRangeAddress range = CellRangeAddress.valueOf(part);
+         if ((range.getFirstColumn() == 0 
+             && range.getLastColumn() == maxColIndex)
+             || (range.getFirstColumn() == -1 
+                 && range.getLastColumn() == -1)) {
+           if (rows) {
+             return range;
+           }
+         } else if (range.getFirstRow() == 0 
+             && range.getLastRow() == maxRowIndex
+             || (range.getFirstRow() == -1 
+                 && range.getLastRow() == -1)) {
+           if (!rows) {
+             return range;
+           }
+         }
+       }
+       return null;
+     }
  }