]> source.dussan.org Git - poi.git/commitdiff
Clean-up of generics in XSSFRelation
authorJosh Micich <josh@apache.org>
Mon, 29 Sep 2008 05:40:48 +0000 (05:40 +0000)
committerJosh Micich <josh@apache.org>
Mon, 29 Sep 2008 05:40:48 +0000 (05:40 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@699990 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRelation.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java

index 2a1ca52ad33aa941d90961596eda31d87821945b..71f3f8ce0dda7139637198c28361236be376b21e 100644 (file)
@@ -1,19 +1,43 @@
-/**
- * 
- */
+/* ====================================================================
+   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.xssf.usermodel;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 
 import org.apache.poi.POIXMLDocument;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
-import org.apache.poi.xssf.model.*;
+import org.apache.poi.xssf.model.BinaryPart;
+import org.apache.poi.xssf.model.CommentsTable;
+import org.apache.poi.xssf.model.Control;
+import org.apache.poi.xssf.model.Drawing;
+import org.apache.poi.xssf.model.SharedStringsTable;
+import org.apache.poi.xssf.model.StylesTable;
+import org.apache.poi.xssf.model.ThemeTable;
+import org.apache.poi.xssf.model.XSSFChildContainingModel;
+import org.apache.poi.xssf.model.XSSFModel;
+import org.apache.poi.xssf.model.XSSFWritableModel;
 import org.openxml4j.exceptions.InvalidFormatException;
 import org.openxml4j.opc.PackagePart;
 import org.openxml4j.opc.PackagePartName;
@@ -22,7 +46,11 @@ import org.openxml4j.opc.PackageRelationshipCollection;
 import org.openxml4j.opc.PackagingURIHelper;
 import org.openxml4j.opc.TargetMode;
 
-public class XSSFRelation {
+/**
+ * 
+ */
+public final class XSSFRelation<W extends XSSFModel> {
+
        public static final XSSFRelation WORKBOOK = new XSSFRelation(
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
                        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/workbook",
@@ -41,13 +69,13 @@ public class XSSFRelation {
                        "/xl/worksheets/sheet#.xml",
                        null
        );
-       public static final XSSFRelation SHARED_STRINGS = new XSSFRelation(
+       public static final XSSFRelation<SharedStringsTable> SHARED_STRINGS = create(
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
                        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
                        "/xl/sharedStrings.xml",
                        SharedStringsTable.class
        );
-       public static final XSSFRelation STYLES = new XSSFRelation(
+       public static final XSSFRelation<StylesTable> STYLES = create(
                    "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
                    "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
                    "/xl/styles.xml",
@@ -59,7 +87,7 @@ public class XSSFRelation {
                        "/xl/drawings/drawing#.xml",
                        null
        );
-       public static final XSSFRelation VML_DRAWINGS = new XSSFRelation(
+       public static final XSSFRelation<Drawing> VML_DRAWINGS = create(
                        "application/vnd.openxmlformats-officedocument.vmlDrawing",
                        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
                        "/xl/drawings/vmlDrawing#.vml",
@@ -71,7 +99,7 @@ public class XSSFRelation {
                "/xl/media/image#.emf",
                null
     );
-       public static final XSSFRelation SHEET_COMMENTS = new XSSFRelation(
+       public static final XSSFRelation<CommentsTable> SHEET_COMMENTS = create(
                    "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
                    "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
                    "/xl/comments#.xml",
@@ -83,38 +111,38 @@ public class XSSFRelation {
                    null,
                    null
        );
-       public static final XSSFRelation OLEEMBEDDINGS = new XSSFRelation(
+       public static final XSSFRelation<BinaryPart> OLEEMBEDDINGS = create(
                null,
                POIXMLDocument.OLE_OBJECT_REL_TYPE,
                null,
                BinaryPart.class
        );
-       public static final XSSFRelation PACKEMBEDDINGS = new XSSFRelation(
+       public static final XSSFRelation<BinaryPart> PACKEMBEDDINGS = create(
             null,
             POIXMLDocument.PACK_OBJECT_REL_TYPE,
             null,
             BinaryPart.class
     );
 
-       public static final XSSFRelation VBA_MACROS = new XSSFRelation(
+       public static final XSSFRelation<BinaryPart> VBA_MACROS = create(
             "application/vnd.ms-office.vbaProject",
             "http://schemas.microsoft.com/office/2006/relationships/vbaProject",
             "/xl/vbaProject.bin",
                BinaryPart.class
     );
-       public static final XSSFRelation ACTIVEX_CONTROLS = new XSSFRelation(
+       public static final XSSFRelation<Control> ACTIVEX_CONTROLS = create(
                        "application/vnd.ms-office.activeX+xml",
                        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/control",
                        "/xl/activeX/activeX#.xml",
                        Control.class
        );
-       public static final XSSFRelation ACTIVEX_BINS = new XSSFRelation(
+       public static final XSSFRelation<BinaryPart> ACTIVEX_BINS = create(
                        "application/vnd.ms-office.activeX",
                        "http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary",
                        "/xl/activeX/activeX#.bin",
                BinaryPart.class
        );
-    public static final XSSFRelation THEME = new XSSFRelation(
+    public static final XSSFRelation<ThemeTable> THEME = create(
             "application/vnd.openxmlformats-officedocument.theme+xml",
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
             "/xl/theme/theme#.xml",
@@ -124,40 +152,61 @@ public class XSSFRelation {
        
     private static POILogger log = POILogFactory.getLogger(XSSFRelation.class);
     
+    private static <R extends XSSFModel> XSSFRelation<R> create(String type, String rel, String defaultName, Class<R> cls) {
+       return new XSSFRelation<R>(type, rel, defaultName, cls);
+    }
    
-       private String TYPE;
-       private String REL;
-       private String DEFAULT_NAME;
-       private Class<? extends XSSFModel> CLASS;
+       private String _type;
+       private String _relation;
+       private String _defaultName;
+       private Constructor<W> _constructor;
+       private final boolean _constructorTakesTwoArgs;
        
-       protected XSSFRelation(String TYPE, String REL, String DEFAULT_NAME, Class<? extends XSSFModel> CLASS) {
-               this.TYPE = TYPE;
-               this.REL = REL;
-               this.DEFAULT_NAME = DEFAULT_NAME;
-               this.CLASS = CLASS;
+       private XSSFRelation(String type, String rel, String defaultName, Class<W> cls) {
+               _type = type;
+               _relation = rel;
+               _defaultName = defaultName;
+               if (cls == null) {
+                       _constructor = null;
+                       _constructorTakesTwoArgs = false;
+               } else {
+                       Constructor<W> c;
+                       boolean twoArg;
+                       
+                       // Find the right constructor 
+                       try {
+                               c = cls.getConstructor(InputStream.class, String.class);
+                               twoArg = true;
+                       } catch(NoSuchMethodException e) {
+                               try {
+                                       c = cls.getConstructor(InputStream.class);
+                                       twoArg = false;
+                               } catch(NoSuchMethodException e2) {
+                                       throw new RuntimeException(e2);
+                               }
+                       }
+                       _constructor = c;
+                       _constructorTakesTwoArgs = twoArg;
+               }
        }
-       public String getContentType() { return TYPE; }
-       public String getRelation() { return REL; }
-       public String getDefaultFileName() { return DEFAULT_NAME; }
+       public String getContentType() { return _type; }
+       public String getRelation() { return _relation; }
+       public String getDefaultFileName() { return _defaultName; }
        
        /**
         * Does one of these exist for the given core
         *  package part?
         */
-       public boolean exists(PackagePart corePart) throws IOException, InvalidFormatException {
+       public boolean exists(PackagePart corePart) throws InvalidFormatException {
                if(corePart == null) {
                        // new file, can't exist
                        return false;
                }
                
         PackageRelationshipCollection prc =
-               corePart.getRelationshipsByType(REL);
+               corePart.getRelationshipsByType(_relation);
         Iterator<PackageRelationship> it = prc.iterator();
-        if(it.hasNext()) {
-               return true;
-        } else {
-               return false;
-        }
+        return it.hasNext();
        }
        
        /**
@@ -165,11 +214,11 @@ public class XSSFRelation {
         *  eg /xl/comments4.xml
         */
        public String getFileName(int index) {
-               if(DEFAULT_NAME.indexOf("#") == -1) {
+               if(_defaultName.indexOf("#") == -1) {
                        // Generic filename in all cases
                        return getDefaultFileName();
                }
-               return DEFAULT_NAME.replace("#", Integer.toString(index));
+               return _defaultName.replace("#", Integer.toString(index));
        }
 
        /**
@@ -179,7 +228,7 @@ public class XSSFRelation {
         */
        public InputStream getContents(PackagePart corePart) throws IOException, InvalidFormatException {
         PackageRelationshipCollection prc =
-               corePart.getRelationshipsByType(REL);
+               corePart.getRelationshipsByType(_relation);
         Iterator<PackageRelationship> it = prc.iterator();
         if(it.hasNext()) {
             PackageRelationship rel = it.next();
@@ -187,7 +236,7 @@ public class XSSFRelation {
             PackagePart part = corePart.getPackage().getPart(relName);
             return part.getInputStream();
         } else {
-               log.log(POILogger.WARN, "No part " + DEFAULT_NAME + " found");
+               log.log(POILogger.WARN, "No part " + _defaultName + " found");
                return null;
         }
        }
@@ -196,9 +245,9 @@ public class XSSFRelation {
         * Loads all the XSSFModels of this type which are
         *  defined as relationships of the given parent part
         */
-       public ArrayList<? extends XSSFModel> loadAll(PackagePart parentPart) throws Exception {
-               ArrayList<XSSFModel> found = new ArrayList<XSSFModel>();
-               for(PackageRelationship rel : parentPart.getRelationshipsByType(REL)) {
+       public List<W> loadAll(PackagePart parentPart) throws Exception {
+               List<W> found = new ArrayList<W>();
+               for(PackageRelationship rel : parentPart.getRelationshipsByType(_relation)) {
                        PackagePart part = XSSFWorkbook.getTargetPart(parentPart.getPackage(), rel);
                        found.add(create(part, rel));
                }
@@ -210,9 +259,9 @@ public class XSSFRelation {
         *  relationship from the specified core (parent) 
         *  package part.
         */
-       public XSSFModel load(PackagePart corePart) throws Exception {
+       public W load(PackagePart corePart) throws Exception {
         PackageRelationshipCollection prc =
-               corePart.getRelationshipsByType(REL);
+               corePart.getRelationshipsByType(_relation);
         Iterator<PackageRelationship> it = prc.iterator();
         if(it.hasNext()) {
             PackageRelationship rel = it.next();
@@ -220,7 +269,7 @@ public class XSSFRelation {
             PackagePart part = corePart.getPackage().getPart(relName);
             return create(part, rel);
         } else {
-               log.log(POILogger.WARN, "No part " + DEFAULT_NAME + " found");
+               log.log(POILogger.WARN, "No part " + _defaultName + " found");
                return null;
         }
        }
@@ -228,48 +277,61 @@ public class XSSFRelation {
        /**
         * Does the actual Model creation
         */
-       private XSSFModel create(PackagePart thisPart, PackageRelationship rel) throws Exception {
-               XSSFModel model = null;
-               
-               Constructor<? extends XSSFModel> c;
-               boolean withString = false;
+       private W create(PackagePart thisPart, PackageRelationship rel) 
+                       throws IOException, InvalidFormatException {
                
-               // Find the right constructor 
-               try {
-                       c = CLASS.getConstructor(InputStream.class, String.class);
-                       withString = true;
-               } catch(NoSuchMethodException e) {
-                       c = CLASS.getConstructor(InputStream.class);
+               if (_constructor == null) {
+                       throw new IllegalStateException("Model class not set");
                }
-               
                // Instantiate, if we can
                InputStream inp = thisPart.getInputStream();
-               if(inp != null) {
-            try {
-               if(withString) {
-                       model = c.newInstance(inp, rel.getId());
-               } else {
-                       model = c.newInstance(inp);
-               }
-            } finally {
-               inp.close();
-            }
-            
-                       // Do children, if required
-                       if(model instanceof XSSFChildContainingModel) {
-                               XSSFChildContainingModel ccm = 
-                                       (XSSFChildContainingModel)model;
-                               for(String relType : ccm.getChildrenRelationshipTypes()) {
-                                       for(PackageRelationship cRel : thisPart.getRelationshipsByType(relType)) {
-                                               PackagePart childPart = XSSFWorkbook.getTargetPart(thisPart.getPackage(), cRel);
-                                               ccm.generateChild(childPart, cRel.getId());
-                                       }
+               if (inp == null) {
+                       return null; // TODO - is this valid?
+               }
+               Object[] args;
+               if (_constructorTakesTwoArgs) {
+                       args = new Object[] { inp, rel.getId(), };
+               } else {
+                       args = new Object[] { inp, };
+               }
+               W result;
+        try {
+               try {
+                               result = _constructor.newInstance(args);
+                       } catch (IllegalArgumentException e) {
+                               throw new RuntimeException(e);
+                       } catch (InstantiationException e) {
+                               throw new RuntimeException(e);
+                       } catch (IllegalAccessException e) {
+                               throw new RuntimeException(e);
+                       } catch (InvocationTargetException e) {
+                               Throwable t = e.getTargetException();
+                               if (t instanceof IOException) {
+                                       throw (IOException)t;
+                               }
+                               if (t instanceof RuntimeException) {
+                                       throw (RuntimeException)t;
                                }
+                               throw new RuntimeException(t);
                        }
+        } finally {
+               inp.close();
         }
+        
+               // Do children, if required
+               if(result instanceof XSSFChildContainingModel) {
+                       XSSFChildContainingModel ccm = 
+                               (XSSFChildContainingModel)result;
+                       for(String relType : ccm.getChildrenRelationshipTypes()) {
+                               for(PackageRelationship cRel : thisPart.getRelationshipsByType(relType)) {
+                                       PackagePart childPart = XSSFWorkbook.getTargetPart(thisPart.getPackage(), cRel);
+                                       ccm.generateChild(childPart, cRel.getId());
+                               }
+                       }
+               }
+               
                
-               
-        return model;
+        return result;
        }
        
        /**
@@ -277,7 +339,7 @@ public class XSSFRelation {
         * @return The internal reference ID it was saved at, normally then used as an r:id
         */
        protected String save(XSSFWritableModel model, PackagePart corePart) throws IOException {
-               return save(model, corePart, DEFAULT_NAME);
+               return save(model, corePart, _defaultName);
        }
        /**
         * Save, with the name generated by the given index
@@ -298,8 +360,8 @@ public class XSSFRelation {
                throw new IllegalStateException("Can't create part with name " + name + " for " + model, e);
         }
         PackageRelationship rel =
-               corePart.addRelationship(ppName, TargetMode.INTERNAL, REL);
-        PackagePart part = corePart.getPackage().createPart(ppName, TYPE);
+               corePart.addRelationship(ppName, TargetMode.INTERNAL, _relation);
+        PackagePart part = corePart.getPackage().createPart(ppName, _type);
         
         OutputStream out = part.getOutputStream();
         model.writeTo(out);
index 257e83c958878fd2d5b3e25311687b1202c748d9..dbf6a45de7124ab73fd2bb1cbe58c779114cf3a3 100644 (file)
@@ -19,15 +19,17 @@ package org.apache.poi.xssf.usermodel;
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
 
 import org.apache.poi.hssf.util.PaneInformation;
 import org.apache.poi.ss.usermodel.CellStyle;
-import org.apache.poi.ss.usermodel.Comment;
 import org.apache.poi.ss.usermodel.CommentsSource;
 import org.apache.poi.ss.usermodel.Footer;
 import org.apache.poi.ss.usermodel.Header;
-import org.apache.poi.ss.usermodel.Hyperlink;
 import org.apache.poi.ss.usermodel.Patriarch;
 import org.apache.poi.ss.usermodel.PrintSetup;
 import org.apache.poi.ss.usermodel.Row;
@@ -43,12 +45,9 @@ import org.apache.xmlbeans.XmlOptions;
 import org.openxml4j.opc.PackagePart;
 import org.openxml4j.opc.PackageRelationship;
 import org.openxml4j.opc.PackageRelationshipCollection;
-import org.openxmlformats.schemas.drawingml.x2006.chart.CTBoolean;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTControls;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCustomProperties;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDialogsheet;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
@@ -58,23 +57,18 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOutlinePr;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetUpPr;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetup;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPane;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRecord;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
-import org.openxmlformats.schemas.spreadsheetml.x2006.main.STSheetState;
 
 
 /**
@@ -87,364 +81,364 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.STSheetState;
  * </p>
  */
 public class XSSFSheet implements Sheet {
-    protected CTSheet sheet;
-    protected CTWorksheet worksheet;
-    protected CTDialogsheet dialogsheet;
-    protected List<Row> rows;
-    protected List<XSSFHyperlink> hyperlinks;
-    protected ColumnHelper columnHelper;
-    protected XSSFWorkbook workbook;
-    protected CommentsSource sheetComments;
-    protected CTMergeCells ctMergeCells;
-    
-
-    protected ArrayList<Drawing> drawings;
-    protected ArrayList<Control> controls;
-
-
-    public static final short LeftMargin = 0;
-    public static final short RightMargin = 1;
-    public static final short TopMargin = 2;
-    public static final short BottomMargin = 3;
-    public static final short HeaderMargin = 4;
-    public static final short FooterMargin = 5;
-
-       public XSSFSheet(CTSheet sheet, CTWorksheet worksheet, XSSFWorkbook workbook, CommentsSource sheetComments, ArrayList<Drawing> drawings, ArrayList<Control> controls) {
+       protected CTSheet sheet;
+       protected CTWorksheet worksheet;
+       protected CTDialogsheet dialogsheet;
+       protected List<Row> rows;
+       protected List<XSSFHyperlink> hyperlinks;
+       protected ColumnHelper columnHelper;
+       protected XSSFWorkbook workbook;
+       protected CommentsSource sheetComments;
+       protected CTMergeCells ctMergeCells;
+
+
+       protected List<Drawing> drawings;
+       protected List<Control> controls;
+
+
+       public static final short LeftMargin = 0;
+       public static final short RightMargin = 1;
+       public static final short TopMargin = 2;
+       public static final short BottomMargin = 3;
+       public static final short HeaderMargin = 4;
+       public static final short FooterMargin = 5;
+
+       public XSSFSheet(CTSheet sheet, CTWorksheet worksheet, XSSFWorkbook workbook, CommentsSource sheetComments, List<Drawing> drawings, List<Control> controls) {
                this(sheet, worksheet, workbook, sheetComments);
                this.drawings = drawings;
                this.controls = controls;
        }
-       
-       public ArrayList<Drawing> getDrawings()
+
+       public List<Drawing> getDrawings()
        {
                return drawings;
        }
-       
-       public ArrayList<Control> getControls()
+
+       public List<Control> getControls()
        {
                return controls;
        }
-       
+
        public XSSFSheet(CTSheet sheet, CTWorksheet worksheet, XSSFWorkbook workbook, CommentsSource sheetComments) {
                this(sheet, worksheet, workbook);
                this.sheetComments = sheetComments;
        }
 
        public XSSFSheet(CTSheet sheet, CTWorksheet worksheet, XSSFWorkbook workbook) {
-        this.workbook = workbook;
-        this.sheet = sheet;
-        this.worksheet = worksheet;
-
-        if (this.worksheet.getSheetData() == null) {
-               this.worksheet.addNewSheetData();
-        }
-
-        initRows(this.worksheet);
-        initColumns(this.worksheet);
-
-       hyperlinks = new ArrayList<XSSFHyperlink>();
-       }
-
-    protected XSSFSheet(XSSFWorkbook workbook) {
-        this.workbook = workbook;
-
-        hyperlinks = new ArrayList<XSSFHyperlink>();
-    }
-
-    /**
-     * Returns the parent XSSFWorkbook
-     *
-     * @return the parent XSSFWorkbook
-     */
-    public XSSFWorkbook getWorkbook() {
-        return this.workbook;
-    }
-
-    /**
-     * Create a new CTWorksheet instance and setup default values
-     *
-     * @return a new instance
-     */
-    protected static CTWorksheet newInstance(){
-        CTWorksheet worksheet = CTWorksheet.Factory.newInstance();
-        CTSheetFormatPr ctFormat = worksheet.addNewSheetFormatPr();
-        ctFormat.setDefaultRowHeight(15.0);
-
-        CTSheetView ctView = worksheet.addNewSheetViews().addNewSheetView();
-        ctView.setTabSelected(true);
-        ctView.setWorkbookViewId(0);
-
-        worksheet.addNewDimension().setRef("A1");
-
-        worksheet.addNewSheetData();
-
-        CTPageMargins ctMargins = worksheet.addNewPageMargins();
-        ctMargins.setBottom(0.75);
-        ctMargins.setFooter(0.3);
-        ctMargins.setHeader(0.3);
-        ctMargins.setLeft(0.7);
-        ctMargins.setRight(0.7);
-        ctMargins.setTop(0.75);
-
-        return worksheet;
-    }
-
-    /**
-     * Tweaks the CTWorksheet to fit with what Excel
-     *  will accept without a massive huff, and write into
-     *  the OutputStream supplied.
-     */
-    protected void save(PackagePart sheetPart, XmlOptions xmlOptions) throws IOException {
-       // Excel objects to <cols/>
-       if(worksheet.getColsArray().length == 1) {
-               CTCols col = worksheet.getColsArray(0);
-               if(col.getColArray().length == 0) {
-                       worksheet.setColsArray(null);
-               }
-       }
-       
-       // Now re-generate our CTHyperlinks, if needed
-       if(hyperlinks.size() > 0) {
-               if(worksheet.getHyperlinks() == null) {
-                       worksheet.addNewHyperlinks();
-               }
-               CTHyperlink[] ctHls = new CTHyperlink[hyperlinks.size()];
-               for(int i=0; i<ctHls.length; i++) {
-                   // If our sheet has hyperlinks, have them add
-                   //  any relationships that they might need
-                       XSSFHyperlink hyperlink = hyperlinks.get(i);
-                       hyperlink.generateRelationIfNeeded(sheetPart);
-                       // Now grab their underling object
-                       ctHls[i] = hyperlink.getCTHyperlink();
-               }
-               worksheet.getHyperlinks().setHyperlinkArray(ctHls);
-       }
-
-       // Save
-       OutputStream out = sheetPart.getOutputStream();
-        worksheet.save(out, xmlOptions);
-        out.close();
-    }
-
-    /**
-     * Provide access to the underlying XML bean
-     *
-     * @return the underlying CTWorksheet bean
-     */
-    public CTWorksheet getWorksheet() {
-        return this.worksheet;
-    }
-    
-    public ColumnHelper getColumnHelper() {
-       return columnHelper;
-    }
-
-    protected void initRows(CTWorksheet worksheet) {
-        this.rows = new LinkedList<Row>();
-        for (CTRow row : worksheet.getSheetData().getRowArray()) {
-            this.rows.add(new XSSFRow(row, this));
-        }
-    }
-
-    protected void initColumns(CTWorksheet worksheet) {
-        columnHelper = new ColumnHelper(worksheet);
-    }
-    
-    protected void initHyperlinks(PackageRelationshipCollection hyperRels) {
-       if(worksheet.getHyperlinks() == null) return;
-       
-       // Turn each one into a XSSFHyperlink
-       for(CTHyperlink hyperlink : worksheet.getHyperlinks().getHyperlinkArray()) {
-               PackageRelationship hyperRel = null;
-               if(hyperlink.getId() != null) {
-                       hyperRel = hyperRels.getRelationshipByID(hyperlink.getId());
-               }
-               
-               hyperlinks.add(
-                               new XSSFHyperlink(hyperlink, hyperRel)
-               );
-       }
-    }
-    
-    protected CTSheet getSheet() {
-        return this.sheet;
-    }
-    public int addMergedRegion(CellRangeAddress cra) {
-       Region r = new Region(cra.getFirstRow(), (short)cra.getFirstColumn(),
-                       cra.getLastRow(), (short)cra.getLastColumn());
-       return addMergedRegion(r);
-    }
-    
-    
-    public int addMergedRegion(Region region) {
-       addNewMergeCell(region);
-       return ctMergeCells.sizeOfMergeCellArray();
-    }
-
-    /**
-     * Adjusts the column width to fit the contents.
-     *
-     * This process can be relatively slow on large sheets, so this should
-     *  normally only be called once per column, at the end of your
-     *  processing.
-     *
-     * @param column the column index
-     */
+               this.workbook = workbook;
+               this.sheet = sheet;
+               this.worksheet = worksheet;
+
+               if (this.worksheet.getSheetData() == null) {
+                       this.worksheet.addNewSheetData();
+               }
+
+               initRows(this.worksheet);
+               initColumns(this.worksheet);
+
+               hyperlinks = new ArrayList<XSSFHyperlink>();
+       }
+
+       protected XSSFSheet(XSSFWorkbook workbook) {
+               this.workbook = workbook;
+
+               hyperlinks = new ArrayList<XSSFHyperlink>();
+       }
+
+       /**
+        * Returns the parent XSSFWorkbook
+        *
+        * @return the parent XSSFWorkbook
+        */
+       public XSSFWorkbook getWorkbook() {
+               return this.workbook;
+       }
+
+       /**
+        * Create a new CTWorksheet instance and setup default values
+        *
+        * @return a new instance
+        */
+       protected static CTWorksheet newInstance(){
+               CTWorksheet worksheet = CTWorksheet.Factory.newInstance();
+               CTSheetFormatPr ctFormat = worksheet.addNewSheetFormatPr();
+               ctFormat.setDefaultRowHeight(15.0);
+
+               CTSheetView ctView = worksheet.addNewSheetViews().addNewSheetView();
+               ctView.setTabSelected(true);
+               ctView.setWorkbookViewId(0);
+
+               worksheet.addNewDimension().setRef("A1");
+
+               worksheet.addNewSheetData();
+
+               CTPageMargins ctMargins = worksheet.addNewPageMargins();
+               ctMargins.setBottom(0.75);
+               ctMargins.setFooter(0.3);
+               ctMargins.setHeader(0.3);
+               ctMargins.setLeft(0.7);
+               ctMargins.setRight(0.7);
+               ctMargins.setTop(0.75);
+
+               return worksheet;
+       }
+
+       /**
+        * Tweaks the CTWorksheet to fit with what Excel
+        *  will accept without a massive huff, and write into
+        *  the OutputStream supplied.
+        */
+       protected void save(PackagePart sheetPart, XmlOptions xmlOptions) throws IOException {
+               // Excel objects to <cols/>
+               if(worksheet.getColsArray().length == 1) {
+                       CTCols col = worksheet.getColsArray(0);
+                       if(col.getColArray().length == 0) {
+                               worksheet.setColsArray(null);
+                       }
+               }
+
+               // Now re-generate our CTHyperlinks, if needed
+               if(hyperlinks.size() > 0) {
+                       if(worksheet.getHyperlinks() == null) {
+                               worksheet.addNewHyperlinks();
+                       }
+                       CTHyperlink[] ctHls = new CTHyperlink[hyperlinks.size()];
+                       for(int i=0; i<ctHls.length; i++) {
+                               // If our sheet has hyperlinks, have them add
+                               //  any relationships that they might need
+                               XSSFHyperlink hyperlink = hyperlinks.get(i);
+                               hyperlink.generateRelationIfNeeded(sheetPart);
+                               // Now grab their underling object
+                               ctHls[i] = hyperlink.getCTHyperlink();
+                       }
+                       worksheet.getHyperlinks().setHyperlinkArray(ctHls);
+               }
+
+               // Save
+               OutputStream out = sheetPart.getOutputStream();
+               worksheet.save(out, xmlOptions);
+               out.close();
+       }
+
+       /**
+        * Provide access to the underlying XML bean
+        *
+        * @return the underlying CTWorksheet bean
+        */
+       public CTWorksheet getWorksheet() {
+               return this.worksheet;
+       }
+
+       public ColumnHelper getColumnHelper() {
+               return columnHelper;
+       }
+
+       protected void initRows(CTWorksheet worksheet) {
+               this.rows = new LinkedList<Row>();
+               for (CTRow row : worksheet.getSheetData().getRowArray()) {
+                       this.rows.add(new XSSFRow(row, this));
+               }
+       }
+
+       protected void initColumns(CTWorksheet worksheet) {
+               columnHelper = new ColumnHelper(worksheet);
+       }
+
+       protected void initHyperlinks(PackageRelationshipCollection hyperRels) {
+               if(worksheet.getHyperlinks() == null) return;
+
+               // Turn each one into a XSSFHyperlink
+               for(CTHyperlink hyperlink : worksheet.getHyperlinks().getHyperlinkArray()) {
+                       PackageRelationship hyperRel = null;
+                       if(hyperlink.getId() != null) {
+                               hyperRel = hyperRels.getRelationshipByID(hyperlink.getId());
+                       }
+
+                       hyperlinks.add(
+                                       new XSSFHyperlink(hyperlink, hyperRel)
+                       );
+               }
+       }
+
+       protected CTSheet getSheet() {
+               return this.sheet;
+       }
+       public int addMergedRegion(CellRangeAddress cra) {
+               Region r = new Region(cra.getFirstRow(), (short)cra.getFirstColumn(),
+                               cra.getLastRow(), (short)cra.getLastColumn());
+               return addMergedRegion(r);
+       }
+
+
+       public int addMergedRegion(Region region) {
+               addNewMergeCell(region);
+               return ctMergeCells.sizeOfMergeCellArray();
+       }
+
+       /**
+        * Adjusts the column width to fit the contents.
+        *
+        * This process can be relatively slow on large sheets, so this should
+        *  normally only be called once per column, at the end of your
+        *  processing.
+        *
+        * @param column the column index
+        */
    public void autoSizeColumn(short column) {
-       autoSizeColumn(column, false);
-    }
-
-    /**
-     * Adjusts the column width to fit the contents.
-     *
-     * This process can be relatively slow on large sheets, so this should
-     *  normally only be called once per column, at the end of your
-     *  processing.
-     *
-     * You can specify whether the content of merged cells should be considered or ignored.
-     *  Default is to ignore merged cells.
-     *
-     * @param column the column index
-     * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column
-     */
-    public void autoSizeColumn(short column, boolean useMergedCells) {
-        //TODO:
-        columnHelper.setColBestFit(column, true);
-    }
-
-    public Patriarch createDrawingPatriarch() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    /**
-     * Creates a split (freezepane). Any existing freezepane or split pane is overwritten.
-     * @param colSplit      Horizonatal position of split.
-     * @param rowSplit      Vertical position of split.
-     * @param topRow        Top row visible in bottom pane
-     * @param leftmostColumn   Left column visible in right pane.
-     */
-    public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) {
-       this.createFreezePane(colSplit, rowSplit);
-       this.showInPane((short)topRow, (short)leftmostColumn);
-    }
-
-    /**
-     * Creates a split (freezepane). Any existing freezepane or split pane is overwritten.
-     * @param colSplit      Horizonatal position of split.
-     * @param rowSplit      Vertical position of split.
-     */
-    public void createFreezePane(int colSplit, int rowSplit) {
-       getPane().setXSplit(colSplit);
-       getPane().setYSplit(rowSplit);
-       // make bottomRight default active pane
-       getPane().setActivePane(STPane.BOTTOM_RIGHT);
-    }
-    
-    /**
-     * Creates a new comment for this sheet. You still
-     *  need to assign it to a cell though
-     */
-    public XSSFComment createComment() {
-       return (XSSFComment)getComments().addComment();
-    }
-
-    protected XSSFRow addRow(int index, int rownum) {
-        CTRow row = this.worksheet.getSheetData().insertNewRow(index);
-        XSSFRow xrow = new XSSFRow(row, this);
-        xrow.setRowNum(rownum);
-        return xrow;
-    }
-
-    /**
-     * Create a new row within the sheet and return the high level representation
-     *
-     * @param rownum  row number
-     * @return High level {@link XSSFRow} object representing a row in the sheet
-     * @see #removeRow(org.apache.poi.ss.usermodel.Row)
-     */
-    public XSSFRow createRow(int rownum) {
-        int index = 0;
-        for (Row r : this.rows) {
-            if (r.getRowNum() == rownum) {
-                // Replace r with new row
-                XSSFRow xrow = addRow(index, rownum);
-                rows.set(index, xrow);
-                return xrow;
-            }
-            if (r.getRowNum() > rownum) {
-                XSSFRow xrow = addRow(index, rownum);
-                rows.add(index, xrow);
-                return xrow;
-            }
-            ++index;
-        }
-        XSSFRow xrow = addRow(index, rownum);
-        rows.add(xrow);
-        return xrow;
-    }
-
-    /**
-     * Creates a split pane. Any existing freezepane or split pane is overwritten.
-     * @param xSplitPos      Horizonatal position of split (in 1/20th of a point).
-     * @param ySplitPos      Vertical position of split (in 1/20th of a point).
-     * @param topRow        Top row visible in bottom pane
-     * @param leftmostColumn   Left column visible in right pane.
-     * @param activePane    Active pane.  One of: PANE_LOWER_RIGHT,
-     *                      PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT
-     * @see #PANE_LOWER_LEFT
-     * @see #PANE_LOWER_RIGHT
-     * @see #PANE_UPPER_LEFT
-     * @see #PANE_UPPER_RIGHT
-     */
-    public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) {
-       createFreezePane(xSplitPos, ySplitPos, leftmostColumn, topRow);
-       getPane().setActivePane(STPane.Enum.forInt(activePane));
-    }
-
-    public boolean getAlternateExpression() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    public boolean getAlternateFormula() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    public XSSFComment getCellComment(int row, int column) {
-       return (XSSFComment)getComments().findCellComment(row, column);
-    }
-    
-    public XSSFHyperlink getHyperlink(int row, int column) {
-       String ref = new CellReference(row, column).formatAsString();
-       for(XSSFHyperlink hyperlink : hyperlinks) {
-               if(hyperlink.getCellRef().equals(ref)) {
-                       return hyperlink;
-               }
-       }
-       return null;
-    }
-
-    /**
-     * Vertical page break information used for print layout view, page layout view, drawing print breaks
-     * in normal view, and for printing the worksheet.
-     *
-     * @return column indexes of all the vertical page breaks, never <code>null</code>
-     */
-    public int[] getColumnBreaks() {
-        if (!worksheet.isSetColBreaks() || worksheet.getColBreaks().sizeOfBrkArray() == 0) {
-            return new int[0];
-        }
-
-        CTBreak[] brkArray = worksheet.getColBreaks().getBrkArray();
-        int[] breaks = new int[brkArray.length];
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            CTBreak brk = brkArray[i];
-            breaks[i] = (int)brk.getId();
-        }
-        return breaks;
-    }
+               autoSizeColumn(column, false);
+       }
+
+       /**
+        * Adjusts the column width to fit the contents.
+        *
+        * This process can be relatively slow on large sheets, so this should
+        *  normally only be called once per column, at the end of your
+        *  processing.
+        *
+        * You can specify whether the content of merged cells should be considered or ignored.
+        *  Default is to ignore merged cells.
+        *
+        * @param column the column index
+        * @param useMergedCells whether to use the contents of merged cells when calculating the width of the column
+        */
+       public void autoSizeColumn(short column, boolean useMergedCells) {
+               //TODO:
+               columnHelper.setColBestFit(column, true);
+       }
+
+       public Patriarch createDrawingPatriarch() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       /**
+        * Creates a split (freezepane). Any existing freezepane or split pane is overwritten.
+        * @param colSplit        Horizonatal position of split.
+        * @param rowSplit        Vertical position of split.
+        * @param topRow                Top row visible in bottom pane
+        * @param leftmostColumn   Left column visible in right pane.
+        */
+       public void createFreezePane(int colSplit, int rowSplit, int leftmostColumn, int topRow) {
+               this.createFreezePane(colSplit, rowSplit);
+               this.showInPane((short)topRow, (short)leftmostColumn);
+       }
+
+       /**
+        * Creates a split (freezepane). Any existing freezepane or split pane is overwritten.
+        * @param colSplit        Horizonatal position of split.
+        * @param rowSplit        Vertical position of split.
+        */
+       public void createFreezePane(int colSplit, int rowSplit) {
+               getPane().setXSplit(colSplit);
+               getPane().setYSplit(rowSplit);
+               // make bottomRight default active pane
+               getPane().setActivePane(STPane.BOTTOM_RIGHT);
+       }
+
+       /**
+        * Creates a new comment for this sheet. You still
+        *  need to assign it to a cell though
+        */
+       public XSSFComment createComment() {
+               return (XSSFComment)getComments().addComment();
+       }
+
+       protected XSSFRow addRow(int index, int rownum) {
+               CTRow row = this.worksheet.getSheetData().insertNewRow(index);
+               XSSFRow xrow = new XSSFRow(row, this);
+               xrow.setRowNum(rownum);
+               return xrow;
+       }
+
+       /**
+        * Create a new row within the sheet and return the high level representation
+        *
+        * @param rownum  row number
+        * @return High level {@link XSSFRow} object representing a row in the sheet
+        * @see #removeRow(org.apache.poi.ss.usermodel.Row)
+        */
+       public XSSFRow createRow(int rownum) {
+               int index = 0;
+               for (Row r : this.rows) {
+                       if (r.getRowNum() == rownum) {
+                               // Replace r with new row
+                               XSSFRow xrow = addRow(index, rownum);
+                               rows.set(index, xrow);
+                               return xrow;
+                       }
+                       if (r.getRowNum() > rownum) {
+                               XSSFRow xrow = addRow(index, rownum);
+                               rows.add(index, xrow);
+                               return xrow;
+                       }
+                       ++index;
+               }
+               XSSFRow xrow = addRow(index, rownum);
+               rows.add(xrow);
+               return xrow;
+       }
+
+       /**
+        * Creates a split pane. Any existing freezepane or split pane is overwritten.
+        * @param xSplitPos       Horizonatal position of split (in 1/20th of a point).
+        * @param ySplitPos       Vertical position of split (in 1/20th of a point).
+        * @param topRow                Top row visible in bottom pane
+        * @param leftmostColumn   Left column visible in right pane.
+        * @param activePane    Active pane.  One of: PANE_LOWER_RIGHT,
+        *                                        PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT
+        * @see #PANE_LOWER_LEFT
+        * @see #PANE_LOWER_RIGHT
+        * @see #PANE_UPPER_LEFT
+        * @see #PANE_UPPER_RIGHT
+        */
+       public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) {
+               createFreezePane(xSplitPos, ySplitPos, leftmostColumn, topRow);
+               getPane().setActivePane(STPane.Enum.forInt(activePane));
+       }
+
+       public boolean getAlternateExpression() {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       public boolean getAlternateFormula() {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       public XSSFComment getCellComment(int row, int column) {
+               return (XSSFComment)getComments().findCellComment(row, column);
+       }
+
+       public XSSFHyperlink getHyperlink(int row, int column) {
+               String ref = new CellReference(row, column).formatAsString();
+               for(XSSFHyperlink hyperlink : hyperlinks) {
+                       if(hyperlink.getCellRef().equals(ref)) {
+                               return hyperlink;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Vertical page break information used for print layout view, page layout view, drawing print breaks
+        * in normal view, and for printing the worksheet.
+        *
+        * @return column indexes of all the vertical page breaks, never <code>null</code>
+        */
+       public int[] getColumnBreaks() {
+               if (!worksheet.isSetColBreaks() || worksheet.getColBreaks().sizeOfBrkArray() == 0) {
+                       return new int[0];
+               }
+
+               CTBreak[] brkArray = worksheet.getColBreaks().getBrkArray();
+               int[] breaks = new int[brkArray.length];
+               for (int i = 0 ; i < brkArray.length ; i++) {
+                       CTBreak brk = brkArray[i];
+                       breaks[i] = (int)brk.getId();
+               }
+               return breaks;
+       }
 
        protected CTPageBreak getSheetTypeColumnBreaks() {
                if (worksheet.getColBreaks() == null) {
@@ -454,19 +448,19 @@ public class XSSFSheet implements Sheet {
        }
 
        public int getColumnWidth(int columnIndex) {
-        return (int) columnHelper.getColumn(columnIndex, false).getWidth();
+               return (int) columnHelper.getColumn(columnIndex, false).getWidth();
+       }
+       public short getColumnWidth(short column) {
+               return (short) getColumnWidth(column & 0xFFFF);
        }
-    public short getColumnWidth(short column) {
-       return (short) getColumnWidth(column & 0xFFFF);
-    }
 
-    public int getDefaultColumnWidth() {
-        return (int)getSheetTypeSheetFormatPr().getDefaultColWidth();
-    }
+       public int getDefaultColumnWidth() {
+               return (int)getSheetTypeSheetFormatPr().getDefaultColWidth();
+       }
 
-    public short getDefaultRowHeight() {
-        return (short) (getSheetTypeSheetFormatPr().getDefaultRowHeight() * 20);
-    }
+       public short getDefaultRowHeight() {
+               return (short) (getSheetTypeSheetFormatPr().getDefaultRowHeight() * 20);
+       }
 
        protected CTSheetFormatPr getSheetTypeSheetFormatPr() {
                if (worksheet.getSheetFormatPr() == null) {
@@ -475,55 +469,55 @@ public class XSSFSheet implements Sheet {
                return worksheet.getSheetFormatPr();
        }
 
-    public float getDefaultRowHeightInPoints() {
-        return (short) getSheetTypeSheetFormatPr().getDefaultRowHeight();
-    }
-
-    public boolean getDialog() {
-       if (dialogsheet != null) {
-               return true;
-       }
-       return false;
-    }
-
-    public boolean getDisplayGuts() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /**
-     * Gets the first row on the sheet
-     *
-     * @return the number of the first logical row on the sheet, zero based
-     */
-    public int getFirstRowNum() {
-        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
-            Row row = it.next();
-            if (row != null) {
-                return row.getRowNum();
-            }
-        }
-        return -1;
-    }
-
-    /**
-     * Flag indicating whether the Fit to Page print option is enabled.
-     *
-     * @return <code>true</code>
-     */
-    public boolean getFitToPage() {
-        CTSheetPr sheetPr = getSheetTypeSheetPr();
-        CTPageSetUpPr psSetup = (sheetPr == null || !sheetPr.isSetPageSetUpPr()) ?
-                CTPageSetUpPr.Factory.newInstance() : sheetPr.getPageSetUpPr();
-        return psSetup.getFitToPage();
-    }
-
-    protected CTSheetPr getSheetTypeSheetPr() {
-        if (worksheet.getSheetPr() == null) {
-            worksheet.setSheetPr(CTSheetPr.Factory.newInstance());
-        }
-        return worksheet.getSheetPr();
-    }
+       public float getDefaultRowHeightInPoints() {
+               return (short) getSheetTypeSheetFormatPr().getDefaultRowHeight();
+       }
+
+       public boolean getDialog() {
+               if (dialogsheet != null) {
+                       return true;
+               }
+               return false;
+       }
+
+       public boolean getDisplayGuts() {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       /**
+        * Gets the first row on the sheet
+        *
+        * @return the number of the first logical row on the sheet, zero based
+        */
+       public int getFirstRowNum() {
+               for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
+                       Row row = it.next();
+                       if (row != null) {
+                               return row.getRowNum();
+                       }
+               }
+               return -1;
+       }
+
+       /**
+        * Flag indicating whether the Fit to Page print option is enabled.
+        *
+        * @return <code>true</code>
+        */
+       public boolean getFitToPage() {
+               CTSheetPr sheetPr = getSheetTypeSheetPr();
+               CTPageSetUpPr psSetup = (sheetPr == null || !sheetPr.isSetPageSetUpPr()) ?
+                               CTPageSetUpPr.Factory.newInstance() : sheetPr.getPageSetUpPr();
+               return psSetup.getFitToPage();
+       }
+
+       protected CTSheetPr getSheetTypeSheetPr() {
+               if (worksheet.getSheetPr() == null) {
+                       worksheet.setSheetPr(CTSheetPr.Factory.newInstance());
+               }
+               return worksheet.getSheetPr();
+       }
 
        protected CTHeaderFooter getSheetTypeHeaderFooter() {
                if (worksheet.getHeaderFooter() == null) {
@@ -534,83 +528,83 @@ public class XSSFSheet implements Sheet {
 
 
 
-    /**
-     * Returns the default footer for the sheet,
-     *  creating one as needed.
-     * You may also want to look at 
-     *  {@link #getFirstFooter()},
-     *  {@link #getOddFooter()} and
-     *  {@link #getEvenFooter()}
-     */
-    public Footer getFooter() {
-       // The default footer is an odd footer
-        return getOddFooter();
-    }
-
-    /**
-     * Returns the default header for the sheet,
-     *  creating one as needed.
-     * You may also want to look at
-     *  {@link #getFirstHeader()},
-     *  {@link #getOddHeader()} and
-     *  {@link #getEvenHeader()}
-     */
-    public Header getHeader() {
-       // The default header is an odd header
-        return getOddHeader();
-    }
-    
-    /**
-     * Returns the odd footer. Used on all pages unless
-     *  other footers also present, when used on only
-     *  odd pages.
-     */
-    public Footer getOddFooter() {
-        return new XSSFOddFooter(getSheetTypeHeaderFooter());
-    }
-    /**
-     * Returns the even footer. Not there by default, but
-     *  when set, used on even pages. 
-     */
-    public Footer getEvenFooter() {
-        return new XSSFEvenFooter(getSheetTypeHeaderFooter());
-    }
-    /**
-     * Returns the first page footer. Not there by
-     *  default, but when set, used on the first page.
-     */
-    public Footer getFirstFooter() {
-        return new XSSFFirstFooter(getSheetTypeHeaderFooter());
-    }
-
-    /**
-     * Returns the odd header. Used on all pages unless
-     *  other headers also present, when used on only
-     *  odd pages.
-     */
-    public Header getOddHeader() {
-        return new XSSFOddHeader(getSheetTypeHeaderFooter());
-    }
-    /**
-     * Returns the even header. Not there by default, but
-     *  when set, used on even pages. 
-     */
-    public Header getEvenHeader() {
-        return new XSSFEvenHeader(getSheetTypeHeaderFooter()
+       /**
+        * Returns the default footer for the sheet,
+        *  creating one as needed.
+        * You may also want to look at
+        *  {@link #getFirstFooter()},
+        *  {@link #getOddFooter()} and
+        *  {@link #getEvenFooter()}
+        */
+       public Footer getFooter() {
+               // The default footer is an odd footer
+               return getOddFooter();
+       }
+
+       /**
+        * Returns the default header for the sheet,
+        *  creating one as needed.
+        * You may also want to look at
+        *  {@link #getFirstHeader()},
+        *  {@link #getOddHeader()} and
+        *  {@link #getEvenHeader()}
+        */
+       public Header getHeader() {
+               // The default header is an odd header
+               return getOddHeader();
+       }
+
+       /**
+        * Returns the odd footer. Used on all pages unless
+        *  other footers also present, when used on only
+        *  odd pages.
+        */
+       public Footer getOddFooter() {
+               return new XSSFOddFooter(getSheetTypeHeaderFooter());
+       }
+       /**
+        * Returns the even footer. Not there by default, but
+        *  when set, used on even pages.
+        */
+       public Footer getEvenFooter() {
+               return new XSSFEvenFooter(getSheetTypeHeaderFooter());
+       }
+       /**
+        * Returns the first page footer. Not there by
+        *  default, but when set, used on the first page.
+        */
+       public Footer getFirstFooter() {
+               return new XSSFFirstFooter(getSheetTypeHeaderFooter());
+       }
+
+       /**
+        * Returns the odd header. Used on all pages unless
+        *  other headers also present, when used on only
+        *  odd pages.
+        */
+       public Header getOddHeader() {
+               return new XSSFOddHeader(getSheetTypeHeaderFooter());
+       }
+       /**
+        * Returns the even header. Not there by default, but
+        *  when set, used on even pages.
+        */
+       public Header getEvenHeader() {
+               return new XSSFEvenHeader(getSheetTypeHeaderFooter()
 );
-    }
-    /**
-     * Returns the first page header. Not there by
-     *  default, but when set, used on the first page.
-     */
-    public Header getFirstHeader() {
-        return new XSSFFirstHeader(getSheetTypeHeaderFooter());
-    }
-
-    
-    public boolean getHorizontallyCenter() {
-       return getSheetTypePrintOptions().getHorizontalCentered();
-    }
+       }
+       /**
+        * Returns the first page header. Not there by
+        *  default, but when set, used on the first page.
+        */
+       public Header getFirstHeader() {
+               return new XSSFFirstHeader(getSheetTypeHeaderFooter());
+       }
+
+
+       public boolean getHorizontallyCenter() {
+               return getSheetTypePrintOptions().getHorizontalCentered();
+       }
 
        protected CTPrintOptions getSheetTypePrintOptions() {
                if (worksheet.getPrintOptions() == null) {
@@ -619,42 +613,42 @@ public class XSSFSheet implements Sheet {
                return worksheet.getPrintOptions();
        }
 
-    public int getLastRowNum() {
-        int lastRowNum = -1;
-        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
-            Row row = it.next();
-            if (row != null) {
-                lastRowNum = row.getRowNum();
-            }
-        }
-        return lastRowNum;
-    }
-
-    public short getLeftCol() {
-       String cellRef = worksheet.getSheetViews().getSheetViewArray(0).getTopLeftCell();
-       CellReference cellReference = new CellReference(cellRef);
-        return (short)cellReference.getCol();
-    }
-
-    public double getMargin(short margin) {
-        CTPageMargins pageMargins = getSheetTypePageMargins();
-        switch (margin) {
-        case LeftMargin:
-            return pageMargins.getLeft();
-        case RightMargin:
-            return pageMargins.getRight();
-        case TopMargin:
-            return pageMargins.getTop();
-        case BottomMargin:
-            return pageMargins.getBottom();
-        case HeaderMargin:
-            return pageMargins.getHeader();
-        case FooterMargin:
-            return pageMargins.getFooter();
-        default :
-            throw new RuntimeException( "Unknown margin constant:  " + margin );
-        }
-    }
+       public int getLastRowNum() {
+               int lastRowNum = -1;
+               for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
+                       Row row = it.next();
+                       if (row != null) {
+                               lastRowNum = row.getRowNum();
+                       }
+               }
+               return lastRowNum;
+       }
+
+       public short getLeftCol() {
+               String cellRef = worksheet.getSheetViews().getSheetViewArray(0).getTopLeftCell();
+               CellReference cellReference = new CellReference(cellRef);
+               return (short)cellReference.getCol();
+       }
+
+       public double getMargin(short margin) {
+               CTPageMargins pageMargins = getSheetTypePageMargins();
+               switch (margin) {
+               case LeftMargin:
+                       return pageMargins.getLeft();
+               case RightMargin:
+                       return pageMargins.getRight();
+               case TopMargin:
+                       return pageMargins.getTop();
+               case BottomMargin:
+                       return pageMargins.getBottom();
+               case HeaderMargin:
+                       return pageMargins.getHeader();
+               case FooterMargin:
+                       return pageMargins.getFooter();
+               default :
+                       throw new RuntimeException( "Unknown margin constant:  " + margin );
+               }
+       }
 
        protected CTPageMargins getSheetTypePageMargins() {
                if (worksheet.getPageMargins() == null) {
@@ -663,184 +657,184 @@ public class XSSFSheet implements Sheet {
                return worksheet.getPageMargins();
        }
 
-    public Region getMergedRegionAt(int index) {
-       CTMergeCell ctMergeCell = getMergedCells().getMergeCellArray(index);
-       return new Region(ctMergeCell.getRef());
-    }
-
-    public int getNumMergedRegions() {
-       return getMergedCells().sizeOfMergeCellArray();
-    }
-    
-    public int getNumHyperlinks() {
-       return hyperlinks.size();
-    }
-
-    public boolean getObjectProtect() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    public PaneInformation getPaneInformation() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    public short getPassword() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    public int getPhysicalNumberOfRows() {
-        int counter = 0;
-        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
-            if (it.next() != null) {
-                counter++;
-            }
-        }
-        return counter;
-    }
-
-    public PrintSetup getPrintSetup() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    public boolean getProtect() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    /**
-     * Returns the logical row ( 0-based).  If you ask for a row that is not
-     * defined you get a null.  This is to say row 4 represents the fifth row on a sheet.
-     *
-     * @param rownum  row to get
-     * @return <code>XSSFRow</code> representing the rownumber or <code>null</code> if its not defined on the sheet
-     */
-    public XSSFRow getRow(int rownum) {
-        //TODO current implemenation is expensive, it should take O(1), not O(N)
-        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
-            Row row = it.next();
-            if (row.getRowNum() == rownum) {
-                 return (XSSFRow)row;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Horizontal page break information used for print layout view, page layout view, drawing print breaks in normal
-     *  view, and for printing the worksheet.
-     *
-     * @return row indexes of all the horizontal page breaks, never <code>null</code>
-     */
-    public int[] getRowBreaks() {
-        if (!worksheet.isSetRowBreaks() || worksheet.getRowBreaks().sizeOfBrkArray() == 0) {
-            return new int[0];
-        }
-
-        CTBreak[] brkArray = worksheet.getRowBreaks().getBrkArray();
-        int[] breaks = new int[brkArray.length];
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            CTBreak brk = brkArray[i];
-            breaks[i] = (int)brk.getId();
-        }
-        return breaks;
-    }
-
-    /**
-     * Flag indicating whether summary rows appear below detail in an outline, when applying an outline.
-     *
-     * <p>
-     * When true a summary row is inserted below the detailed data being summarized and a
-     * new outline level is established on that row.
-     * </p>
-     * <p>
-     * When false a summary row is inserted above the detailed data being summarized and a new outline level
-     * is established on that row.
-     * </p>
-     * @return <code>true</code> if row summaries appear below detail in the outline
-     */
-    public boolean getRowSumsBelow() {
-        CTSheetPr sheetPr = worksheet.getSheetPr();
-        CTOutlinePr outlinePr = (sheetPr != null && sheetPr.isSetOutlinePr())
-                ? sheetPr.getOutlinePr() : CTOutlinePr.Factory.newInstance();
-        return outlinePr.getSummaryBelow();
-    }
-
-    /**
-     * Flag indicating whether summary rows appear below detail in an outline, when applying an outline.
-     *
-     * <p>
-     * When true a summary row is inserted below the detailed data being summarized and a
-     * new outline level is established on that row.
-     * </p>
-     * <p>
-     * When false a summary row is inserted above the detailed data being summarized and a new outline level
-     * is established on that row.
-     * </p>
-     * @param value <code>true</code> if row summaries appear below detail in the outline
-     */
-    public void setRowSumsBelow(boolean value) {
-        ensureOutlinePr().setSummaryBelow(value);
-    }
-
-    /**
-     * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline.
-     *
-     * <p>
-     * When true a summary column is inserted to the right of the detailed data being summarized
-     * and a new outline level is established on that column.
-     * </p>
-     * <p>
-     * When false a summary column is inserted to the left of the detailed data being
-     * summarized and a new outline level is established on that column.
-     * </p>
-     * @return <code>true</code> if col summaries appear right of the detail in the outline
-     */
-    public boolean getRowSumsRight() {
-        CTSheetPr sheetPr = worksheet.getSheetPr();
-        CTOutlinePr outlinePr = (sheetPr != null && sheetPr.isSetOutlinePr())
-                ? sheetPr.getOutlinePr() : CTOutlinePr.Factory.newInstance();
-        return outlinePr.getSummaryRight();
-    }
-
-    /**
-     * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline.
-     *
-     * <p>
-     * When true a summary column is inserted to the right of the detailed data being summarized
-     * and a new outline level is established on that column.
-     * </p>
-     * <p>
-     * When false a summary column is inserted to the left of the detailed data being
-     * summarized and a new outline level is established on that column.
-     * </p>
-     * @param value <code>true</code> if col summaries appear right of the detail in the outline
-     */
-    public void setRowSumsRight(boolean value) {
-        ensureOutlinePr().setSummaryRight(value);
-    }
-
-
-    /**
-     * Ensure CTWorksheet.CTSheetPr.CTOutlinePr
-     */
-    private CTOutlinePr ensureOutlinePr(){
-        CTSheetPr sheetPr = worksheet.isSetSheetPr() ? worksheet.getSheetPr() : worksheet.addNewSheetPr();
-        CTOutlinePr outlinePr = sheetPr.isSetOutlinePr() ? sheetPr.getOutlinePr() : sheetPr.addNewOutlinePr();
-        return outlinePr;
-    }
-
-    /**
-     * A flag indicating whether scenarios are locked when the sheet is protected.
-     *
-     * @return true => protection enabled; false => protection disabled
-     */
-    public boolean getScenarioProtect() {
-       return getSheetTypeProtection().getScenarios();
-    }
+       public Region getMergedRegionAt(int index) {
+               CTMergeCell ctMergeCell = getMergedCells().getMergeCellArray(index);
+               return new Region(ctMergeCell.getRef());
+       }
+
+       public int getNumMergedRegions() {
+               return getMergedCells().sizeOfMergeCellArray();
+       }
+
+       public int getNumHyperlinks() {
+               return hyperlinks.size();
+       }
+
+       public boolean getObjectProtect() {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       public PaneInformation getPaneInformation() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public short getPassword() {
+               // TODO Auto-generated method stub
+               return 0;
+       }
+
+       public int getPhysicalNumberOfRows() {
+               int counter = 0;
+               for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
+                       if (it.next() != null) {
+                               counter++;
+                       }
+               }
+               return counter;
+       }
+
+       public PrintSetup getPrintSetup() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public boolean getProtect() {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       /**
+        * Returns the logical row ( 0-based).  If you ask for a row that is not
+        * defined you get a null.  This is to say row 4 represents the fifth row on a sheet.
+        *
+        * @param rownum  row to get
+        * @return <code>XSSFRow</code> representing the rownumber or <code>null</code> if its not defined on the sheet
+        */
+       public XSSFRow getRow(int rownum) {
+               //TODO current implemenation is expensive, it should take O(1), not O(N)
+               for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
+                       Row row = it.next();
+                       if (row.getRowNum() == rownum) {
+                                return (XSSFRow)row;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Horizontal page break information used for print layout view, page layout view, drawing print breaks in normal
+        *  view, and for printing the worksheet.
+        *
+        * @return row indexes of all the horizontal page breaks, never <code>null</code>
+        */
+       public int[] getRowBreaks() {
+               if (!worksheet.isSetRowBreaks() || worksheet.getRowBreaks().sizeOfBrkArray() == 0) {
+                       return new int[0];
+               }
+
+               CTBreak[] brkArray = worksheet.getRowBreaks().getBrkArray();
+               int[] breaks = new int[brkArray.length];
+               for (int i = 0 ; i < brkArray.length ; i++) {
+                       CTBreak brk = brkArray[i];
+                       breaks[i] = (int)brk.getId();
+               }
+               return breaks;
+       }
+
+       /**
+        * Flag indicating whether summary rows appear below detail in an outline, when applying an outline.
+        *
+        * <p>
+        * When true a summary row is inserted below the detailed data being summarized and a
+        * new outline level is established on that row.
+        * </p>
+        * <p>
+        * When false a summary row is inserted above the detailed data being summarized and a new outline level
+        * is established on that row.
+        * </p>
+        * @return <code>true</code> if row summaries appear below detail in the outline
+        */
+       public boolean getRowSumsBelow() {
+               CTSheetPr sheetPr = worksheet.getSheetPr();
+               CTOutlinePr outlinePr = (sheetPr != null && sheetPr.isSetOutlinePr())
+                               ? sheetPr.getOutlinePr() : CTOutlinePr.Factory.newInstance();
+               return outlinePr.getSummaryBelow();
+       }
+
+       /**
+        * Flag indicating whether summary rows appear below detail in an outline, when applying an outline.
+        *
+        * <p>
+        * When true a summary row is inserted below the detailed data being summarized and a
+        * new outline level is established on that row.
+        * </p>
+        * <p>
+        * When false a summary row is inserted above the detailed data being summarized and a new outline level
+        * is established on that row.
+        * </p>
+        * @param value <code>true</code> if row summaries appear below detail in the outline
+        */
+       public void setRowSumsBelow(boolean value) {
+               ensureOutlinePr().setSummaryBelow(value);
+       }
+
+       /**
+        * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline.
+        *
+        * <p>
+        * When true a summary column is inserted to the right of the detailed data being summarized
+        * and a new outline level is established on that column.
+        * </p>
+        * <p>
+        * When false a summary column is inserted to the left of the detailed data being
+        * summarized and a new outline level is established on that column.
+        * </p>
+        * @return <code>true</code> if col summaries appear right of the detail in the outline
+        */
+       public boolean getRowSumsRight() {
+               CTSheetPr sheetPr = worksheet.getSheetPr();
+               CTOutlinePr outlinePr = (sheetPr != null && sheetPr.isSetOutlinePr())
+                               ? sheetPr.getOutlinePr() : CTOutlinePr.Factory.newInstance();
+               return outlinePr.getSummaryRight();
+       }
+
+       /**
+        * Flag indicating whether summary columns appear to the right of detail in an outline, when applying an outline.
+        *
+        * <p>
+        * When true a summary column is inserted to the right of the detailed data being summarized
+        * and a new outline level is established on that column.
+        * </p>
+        * <p>
+        * When false a summary column is inserted to the left of the detailed data being
+        * summarized and a new outline level is established on that column.
+        * </p>
+        * @param value <code>true</code> if col summaries appear right of the detail in the outline
+        */
+       public void setRowSumsRight(boolean value) {
+               ensureOutlinePr().setSummaryRight(value);
+       }
+
+
+       /**
+        * Ensure CTWorksheet.CTSheetPr.CTOutlinePr
+        */
+       private CTOutlinePr ensureOutlinePr(){
+               CTSheetPr sheetPr = worksheet.isSetSheetPr() ? worksheet.getSheetPr() : worksheet.addNewSheetPr();
+               CTOutlinePr outlinePr = sheetPr.isSetOutlinePr() ? sheetPr.getOutlinePr() : sheetPr.addNewOutlinePr();
+               return outlinePr;
+       }
+
+       /**
+        * A flag indicating whether scenarios are locked when the sheet is protected.
+        *
+        * @return true => protection enabled; false => protection disabled
+        */
+       public boolean getScenarioProtect() {
+               return getSheetTypeProtection().getScenarios();
+       }
 
        protected CTSheetProtection getSheetTypeProtection() {
                if (worksheet.getSheetProtection() == null) {
@@ -849,310 +843,310 @@ public class XSSFSheet implements Sheet {
                return worksheet.getSheetProtection();
        }
 
-    /**
-     * The top row in the visible view when the sheet is
-     * first viewed after opening it in a viewer
-     *
-     * @return integer indicating the rownum (0 based) of the top row
-     */
-    public short getTopRow() {
-       String cellRef = getSheetTypeSheetView().getTopLeftCell();
-       CellReference cellReference = new CellReference(cellRef);
-        return (short) cellReference.getRow();
-    }
-
-    /**
-     * Determine whether printed output for this sheet will be vertically centered.
-     *
-     * @return whether printed output for this sheet will be vertically centered.
-     */
-    public boolean getVerticallyCenter() {
-        return getSheetTypePrintOptions().getVerticalCentered();
-    }
-
-    /**
-     * Group between (0 based) columns 
-     */
-    public void groupColumn(short fromColumn, short toColumn) {
-       groupColumn1Based(fromColumn+1, toColumn+1);
-    }
-    private void groupColumn1Based(int fromColumn, int toColumn) {
-       CTCols ctCols=worksheet.getColsArray(0);
-       CTCol ctCol=CTCol.Factory.newInstance();
-       ctCol.setMin(fromColumn);
-       ctCol.setMax(toColumn);
-       this.columnHelper.addCleanColIntoCols(ctCols, ctCol);           
-       for(int index=fromColumn;index<=toColumn;index++){
-               CTCol col=columnHelper.getColumn1Based(index, false);
-               //col must exist
-               short outlineLevel=col.getOutlineLevel();
-               col.setOutlineLevel((short)(outlineLevel+1));
-               index=(int)col.getMax();
-       }       
-       worksheet.setColsArray(0,ctCols);
-       setSheetFormatPrOutlineLevelCol();
-    }
-
-    public void groupRow(int fromRow, int toRow) {
-       for(int i=fromRow;i<=toRow;i++){
-               XSSFRow xrow = getRow(i-1);
-               if(xrow == null){//create a new Row
-                        xrow = createRow(i-1);
-               }               
-               CTRow ctrow=xrow.getCTRow();
-               short outlineLevel=ctrow.getOutlineLevel();
-               ctrow.setOutlineLevel((short)(outlineLevel+1));                         
-               }
-       setSheetFormatPrOutlineLevelRow();
-    }
+       /**
+        * The top row in the visible view when the sheet is
+        * first viewed after opening it in a viewer
+        *
+        * @return integer indicating the rownum (0 based) of the top row
+        */
+       public short getTopRow() {
+               String cellRef = getSheetTypeSheetView().getTopLeftCell();
+               CellReference cellReference = new CellReference(cellRef);
+               return (short) cellReference.getRow();
+       }
+
+       /**
+        * Determine whether printed output for this sheet will be vertically centered.
+        *
+        * @return whether printed output for this sheet will be vertically centered.
+        */
+       public boolean getVerticallyCenter() {
+               return getSheetTypePrintOptions().getVerticalCentered();
+       }
+
+       /**
+        * Group between (0 based) columns
+        */
+       public void groupColumn(short fromColumn, short toColumn) {
+               groupColumn1Based(fromColumn+1, toColumn+1);
+       }
+       private void groupColumn1Based(int fromColumn, int toColumn) {
+               CTCols ctCols=worksheet.getColsArray(0);
+               CTCol ctCol=CTCol.Factory.newInstance();
+               ctCol.setMin(fromColumn);
+               ctCol.setMax(toColumn);
+               this.columnHelper.addCleanColIntoCols(ctCols, ctCol);
+               for(int index=fromColumn;index<=toColumn;index++){
+                       CTCol col=columnHelper.getColumn1Based(index, false);
+                       //col must exist
+                       short outlineLevel=col.getOutlineLevel();
+                       col.setOutlineLevel((short)(outlineLevel+1));
+                       index=(int)col.getMax();
+               }
+               worksheet.setColsArray(0,ctCols);
+               setSheetFormatPrOutlineLevelCol();
+       }
+
+       public void groupRow(int fromRow, int toRow) {
+               for(int i=fromRow;i<=toRow;i++){
+                       XSSFRow xrow = getRow(i-1);
+                       if(xrow == null){//create a new Row
+                                xrow = createRow(i-1);
+                       }
+                       CTRow ctrow=xrow.getCTRow();
+                       short outlineLevel=ctrow.getOutlineLevel();
+                       ctrow.setOutlineLevel((short)(outlineLevel+1));
+               }
+               setSheetFormatPrOutlineLevelRow();
+       }
 
    private short getMaxOutlineLevelRows(){
-       short outlineLevel=0;
-       for(Row r:rows){
-               XSSFRow xrow=(XSSFRow)r;
-               outlineLevel=xrow.getCTRow().getOutlineLevel()>outlineLevel? xrow.getCTRow().getOutlineLevel(): outlineLevel;
-       }
-       return outlineLevel;
-    }
-    
-    
-    private short getMaxOutlineLevelCols(){
-       CTCols ctCols=worksheet.getColsArray(0);
-       CTCol[]colArray=ctCols.getColArray();
-       short outlineLevel=0;
-       for(CTCol col: colArray){
-               outlineLevel=col.getOutlineLevel()>outlineLevel? col.getOutlineLevel(): outlineLevel;                   
-       }
-       return outlineLevel;
-    }    
-
-    /**
-     * Determines if there is a page break at the indicated column
-     */
-    public boolean isColumnBroken(short column) {
-        int[] colBreaks = getColumnBreaks();
-        for (int i = 0 ; i < colBreaks.length ; i++) {
-            if (colBreaks[i] == column) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public boolean isColumnHidden(int columnIndex) {
-        return columnHelper.getColumn(columnIndex, false).getHidden();
-    }
-    public boolean isColumnHidden(short column) {
-        return isColumnHidden(column & 0xFFFF);
-    }
-
-    public boolean isDisplayFormulas() {
-       return getSheetTypeSheetView().getShowFormulas();
-    }
-
-    public boolean isDisplayGridlines() {
-        return getSheetTypeSheetView().getShowGridLines();
-    }
-
-    public boolean isDisplayRowColHeadings() {
-        return getSheetTypeSheetView().getShowRowColHeaders();
-    }
-
-    public boolean isGridsPrinted() {
-       return isPrintGridlines();
-    }
-
-    public boolean isPrintGridlines() {
-       return getSheetTypePrintOptions().getGridLines();
-    }
-
-    /**
-     * Tests if there is a page break at the indicated row
-     *
-     * @param row index of the row to test
-     * @return <code>true</code> if there is a page break at the indicated row
-     */
-    public boolean isRowBroken(int row) {
-        int[] rowBreaks = getRowBreaks();
-        for (int i = 0 ; i < rowBreaks.length ; i++) {
-            if (rowBreaks[i] == row) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Sets a page break at the indicated row
-     */
-    public void setRowBreak(int row) {
-        CTPageBreak pgBreak = worksheet.isSetRowBreaks() ? worksheet.getRowBreaks() : worksheet.addNewRowBreaks();
-        if (! isRowBroken(row)) {
-            CTBreak brk = pgBreak.addNewBrk();
-            brk.setId(row);
-        }
-    }
-
-    /**
-     * Removes a page break at the indicated column
-     */
-    public void removeColumnBreak(short column) {
-        CTBreak[] brkArray = getSheetTypeColumnBreaks().getBrkArray();
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            if (brkArray[i].getId() == column) {
-                getSheetTypeColumnBreaks().removeBrk(i);
-            }
-        }
-    }
-
-    public void protectSheet(String password) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void removeMergedRegion(int index) {
-       CTMergeCell[] mergeCellsArray = new CTMergeCell[getMergedCells().sizeOfMergeCellArray() - 1];
-       for (int i = 0 ; i < getMergedCells().sizeOfMergeCellArray() ; i++) {
-               if (i < index) {
-                       mergeCellsArray[i] = getMergedCells().getMergeCellArray(i);
-               }
-               else if (i > index) {
-                       mergeCellsArray[i - 1] = getMergedCells().getMergeCellArray(i);
-               }
-       }
-       getMergedCells().setMergeCellArray(mergeCellsArray);
-    }
-
-    public void removeRow(Row row) {
-        int counter = 0;
-        int rowNum=row.getRowNum();
-        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
-            Row r = it.next();
-            if (r.getRowNum() == rowNum) {
-                it.remove();
-                worksheet.getSheetData().removeRow(counter);
-            }
-            counter++;
-        }
-    }
-
-    /**
-     * Removes the page break at the indicated row
-     */
-    public void removeRowBreak(int row) {
-        CTPageBreak pgBreak = worksheet.isSetRowBreaks() ? worksheet.getRowBreaks() : worksheet.addNewRowBreaks();
-        CTBreak[] brkArray = pgBreak.getBrkArray();
-        for (int i = 0 ; i < brkArray.length ; i++) {
-            if (brkArray[i].getId() == row) {
-                pgBreak.removeBrk(i);
-            }
-        }
-    }
-
-    public Iterator<Row> rowIterator() {
-        return rows.iterator();
-    }
-
-    /**
-     * Alias for {@link #rowIterator()} to
-     *  allow foreach loops
-     */
-    public Iterator<Row> iterator() {
-       return rowIterator();
-    }
-
-    public void setAlternativeExpression(boolean b) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void setAlternativeFormula(boolean b) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /**
-     * Flag indicating whether the sheet displays Automatic Page Breaks.
-     *
-     * @return <code>true</code> if the sheet displays Automatic Page Breaks.
-     */
-     public boolean getAutobreaks() {
-        CTSheetPr sheetPr = getSheetTypeSheetPr();
-        CTPageSetUpPr psSetup = (sheetPr == null || !sheetPr.isSetPageSetUpPr()) ?
-                CTPageSetUpPr.Factory.newInstance() : sheetPr.getPageSetUpPr();
-        return psSetup.getAutoPageBreaks();
-    }
-
-    /**
-     * Flag indicating whether the sheet displays Automatic Page Breaks.
-     *
-     * @param value <code>true</code> if the sheet displays Automatic Page Breaks.
-     */
-    public void setAutobreaks(boolean value) {
-        CTSheetPr sheetPr = getSheetTypeSheetPr();
-        CTPageSetUpPr psSetup = sheetPr.isSetPageSetUpPr() ? sheetPr.getPageSetUpPr() : sheetPr.addNewPageSetUpPr();
-        psSetup.setAutoPageBreaks(value);
-    }
-
-    public void setColumnBreak(short column) {
-        if (! isColumnBroken(column)) {
-            CTBreak brk = getSheetTypeColumnBreaks().addNewBrk();
-            brk.setId(column);
-        }
-    }
-
-    public void setColumnGroupCollapsed(short columnNumber, boolean collapsed) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void setColumnHidden(int columnIndex, boolean hidden) {
-        columnHelper.setColHidden(columnIndex, hidden);
-    }
-    public void setColumnHidden(short column, boolean hidden) {
-       setColumnHidden(column & 0xFFFF, hidden);
-    }
-
-    public void setColumnWidth(int columnIndex, int width) {
-        columnHelper.setColWidth(columnIndex, width);
-    }
-    public void setColumnWidth(short column, short width) {
-       setColumnWidth(column & 0xFFFF, width & 0xFFFF);
-    }
-
-    public void setDefaultColumnStyle(short column, CellStyle style) {
-       columnHelper.setColDefaultStyle(column, style);
-    }
-
-    public void setDefaultColumnWidth(int width) {
-        getSheetTypeSheetFormatPr().setDefaultColWidth(width);
-    }
-    public void setDefaultColumnWidth(short width) {
-       setDefaultColumnWidth(width & 0xFFFF);
-    }
-
-    public void setDefaultRowHeight(short height) {
-        getSheetTypeSheetFormatPr().setDefaultRowHeight(height / 20);
-
-    }
-
-    public void setDefaultRowHeightInPoints(float height) {
-        getSheetTypeSheetFormatPr().setDefaultRowHeight(height);
-
-    }
-
-    public void setDialog(boolean b) {
-        if(b && dialogsheet == null){
-            CTDialogsheet dialogSheet = CTDialogsheet.Factory.newInstance();
-            dialogsheet = dialogSheet;
-        }else{
-            dialogsheet = null;
-        }
-    }
-
-    public void setDisplayFormulas(boolean show) {
-       getSheetTypeSheetView().setShowFormulas(show);
-    }
+               short outlineLevel=0;
+               for(Row r:rows){
+                       XSSFRow xrow=(XSSFRow)r;
+                       outlineLevel=xrow.getCTRow().getOutlineLevel()>outlineLevel? xrow.getCTRow().getOutlineLevel(): outlineLevel;
+               }
+               return outlineLevel;
+       }
+
+
+       private short getMaxOutlineLevelCols(){
+               CTCols ctCols=worksheet.getColsArray(0);
+               CTCol[]colArray=ctCols.getColArray();
+               short outlineLevel=0;
+               for(CTCol col: colArray){
+                       outlineLevel=col.getOutlineLevel()>outlineLevel? col.getOutlineLevel(): outlineLevel;
+               }
+               return outlineLevel;
+       }
+
+       /**
+        * Determines if there is a page break at the indicated column
+        */
+       public boolean isColumnBroken(short column) {
+               int[] colBreaks = getColumnBreaks();
+               for (int i = 0 ; i < colBreaks.length ; i++) {
+                       if (colBreaks[i] == column) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       public boolean isColumnHidden(int columnIndex) {
+               return columnHelper.getColumn(columnIndex, false).getHidden();
+       }
+       public boolean isColumnHidden(short column) {
+               return isColumnHidden(column & 0xFFFF);
+       }
+
+       public boolean isDisplayFormulas() {
+               return getSheetTypeSheetView().getShowFormulas();
+       }
+
+       public boolean isDisplayGridlines() {
+               return getSheetTypeSheetView().getShowGridLines();
+       }
+
+       public boolean isDisplayRowColHeadings() {
+               return getSheetTypeSheetView().getShowRowColHeaders();
+       }
+
+       public boolean isGridsPrinted() {
+               return isPrintGridlines();
+       }
+
+       public boolean isPrintGridlines() {
+               return getSheetTypePrintOptions().getGridLines();
+       }
+
+       /**
+        * Tests if there is a page break at the indicated row
+        *
+        * @param row index of the row to test
+        * @return <code>true</code> if there is a page break at the indicated row
+        */
+       public boolean isRowBroken(int row) {
+               int[] rowBreaks = getRowBreaks();
+               for (int i = 0 ; i < rowBreaks.length ; i++) {
+                       if (rowBreaks[i] == row) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Sets a page break at the indicated row
+        */
+       public void setRowBreak(int row) {
+               CTPageBreak pgBreak = worksheet.isSetRowBreaks() ? worksheet.getRowBreaks() : worksheet.addNewRowBreaks();
+               if (! isRowBroken(row)) {
+                       CTBreak brk = pgBreak.addNewBrk();
+                       brk.setId(row);
+               }
+       }
+
+       /**
+        * Removes a page break at the indicated column
+        */
+       public void removeColumnBreak(short column) {
+               CTBreak[] brkArray = getSheetTypeColumnBreaks().getBrkArray();
+               for (int i = 0 ; i < brkArray.length ; i++) {
+                       if (brkArray[i].getId() == column) {
+                               getSheetTypeColumnBreaks().removeBrk(i);
+                       }
+               }
+       }
+
+       public void protectSheet(String password) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void removeMergedRegion(int index) {
+               CTMergeCell[] mergeCellsArray = new CTMergeCell[getMergedCells().sizeOfMergeCellArray() - 1];
+               for (int i = 0 ; i < getMergedCells().sizeOfMergeCellArray() ; i++) {
+                       if (i < index) {
+                               mergeCellsArray[i] = getMergedCells().getMergeCellArray(i);
+                       }
+                       else if (i > index) {
+                               mergeCellsArray[i - 1] = getMergedCells().getMergeCellArray(i);
+                       }
+               }
+               getMergedCells().setMergeCellArray(mergeCellsArray);
+       }
+
+       public void removeRow(Row row) {
+               int counter = 0;
+               int rowNum=row.getRowNum();
+               for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
+                       Row r = it.next();
+                       if (r.getRowNum() == rowNum) {
+                               it.remove();
+                               worksheet.getSheetData().removeRow(counter);
+                       }
+                       counter++;
+               }
+       }
+
+       /**
+        * Removes the page break at the indicated row
+        */
+       public void removeRowBreak(int row) {
+               CTPageBreak pgBreak = worksheet.isSetRowBreaks() ? worksheet.getRowBreaks() : worksheet.addNewRowBreaks();
+               CTBreak[] brkArray = pgBreak.getBrkArray();
+               for (int i = 0 ; i < brkArray.length ; i++) {
+                       if (brkArray[i].getId() == row) {
+                               pgBreak.removeBrk(i);
+                       }
+               }
+       }
+
+       public Iterator<Row> rowIterator() {
+               return rows.iterator();
+       }
+
+       /**
+        * Alias for {@link #rowIterator()} to
+        *  allow foreach loops
+        */
+       public Iterator<Row> iterator() {
+               return rowIterator();
+       }
+
+       public void setAlternativeExpression(boolean b) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void setAlternativeFormula(boolean b) {
+               // TODO Auto-generated method stub
+
+       }
+
+       /**
+        * Flag indicating whether the sheet displays Automatic Page Breaks.
+        *
+        * @return <code>true</code> if the sheet displays Automatic Page Breaks.
+        */
+        public boolean getAutobreaks() {
+               CTSheetPr sheetPr = getSheetTypeSheetPr();
+               CTPageSetUpPr psSetup = (sheetPr == null || !sheetPr.isSetPageSetUpPr()) ?
+                               CTPageSetUpPr.Factory.newInstance() : sheetPr.getPageSetUpPr();
+               return psSetup.getAutoPageBreaks();
+       }
+
+       /**
+        * Flag indicating whether the sheet displays Automatic Page Breaks.
+        *
+        * @param value <code>true</code> if the sheet displays Automatic Page Breaks.
+        */
+       public void setAutobreaks(boolean value) {
+               CTSheetPr sheetPr = getSheetTypeSheetPr();
+               CTPageSetUpPr psSetup = sheetPr.isSetPageSetUpPr() ? sheetPr.getPageSetUpPr() : sheetPr.addNewPageSetUpPr();
+               psSetup.setAutoPageBreaks(value);
+       }
+
+       public void setColumnBreak(short column) {
+               if (! isColumnBroken(column)) {
+                       CTBreak brk = getSheetTypeColumnBreaks().addNewBrk();
+                       brk.setId(column);
+               }
+       }
+
+       public void setColumnGroupCollapsed(short columnNumber, boolean collapsed) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void setColumnHidden(int columnIndex, boolean hidden) {
+               columnHelper.setColHidden(columnIndex, hidden);
+       }
+       public void setColumnHidden(short column, boolean hidden) {
+               setColumnHidden(column & 0xFFFF, hidden);
+       }
+
+       public void setColumnWidth(int columnIndex, int width) {
+               columnHelper.setColWidth(columnIndex, width);
+       }
+       public void setColumnWidth(short column, short width) {
+               setColumnWidth(column & 0xFFFF, width & 0xFFFF);
+       }
+
+       public void setDefaultColumnStyle(short column, CellStyle style) {
+               columnHelper.setColDefaultStyle(column, style);
+       }
+
+       public void setDefaultColumnWidth(int width) {
+               getSheetTypeSheetFormatPr().setDefaultColWidth(width);
+       }
+       public void setDefaultColumnWidth(short width) {
+               setDefaultColumnWidth(width & 0xFFFF);
+       }
+
+       public void setDefaultRowHeight(short height) {
+               getSheetTypeSheetFormatPr().setDefaultRowHeight(height / 20);
+
+       }
+
+       public void setDefaultRowHeightInPoints(float height) {
+               getSheetTypeSheetFormatPr().setDefaultRowHeight(height);
+
+       }
+
+       public void setDialog(boolean b) {
+               if(b && dialogsheet == null){
+                       CTDialogsheet dialogSheet = CTDialogsheet.Factory.newInstance();
+                       dialogsheet = dialogSheet;
+               }else{
+                       dialogsheet = null;
+               }
+       }
+
+       public void setDisplayFormulas(boolean show) {
+               getSheetTypeSheetView().setShowFormulas(show);
+       }
 
        protected CTSheetView getSheetTypeSheetView() {
                if (getDefaultSheetView() == null) {
@@ -1161,244 +1155,244 @@ public class XSSFSheet implements Sheet {
                return getDefaultSheetView();
        }
 
-    public void setDisplayGridlines(boolean show) {
-       getSheetTypeSheetView().setShowGridLines(show);
-    }
-
-    public void setDisplayGuts(boolean b) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void setDisplayRowColHeadings(boolean show) {
-       getSheetTypeSheetView().setShowRowColHeaders(show);
-    }
-
-    public void setFitToPage(boolean b) {
-        getSheetTypePageSetUpPr().setFitToPage(b);
-    }
-
-    public void setGridsPrinted(boolean value) {
-       setPrintGridlines(value);
-    }
-
-    public void setHorizontallyCenter(boolean value) {
-       getSheetTypePrintOptions().setHorizontalCentered(value);
-    }
-
-    public void setMargin(short margin, double size) {
-        CTPageMargins pageMargins = getSheetTypePageMargins();
-        switch (margin) {
-        case LeftMargin:
-            pageMargins.setLeft(size);
-        case RightMargin:
-            pageMargins.setRight(size);
-        case TopMargin:
-            pageMargins.setTop(size);
-        case BottomMargin:
-            pageMargins.setBottom(size);
-        case HeaderMargin:
-            pageMargins.setHeader(size);
-        case FooterMargin:
-            pageMargins.setFooter(size);
-        }
-    }
-
-    public void setPrintGridlines(boolean newPrintGridlines) {
-       getSheetTypePrintOptions().setGridLines(newPrintGridlines);
-    }
-
-    public void setRowGroupCollapsed(int row, boolean collapse) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void setVerticallyCenter(boolean value) {
-       getSheetTypePrintOptions().setVerticalCentered(value);
-    }
-
-    /**
-     * Sets the zoom magnication for the sheet.  The zoom is expressed as a
-     * fraction.  For example to express a zoom of 75% use 3 for the numerator
-     * and 4 for the denominator.
-     *
-     * @param numerator     The numerator for the zoom magnification.
-     * @param denominator   The denominator for the zoom magnification.
-     * @see #setZoom(int)
-     */    
-    public void setZoom(int numerator, int denominator) {
-        Float result = new Float(numerator)/new Float(denominator)*100;
-       setZoom(result.intValue());
-    }
-
-    /**
-     * Window zoom magnification for current view representing percent values.
-     * Valid values range from 10 to 400. Horizontal & Vertical scale together.
-     *
-     * For example:
-     * <pre>
-     * 10 - 10%
-     * 20 - 20%
-     * \85
-     * 100 - 100%
-     * \85
-     * 400 - 400%
-     * </pre>
-     *
-     * Current view can be Normal, Page Layout, or Page Break Preview.
-     *
-     * @param scale window zoom magnification
-     */
-    public void setZoom(int scale) {
-       getSheetTypeSheetView().setZoomScale(scale);
-    }
-
-    /**
-     * Zoom magnification to use when in normal view, representing percent values.
-     * Valid values range from 10 to 400. Horizontal & Vertical scale together.
-     *
-     * For example:
-     * <pre>
-     * 10 - 10%
-     * 20 - 20%
-     * \85
-     * 100 - 100%
-     * \85
-     * 400 - 400%
-     * </pre>
-     *
-     * Applies for worksheet sheet type only; zero implies the automatic setting.
-     *
-     * @param scale window zoom magnification
-     */
-    public void setZoomNormal(int scale) {
-       getSheetTypeSheetView().setZoomScaleNormal(scale);
-    }
-
-    /**
-     * Zoom magnification to use when in page layout view, representing percent values.
-     * Valid values range from 10 to 400. Horizontal & Vertical scale together.
-     *
-     * For example:
-     * <pre>
-     * 10 - 10%
-     * 20 - 20%
-     * \85
-     * 100 - 100%
-     * \85
-     * 400 - 400%
-     * </pre>
-     *
-     * Applies for worksheet sheet type only; zero implies the automatic setting.
-     *
-     * @param scale
-     */
-    public void setZoomPageLayoutView(int scale) {
-       getSheetTypeSheetView().setZoomScalePageLayoutView(scale);
-    }
-
-    /**
-     * Zoom magnification to use when in page break preview, representing percent values.
-     * Valid values range from 10 to 400. Horizontal & Vertical scale together.
-     *
-     * For example:
-     * <pre>
-     * 10 - 10%
-     * 20 - 20%
-     * \85
-     * 100 - 100%
-     * \85
-     * 400 - 400%
-     * </pre>
-     *
-     * Applies for worksheet only; zero implies the automatic setting.
-     *
-     * @param scale
-     */
-    public void setZoomSheetLayoutView(int scale) {
-       getSheetTypeSheetView().setZoomScaleSheetLayoutView(scale);
-    }
-
-    public void shiftRows(int startRow, int endRow, int n) {
-       shiftRows(startRow, endRow, n, false, false);
-    }
-
-    public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
-        for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
-               Row row = it.next();
-               if (!copyRowHeight) {
-                       row.setHeight((short)0);
-               }
-               if (resetOriginalRowHeight && getDefaultRowHeight() >= 0) {
-                       row.setHeight(getDefaultRowHeight());
-               }
-               if (removeRow(startRow, endRow, n, row.getRowNum())) {
-                       it.remove();
-               }
-               else if (row.getRowNum() >= startRow && row.getRowNum() <= endRow) {
-                       row.setRowNum(row.getRowNum() + n);
-               }
-        }
-    }
-
-    /**
-     * Location of the top left visible cell Location of the top left visible cell in the bottom right
-     * pane (when in Left-to-Right mode).
-     *
-     * @param toprow the top row to show in desktop window pane
-     * @param leftcol the left column to show in desktop window pane
-     */
-    public void showInPane(short toprow, short leftcol) {
-       CellReference cellReference = new CellReference(toprow, leftcol);
-       String cellRef = cellReference.formatAsString();
-       getSheetTypeSheetView().setTopLeftCell(cellRef);
-    }
-
-    public void ungroupColumn(short fromColumn, short toColumn) {
-       CTCols cols=worksheet.getColsArray(0);
-       for(int index=fromColumn;index<=toColumn;index++){
-               CTCol col=columnHelper.getColumn(index, false);
-               if(col!=null){
-                       short outlineLevel=col.getOutlineLevel();
-                       col.setOutlineLevel((short)(outlineLevel-1));
-                       index=(int)col.getMax();
-                       
-                       if(col.getOutlineLevel()<=0){
-                               int colIndex=columnHelper.getIndexOfColumn(cols,col);
-                       worksheet.getColsArray(0).removeCol(colIndex);
-                       }
-               }
-       }
-       worksheet.setColsArray(0,cols);
-       setSheetFormatPrOutlineLevelCol();
-    }
-
-    public void ungroupRow(int fromRow, int toRow) {
-       for(int i=fromRow;i<=toRow;i++){
-               XSSFRow xrow=(XSSFRow)getRow(i-1);
-               if(xrow!=null){
-                       CTRow ctrow=xrow.getCTRow();
-                       short outlinelevel=ctrow.getOutlineLevel();
-                       ctrow.setOutlineLevel((short)(outlinelevel-1));
-                       //remove a row only if the row has no cell and if the outline level is 0
-                       if(ctrow.getOutlineLevel()==0 && xrow.getFirstCellNum()==-1){
-                               removeRow(xrow);
-                       }
-               }
-       }
-       setSheetFormatPrOutlineLevelRow();
-    }
-
-    private void setSheetFormatPrOutlineLevelRow(){
-       short maxLevelRow=getMaxOutlineLevelRows();
-       getSheetTypeSheetFormatPr().setOutlineLevelRow((short)(maxLevelRow));
-    }
-    
-    private void setSheetFormatPrOutlineLevelCol(){
-       short maxLevelCol=getMaxOutlineLevelCols();
-       getSheetTypeSheetFormatPr().setOutlineLevelCol((short)(maxLevelCol));
-    }
-    
+       public void setDisplayGridlines(boolean show) {
+               getSheetTypeSheetView().setShowGridLines(show);
+       }
+
+       public void setDisplayGuts(boolean b) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void setDisplayRowColHeadings(boolean show) {
+               getSheetTypeSheetView().setShowRowColHeaders(show);
+       }
+
+       public void setFitToPage(boolean b) {
+               getSheetTypePageSetUpPr().setFitToPage(b);
+       }
+
+       public void setGridsPrinted(boolean value) {
+               setPrintGridlines(value);
+       }
+
+       public void setHorizontallyCenter(boolean value) {
+               getSheetTypePrintOptions().setHorizontalCentered(value);
+       }
+
+       public void setMargin(short margin, double size) {
+               CTPageMargins pageMargins = getSheetTypePageMargins();
+               switch (margin) {
+               case LeftMargin:
+                       pageMargins.setLeft(size);
+               case RightMargin:
+                       pageMargins.setRight(size);
+               case TopMargin:
+                       pageMargins.setTop(size);
+               case BottomMargin:
+                       pageMargins.setBottom(size);
+               case HeaderMargin:
+                       pageMargins.setHeader(size);
+               case FooterMargin:
+                       pageMargins.setFooter(size);
+               }
+       }
+
+       public void setPrintGridlines(boolean newPrintGridlines) {
+               getSheetTypePrintOptions().setGridLines(newPrintGridlines);
+       }
+
+       public void setRowGroupCollapsed(int row, boolean collapse) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void setVerticallyCenter(boolean value) {
+               getSheetTypePrintOptions().setVerticalCentered(value);
+       }
+
+       /**
+        * Sets the zoom magnication for the sheet.  The zoom is expressed as a
+        * fraction.  For example to express a zoom of 75% use 3 for the numerator
+        * and 4 for the denominator.
+        *
+        * @param numerator      The numerator for the zoom magnification.
+        * @param denominator   The denominator for the zoom magnification.
+        * @see #setZoom(int)
+        */
+       public void setZoom(int numerator, int denominator) {
+               Float result = new Float(numerator)/new Float(denominator)*100;
+               setZoom(result.intValue());
+       }
+
+       /**
+        * Window zoom magnification for current view representing percent values.
+        * Valid values range from 10 to 400. Horizontal & Vertical scale together.
+        *
+        * For example:
+        * <pre>
+        * 10 - 10%
+        * 20 - 20%
+        \85
+        * 100 - 100%
+        \85
+        * 400 - 400%
+        * </pre>
+        *
+        * Current view can be Normal, Page Layout, or Page Break Preview.
+        *
+        * @param scale window zoom magnification
+        */
+       public void setZoom(int scale) {
+               getSheetTypeSheetView().setZoomScale(scale);
+       }
+
+       /**
+        * Zoom magnification to use when in normal view, representing percent values.
+        * Valid values range from 10 to 400. Horizontal & Vertical scale together.
+        *
+        * For example:
+        * <pre>
+        * 10 - 10%
+        * 20 - 20%
+        \85
+        * 100 - 100%
+        \85
+        * 400 - 400%
+        * </pre>
+        *
+        * Applies for worksheet sheet type only; zero implies the automatic setting.
+        *
+        * @param scale window zoom magnification
+        */
+       public void setZoomNormal(int scale) {
+               getSheetTypeSheetView().setZoomScaleNormal(scale);
+       }
+
+       /**
+        * Zoom magnification to use when in page layout view, representing percent values.
+        * Valid values range from 10 to 400. Horizontal & Vertical scale together.
+        *
+        * For example:
+        * <pre>
+        * 10 - 10%
+        * 20 - 20%
+        \85
+        * 100 - 100%
+        \85
+        * 400 - 400%
+        * </pre>
+        *
+        * Applies for worksheet sheet type only; zero implies the automatic setting.
+        *
+        * @param scale
+        */
+       public void setZoomPageLayoutView(int scale) {
+               getSheetTypeSheetView().setZoomScalePageLayoutView(scale);
+       }
+
+       /**
+        * Zoom magnification to use when in page break preview, representing percent values.
+        * Valid values range from 10 to 400. Horizontal & Vertical scale together.
+        *
+        * For example:
+        * <pre>
+        * 10 - 10%
+        * 20 - 20%
+        \85
+        * 100 - 100%
+        \85
+        * 400 - 400%
+        * </pre>
+        *
+        * Applies for worksheet only; zero implies the automatic setting.
+        *
+        * @param scale
+        */
+       public void setZoomSheetLayoutView(int scale) {
+               getSheetTypeSheetView().setZoomScaleSheetLayoutView(scale);
+       }
+
+       public void shiftRows(int startRow, int endRow, int n) {
+               shiftRows(startRow, endRow, n, false, false);
+       }
+
+       public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
+               for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
+                       Row row = it.next();
+                       if (!copyRowHeight) {
+                               row.setHeight((short)0);
+                       }
+                       if (resetOriginalRowHeight && getDefaultRowHeight() >= 0) {
+                               row.setHeight(getDefaultRowHeight());
+                       }
+                       if (removeRow(startRow, endRow, n, row.getRowNum())) {
+                               it.remove();
+                       }
+                       else if (row.getRowNum() >= startRow && row.getRowNum() <= endRow) {
+                               row.setRowNum(row.getRowNum() + n);
+                       }
+               }
+       }
+
+       /**
+        * Location of the top left visible cell Location of the top left visible cell in the bottom right
+        * pane (when in Left-to-Right mode).
+        *
+        * @param toprow the top row to show in desktop window pane
+        * @param leftcol the left column to show in desktop window pane
+        */
+       public void showInPane(short toprow, short leftcol) {
+               CellReference cellReference = new CellReference(toprow, leftcol);
+               String cellRef = cellReference.formatAsString();
+               getSheetTypeSheetView().setTopLeftCell(cellRef);
+       }
+
+       public void ungroupColumn(short fromColumn, short toColumn) {
+               CTCols cols=worksheet.getColsArray(0);
+               for(int index=fromColumn;index<=toColumn;index++){
+                       CTCol col=columnHelper.getColumn(index, false);
+                       if(col!=null){
+                               short outlineLevel=col.getOutlineLevel();
+                               col.setOutlineLevel((short)(outlineLevel-1));
+                               index=(int)col.getMax();
+
+                               if(col.getOutlineLevel()<=0){
+                                       int colIndex=columnHelper.getIndexOfColumn(cols,col);
+                                       worksheet.getColsArray(0).removeCol(colIndex);
+                               }
+                       }
+               }
+               worksheet.setColsArray(0,cols);
+               setSheetFormatPrOutlineLevelCol();
+       }
+
+       public void ungroupRow(int fromRow, int toRow) {
+               for(int i=fromRow;i<=toRow;i++){
+                       XSSFRow xrow=(XSSFRow)getRow(i-1);
+                       if(xrow!=null){
+                               CTRow ctrow=xrow.getCTRow();
+                               short outlinelevel=ctrow.getOutlineLevel();
+                               ctrow.setOutlineLevel((short)(outlinelevel-1));
+                               //remove a row only if the row has no cell and if the outline level is 0
+                               if(ctrow.getOutlineLevel()==0 && xrow.getFirstCellNum()==-1){
+                                       removeRow(xrow);
+                               }
+                       }
+               }
+               setSheetFormatPrOutlineLevelRow();
+       }
+
+       private void setSheetFormatPrOutlineLevelRow(){
+               short maxLevelRow=getMaxOutlineLevelRows();
+               getSheetTypeSheetFormatPr().setOutlineLevelRow((short)(maxLevelRow));
+       }
+
+       private void setSheetFormatPrOutlineLevelCol(){
+               short maxLevelCol=getMaxOutlineLevelCols();
+               getSheetTypeSheetFormatPr().setOutlineLevelCol((short)(maxLevelCol));
+       }
+
        protected CTSheetViews getSheetTypeSheetViews() {
                if (worksheet.getSheetViews() == null) {
                        worksheet.setSheetViews(CTSheetViews.Factory.newInstance());
@@ -1407,76 +1401,76 @@ public class XSSFSheet implements Sheet {
                return worksheet.getSheetViews();
        }
 
-    /**
-     * Returns a flag indicating whether this sheet is selected.
-     * <p>
-     * When only 1 sheet is selected and active, this value should be in synch with the activeTab value.
-     * In case of a conflict, the Start Part setting wins and sets the active sheet tab.
-     * </p>
-     * Note: multiple sheets can be selected, but only one sheet can be active at one time.
-     *
-     * @return <code>true</code> if this sheet is selected
-     */
-    public boolean isSelected() {
-        CTSheetView view = getDefaultSheetView();
-        return view != null && view.getTabSelected();
-    }
-    
-    /**
-     * Sets a flag indicating whether this sheet is selected.
-     *
-     * <p>
-     * When only 1 sheet is selected and active, this value should be in synch with the activeTab value.
-     * In case of a conflict, the Start Part setting wins and sets the active sheet tab.
-     * </p>
-     * Note: multiple sheets can be selected, but only one sheet can be active at one time.
-     *
-     * @param value <code>true</code> if this sheet is selected
-     */
-    public void setSelected(boolean value) {
-        CTSheetViews views = getSheetTypeSheetViews();
-        for (CTSheetView view : views.getSheetViewArray()) {
-            view.setTabSelected(value);
-        }
-    }
-
-    /**
-     * Assign a cell comment to a cell region in this worksheet
-     *
-     * @param cellRef cell region
-     * @param comment the comment to assign
-     */
-    public void setCellComment(String cellRef, XSSFComment comment) {
+       /**
+        * Returns a flag indicating whether this sheet is selected.
+        * <p>
+        * When only 1 sheet is selected and active, this value should be in synch with the activeTab value.
+        * In case of a conflict, the Start Part setting wins and sets the active sheet tab.
+        * </p>
+        * Note: multiple sheets can be selected, but only one sheet can be active at one time.
+        *
+        * @return <code>true</code> if this sheet is selected
+        */
+       public boolean isSelected() {
+               CTSheetView view = getDefaultSheetView();
+               return view != null && view.getTabSelected();
+       }
+
+       /**
+        * Sets a flag indicating whether this sheet is selected.
+        *
+        * <p>
+        * When only 1 sheet is selected and active, this value should be in synch with the activeTab value.
+        * In case of a conflict, the Start Part setting wins and sets the active sheet tab.
+        * </p>
+        * Note: multiple sheets can be selected, but only one sheet can be active at one time.
+        *
+        * @param value <code>true</code> if this sheet is selected
+        */
+       public void setSelected(boolean value) {
+               CTSheetViews views = getSheetTypeSheetViews();
+               for (CTSheetView view : views.getSheetViewArray()) {
+                       view.setTabSelected(value);
+               }
+       }
+
+       /**
+        * Assign a cell comment to a cell region in this worksheet
+        *
+        * @param cellRef cell region
+        * @param comment the comment to assign
+        */
+       public void setCellComment(String cellRef, XSSFComment comment) {
                CellReference cellReference = new CellReference(cellRef);
-       
+
                comment.setRow(cellReference.getRow());
                comment.setColumn(cellReference.getCol());
-    }
-    
-    protected void setCellHyperlink(XSSFHyperlink hyperlink) {
-       hyperlinks.add(hyperlink);
-    }
-
-    /**
-     * Return location of the active cell, e.g. <code>A1</code>.
-     *
-     * @return the location of the active cell.
-     */
-    public String getActiveCell() {
-       return getSheetTypeSelection().getActiveCell();
-    }
-
-    /**
-     * Sets location of the active cell
-     *
-     * @param cellRef the location of the active cell, e.g. <code>A1</code>..
-     */
+       }
+
+       protected void setCellHyperlink(XSSFHyperlink hyperlink) {
+               hyperlinks.add(hyperlink);
+       }
+
+       /**
+        * Return location of the active cell, e.g. <code>A1</code>.
+        *
+        * @return the location of the active cell.
+        */
+       public String getActiveCell() {
+               return getSheetTypeSelection().getActiveCell();
+       }
+
+       /**
+        * Sets location of the active cell
+        *
+        * @param cellRef the location of the active cell, e.g. <code>A1</code>..
+        */
        public void setActiveCell(String cellRef) {
                CTSelection ctsel = getSheetTypeSelection();
-        ctsel.setActiveCell(cellRef);
-        ctsel.setSqref(Arrays.asList(cellRef));
-    }
-       
+               ctsel.setActiveCell(cellRef);
+               ctsel.setSqref(Arrays.asList(cellRef));
+       }
+
        /**
         * Does this sheet have any comments on it? We need to know,
         *  so we can decide about writing it to disk or not
@@ -1497,33 +1491,33 @@ public class XSSFSheet implements Sheet {
                return getSheetTypeSheetView().getSelectionArray(0);
        }
 
-    /**
-     * Return the default sheet view. This is the last one if the sheet's views, according to sec. 3.3.1.83
-     * of the OOXML spec: "A single sheet view definition. When more than 1 sheet view is defined in the file,
-     * it means that when opening the workbook, each sheet view corresponds to a separate window within the 
-     * spreadsheet application, where each window is showing the particular sheet. containing the same 
-     * workbookViewId value, the last sheetView definition is loaded, and the others are discarded. 
-     * When multiple windows are viewing the same sheet, multiple sheetView elements (with corresponding 
-     * workbookView entries) are saved."
-     */
-    private CTSheetView getDefaultSheetView() {
-        CTSheetViews views = getSheetTypeSheetViews();
-        if (views == null || views.getSheetViewArray() == null || views.getSheetViewArray().length <= 0) {
-            return null;
-        }
-        return views.getSheetViewArray(views.getSheetViewArray().length - 1);
-    }
-    
-    protected XSSFSheet cloneSheet() {
-       XSSFSheet newSheet = new XSSFSheet(this.workbook);
-       newSheet.setSheet((CTSheet)sheet.copy());
-        return newSheet;
-    }
-    
+       /**
+        * Return the default sheet view. This is the last one if the sheet's views, according to sec. 3.3.1.83
+        * of the OOXML spec: "A single sheet view definition. When more than 1 sheet view is defined in the file,
+        * it means that when opening the workbook, each sheet view corresponds to a separate window within the
+        * spreadsheet application, where each window is showing the particular sheet. containing the same
+        * workbookViewId value, the last sheetView definition is loaded, and the others are discarded.
+        * When multiple windows are viewing the same sheet, multiple sheetView elements (with corresponding
+        * workbookView entries) are saved."
+        */
+       private CTSheetView getDefaultSheetView() {
+               CTSheetViews views = getSheetTypeSheetViews();
+               if (views == null || views.getSheetViewArray() == null || views.getSheetViewArray().length <= 0) {
+                       return null;
+               }
+               return views.getSheetViewArray(views.getSheetViewArray().length - 1);
+       }
+
+       protected XSSFSheet cloneSheet() {
+               XSSFSheet newSheet = new XSSFSheet(this.workbook);
+               newSheet.setSheet((CTSheet)sheet.copy());
+               return newSheet;
+       }
+
        private void setSheet(CTSheet sheet) {
                this.sheet = sheet;
        }
-       
+
        private CommentsSource getComments() {
                if (sheetComments == null) {
                        sheetComments = new CommentsTable();
@@ -1539,34 +1533,34 @@ public class XSSFSheet implements Sheet {
        }
 
        private void addNewMergeCell(Region region) {
-       ctMergeCells = getMergedCells();
-       CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell();
-       ctMergeCell.setRef(region.getRegionRef());
+               ctMergeCells = getMergedCells();
+               CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell();
+               ctMergeCell.setRef(region.getRegionRef());
        }
 
        private CTMergeCells getMergedCells() {
                if (ctMergeCells == null) {
                        ctMergeCells = worksheet.addNewMergeCells();
-       }
+               }
                return ctMergeCells;
        }
 
        private CTPageSetUpPr getSheetTypePageSetUpPr() {
-        CTSheetPr sheetPr = getSheetTypeSheetPr();
-        return sheetPr.isSetPageSetUpPr() ? sheetPr.getPageSetUpPr() : sheetPr.addNewPageSetUpPr();
-       }
-
-    private boolean removeRow(int startRow, int endRow, int n, int rownum) {
-       if (rownum >= (startRow + n) && rownum <= (endRow + n)) {
-               if (n > 0 && rownum > endRow) {
-                       return true;
-               }
-               else if (n < 0 && rownum < startRow) {
-                       return true;
-               }
-       }
-       return false;
-    }
+               CTSheetPr sheetPr = getSheetTypeSheetPr();
+               return sheetPr.isSetPageSetUpPr() ? sheetPr.getPageSetUpPr() : sheetPr.addNewPageSetUpPr();
+       }
+
+       private boolean removeRow(int startRow, int endRow, int n, int rownum) {
+               if (rownum >= (startRow + n) && rownum <= (endRow + n)) {
+                       if (n > 0 && rownum > endRow) {
+                               return true;
+                       }
+                       else if (n < 0 && rownum < startRow) {
+                               return true;
+                       }
+               }
+               return false;
+       }
 
        private CTPane getPane() {
                if (getDefaultSheetView().getPane() == null) {
@@ -1574,9 +1568,4 @@ public class XSSFSheet implements Sheet {
                }
                return getDefaultSheetView().getPane();
        }
-       
-       
-       
-       
-       
 }
index 141bda29283a7c119c6c94787278390a247f1be3..10449078dbef05db1072290a752999989eb97a0e 100644 (file)
@@ -20,7 +20,6 @@ package org.apache.poi.xssf.usermodel;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -68,445 +67,443 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
        /** Are we a normal workbook, or a macro enabled one? */
        private boolean isMacroEnabled = false;
 
-    private CTWorkbook workbook;
-
-    private List<XSSFSheet> sheets = new LinkedList<XSSFSheet>();
-    private List<XSSFName> namedRanges = new LinkedList<XSSFName>();
-
-    private SharedStringSource sharedStringSource;
-    private StylesSource stylesSource;
-
-    private List<? extends XSSFModel> themes = new LinkedList<ThemeTable>();
-
-    private MissingCellPolicy missingCellPolicy = Row.RETURN_NULL_AND_BLANK;
-
-    private static POILogger log = POILogFactory.getLogger(XSSFWorkbook.class);
-
-    public XSSFWorkbook() {
-        this.workbook = CTWorkbook.Factory.newInstance();
-        CTBookViews bvs = this.workbook.addNewBookViews();
-        CTBookView bv = bvs.addNewWorkbookView();
-        bv.setActiveTab(0);
-        this.workbook.addNewSheets();
-
-        // We always require styles and shared strings
-        sharedStringSource = new SharedStringsTable();
-        stylesSource = new StylesTable();
-    }
-
-    public XSSFWorkbook(String path) throws IOException {
-       this(openPackage(path));
-    }
-    public XSSFWorkbook(InputStream  is) throws IOException {
-       this(openPackage(is));
-    }
-
-    public XSSFWorkbook(Package pkg) throws IOException {
-        super(pkg);
-        try {
-            WorkbookDocument doc = WorkbookDocument.Factory.parse(getCorePart().getInputStream());
-            this.workbook = doc.getWorkbook();
-
-            // Are we macro enabled, or just normal?
-            isMacroEnabled =
-                       getCorePart().getContentType().equals(XSSFRelation.MACROS_WORKBOOK.getContentType());
-
-            try {
-                   // Load shared strings
-                   this.sharedStringSource = (SharedStringSource)
-                       XSSFRelation.SHARED_STRINGS.load(getCorePart());
-            } catch(Exception e) {
-               throw new IOException("Unable to load shared strings - " + e.toString());
-            }
-            try {
-                   // Load styles source
-                   this.stylesSource = (StylesSource)
-                       XSSFRelation.STYLES.load(getCorePart());
-            } catch(Exception e) {
-               e.printStackTrace();
-               throw new IOException("Unable to load styles - " + e.toString());
-            }
-            try {
-                   // Load themes
-                   this.themes = XSSFRelation.THEME.loadAll(getCorePart());
-            } catch(Exception e) {
-               throw new IOException("Unable to load shared strings - " + e.toString());
-            }
-
-            // Load individual sheets
-            for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) {
-                PackagePart part = getPackagePart(ctSheet);
-                if (part == null) {
-                       log.log(POILogger.WARN, "Sheet with name " + ctSheet.getName() + " and r:id " + ctSheet.getId()+ " was defined, but didn't exist in package, skipping");
-                    continue;
-                }
-
-                // Load child streams of the sheet
-                ArrayList<? extends XSSFModel> childModels;
-                CommentsSource comments = null;
-                ArrayList<Drawing> drawings;
-                ArrayList<Control> controls;
-                try {
-                       // Get the comments for the sheet, if there are any
-                       childModels = XSSFRelation.SHEET_COMMENTS.loadAll(part);
-                       if(childModels.size() > 0) {
-                               comments = (CommentsSource)childModels.get(0);
-                       }
-
-                       // Get the drawings for the sheet, if there are any
-                       drawings = (ArrayList<Drawing>)XSSFRelation.VML_DRAWINGS.loadAll(part);
-                       // Get the activeX controls for the sheet, if there are any
-                       controls = (ArrayList<Control>)XSSFRelation.ACTIVEX_CONTROLS.loadAll(part);
-                } catch(Exception e) {
-                       throw new RuntimeException("Unable to construct child part",e);
-                }
-
-                // Now create the sheet
-                WorksheetDocument worksheetDoc = WorksheetDocument.Factory.parse(part.getInputStream());
-                XSSFSheet sheet = new XSSFSheet(ctSheet, worksheetDoc.getWorksheet(), this, comments, drawings, controls);
-                this.sheets.add(sheet);
-
-                // Process external hyperlinks for the sheet,
-                //  if there are any
-                PackageRelationshipCollection hyperlinkRels =
-                       part.getRelationshipsByType(XSSFRelation.SHEET_HYPERLINKS.getRelation());
-                sheet.initHyperlinks(hyperlinkRels);
-
-                // Get the embeddings for the workbook
-                for(PackageRelationship rel : part.getRelationshipsByType(XSSFRelation.OLEEMBEDDINGS.getRelation()))
-                    embedds.add(getTargetPart(rel)); // TODO: Add this reference to each sheet as well
-
-                for(PackageRelationship rel : part.getRelationshipsByType(XSSFRelation.PACKEMBEDDINGS.getRelation()))
-                    embedds.add(getTargetPart(rel));
-            }
-        } catch (XmlException e) {
-            throw new IOException(e.toString());
-        } catch (InvalidFormatException e) {
-            throw new IOException(e.toString());
-        }
-
-        // Process the named ranges
-        if(workbook.getDefinedNames() != null) {
-               for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameArray()) {
-                       namedRanges.add(new XSSFName(ctName, this));
-               }
-        }
-    }
-
-    /**
-     * Return the underlying XML bean
-     *
-     * @return the underlying CTWorkbook bean
-     */
-    public CTWorkbook getWorkbook() {
-        return this.workbook;
-    }
-
-    /**
-     * Get the PackagePart corresponding to a given sheet.
-     *
-     * @param ctSheet The sheet
-     * @return A PackagePart, or null if no matching part found.
-     * @throws InvalidFormatException
-     */
-    private PackagePart getPackagePart(CTSheet ctSheet) throws InvalidFormatException {
-        PackageRelationship rel = this.getCorePart().getRelationship(ctSheet.getId());
-        if (rel == null) {
-            log.log(POILogger.WARN, "No relationship found for sheet " + ctSheet.getId() + " - core part has " + this.getCorePart().getRelationships().size() + " relations defined");
-            return null;
-        }
-        return getTargetPart(rel);
-    }
-
-    public int addPicture(byte[] pictureData, int format) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    public XSSFSheet cloneSheet(int sheetNum) {
-        XSSFSheet srcSheet = sheets.get(sheetNum);
-        String srcName = getSheetName(sheetNum);
-        if (srcSheet != null) {
-            XSSFSheet clonedSheet = srcSheet.cloneSheet();
-
-            sheets.add(clonedSheet);
-            CTSheet newcts = this.workbook.getSheets().addNewSheet();
-            newcts.set(clonedSheet.getSheet());
-
-            int i = 1;
-            while (true) {
-                //Try and find the next sheet name that is unique
-                String name = srcName;
-                String index = Integer.toString(i++);
-                if (name.length() + index.length() + 2 < 31) {
-                    name = name + "("+index+")";
-                } else {
-                    name = name.substring(0, 31 - index.length() - 2) + "(" +index + ")";
-                }
-
-                //If the sheet name is unique, then set it otherwise move on to the next number.
-                if (getSheetIndex(name) == -1) {
-                    setSheetName(sheets.size() - 1, name);
-                    break;
-                }
-            }
-            return clonedSheet;
-        }
-        return null;
-    }
-
-    public XSSFCellStyle createCellStyle() {
-        CTXf xf=CTXf.Factory.newInstance();
-        xf.setNumFmtId(0);
-        xf.setFontId(0);
-        xf.setFillId(0);
-        xf.setBorderId(0);
-        xf.setXfId(0);
-        int xfSize=((StylesTable)stylesSource)._getStyleXfsSize();
-        long indexXf=((StylesTable)stylesSource).putCellXf(xf);
-        XSSFCellStyle style = new XSSFCellStyle(new Long(indexXf-1).intValue(), xfSize-1, (StylesTable)stylesSource);
-        return style;
-    }
-
-    public XSSFDataFormat createDataFormat() {
-       return (XSSFDataFormat)getCreationHelper().createDataFormat();
-    }
-
-    public XSSFFont createFont() {
-        XSSFFont font= new XSSFFont();
-        stylesSource.putFont(font);
-        return font;
-    }
-
-    public XSSFName createName() {
-       XSSFName name = new XSSFName(this);
-       namedRanges.add(name);
-       return name;
-    }
-
-    public XSSFSheet createSheet() {
-        String sheetname = "Sheet" + (sheets.size() + 1);
-        return createSheet(sheetname);
-    }
-
-    public XSSFSheet createSheet(String sheetname) {
-           if (doesContainsSheetName( sheetname, sheets.size() ))
-                   throw new IllegalArgumentException( "The workbook already contains a sheet of this name" );
-        return createSheet(sheetname, XSSFSheet.newInstance());
-    }
-
-    public XSSFSheet createSheet(String sheetname, CTWorksheet worksheet) {
-        CTSheet sheet = addSheet(sheetname);
-        XSSFSheet wrapper = new XSSFSheet(sheet, worksheet, this);
-        this.sheets.add(wrapper);
-        return wrapper;
-    }
-
-    public XSSFSheet createDialogsheet(String sheetname, CTDialogsheet dialogsheet) {
-    CTSheet sheet = addSheet(sheetname);
-    XSSFDialogsheet wrapper = new XSSFDialogsheet(sheet, dialogsheet, this);
-    this.sheets.add(wrapper);
-    return wrapper;
-    }
+       private CTWorkbook workbook;
+
+       private List<XSSFSheet> sheets = new LinkedList<XSSFSheet>();
+       private List<XSSFName> namedRanges = new LinkedList<XSSFName>();
+
+       private SharedStringSource sharedStringSource;
+       private StylesSource stylesSource;
+
+       private List<ThemeTable> themes = new LinkedList<ThemeTable>();
+
+       private MissingCellPolicy missingCellPolicy = Row.RETURN_NULL_AND_BLANK;
+
+       private static POILogger log = POILogFactory.getLogger(XSSFWorkbook.class);
+
+       public XSSFWorkbook() {
+               this.workbook = CTWorkbook.Factory.newInstance();
+               CTBookViews bvs = this.workbook.addNewBookViews();
+               CTBookView bv = bvs.addNewWorkbookView();
+               bv.setActiveTab(0);
+               this.workbook.addNewSheets();
+
+               // We always require styles and shared strings
+               sharedStringSource = new SharedStringsTable();
+               stylesSource = new StylesTable();
+       }
+
+       public XSSFWorkbook(String path) throws IOException {
+               this(openPackage(path));
+       }
+       public XSSFWorkbook(InputStream  is) throws IOException {
+               this(openPackage(is));
+       }
+
+       public XSSFWorkbook(Package pkg) throws IOException {
+               super(pkg);
+               try {
+                       WorkbookDocument doc = WorkbookDocument.Factory.parse(getCorePart().getInputStream());
+                       this.workbook = doc.getWorkbook();
+
+                       // Are we macro enabled, or just normal?
+                       isMacroEnabled =
+                                       getCorePart().getContentType().equals(XSSFRelation.MACROS_WORKBOOK.getContentType());
+
+                       try {
+                               // Load shared strings
+                               sharedStringSource = XSSFRelation.SHARED_STRINGS.load(getCorePart());
+                       } catch(Exception e) {
+                               throw new IOException("Unable to load shared strings - " + e.toString());
+                       }
+                       try {
+                               // Load styles source
+                               stylesSource = XSSFRelation.STYLES.load(getCorePart());
+                       } catch(Exception e) {
+                               e.printStackTrace();
+                               throw new IOException("Unable to load styles - " + e.toString());
+                       }
+                       try {
+                               // Load themes
+                               themes = XSSFRelation.THEME.loadAll(getCorePart());
+                       } catch(Exception e) {
+                               throw new IOException("Unable to load shared strings - " + e.toString());
+                       }
+
+                       // Load individual sheets
+                       for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) {
+                               PackagePart part = getPackagePart(ctSheet);
+                               if (part == null) {
+                                       log.log(POILogger.WARN, "Sheet with name " + ctSheet.getName() + " and r:id " + ctSheet.getId()+ " was defined, but didn't exist in package, skipping");
+                                       continue;
+                               }
+
+                               // Load child streams of the sheet
+                               List<CommentsTable> childModels;
+                               CommentsSource comments = null;
+                               List<Drawing> drawings;
+                               List<Control> controls;
+                               try {
+                                       // Get the comments for the sheet, if there are any
+                                       childModels = XSSFRelation.SHEET_COMMENTS.loadAll(part);
+                                       if(childModels.size() > 0) {
+                                               comments = childModels.get(0);
+                                       }
+
+                                       // Get the drawings for the sheet, if there are any
+                                       drawings = XSSFRelation.VML_DRAWINGS.loadAll(part);
+                                       // Get the activeX controls for the sheet, if there are any
+                                       controls = XSSFRelation.ACTIVEX_CONTROLS.loadAll(part);
+                               } catch(Exception e) {
+                                       throw new RuntimeException("Unable to construct child part",e);
+                               }
+
+                               // Now create the sheet
+                               WorksheetDocument worksheetDoc = WorksheetDocument.Factory.parse(part.getInputStream());
+                               XSSFSheet sheet = new XSSFSheet(ctSheet, worksheetDoc.getWorksheet(), this, comments, drawings, controls);
+                               this.sheets.add(sheet);
+
+                               // Process external hyperlinks for the sheet,
+                               //  if there are any
+                               PackageRelationshipCollection hyperlinkRels =
+                                       part.getRelationshipsByType(XSSFRelation.SHEET_HYPERLINKS.getRelation());
+                               sheet.initHyperlinks(hyperlinkRels);
+
+                               // Get the embeddings for the workbook
+                               for(PackageRelationship rel : part.getRelationshipsByType(XSSFRelation.OLEEMBEDDINGS.getRelation()))
+                                       embedds.add(getTargetPart(rel)); // TODO: Add this reference to each sheet as well
+
+                               for(PackageRelationship rel : part.getRelationshipsByType(XSSFRelation.PACKEMBEDDINGS.getRelation()))
+                                       embedds.add(getTargetPart(rel));
+                       }
+               } catch (XmlException e) {
+                       throw new IOException(e.toString());
+               } catch (InvalidFormatException e) {
+                       throw new IOException(e.toString());
+               }
+
+               // Process the named ranges
+               if(workbook.getDefinedNames() != null) {
+                       for(CTDefinedName ctName : workbook.getDefinedNames().getDefinedNameArray()) {
+                               namedRanges.add(new XSSFName(ctName, this));
+                       }
+               }
+       }
+
+       /**
+        * Return the underlying XML bean
+        *
+        * @return the underlying CTWorkbook bean
+        */
+       public CTWorkbook getWorkbook() {
+               return this.workbook;
+       }
+
+       /**
+        * Get the PackagePart corresponding to a given sheet.
+        *
+        * @param ctSheet The sheet
+        * @return A PackagePart, or null if no matching part found.
+        * @throws InvalidFormatException
+        */
+       private PackagePart getPackagePart(CTSheet ctSheet) throws InvalidFormatException {
+               PackageRelationship rel = this.getCorePart().getRelationship(ctSheet.getId());
+               if (rel == null) {
+                       log.log(POILogger.WARN, "No relationship found for sheet " + ctSheet.getId() + " - core part has " + this.getCorePart().getRelationships().size() + " relations defined");
+                       return null;
+               }
+               return getTargetPart(rel);
+       }
+
+       public int addPicture(byte[] pictureData, int format) {
+               // TODO Auto-generated method stub
+               return 0;
+       }
+
+       public XSSFSheet cloneSheet(int sheetNum) {
+               XSSFSheet srcSheet = sheets.get(sheetNum);
+               String srcName = getSheetName(sheetNum);
+               if (srcSheet != null) {
+                       XSSFSheet clonedSheet = srcSheet.cloneSheet();
+
+                       sheets.add(clonedSheet);
+                       CTSheet newcts = this.workbook.getSheets().addNewSheet();
+                       newcts.set(clonedSheet.getSheet());
+
+                       int i = 1;
+                       while (true) {
+                               //Try and find the next sheet name that is unique
+                               String name = srcName;
+                               String index = Integer.toString(i++);
+                               if (name.length() + index.length() + 2 < 31) {
+                                       name = name + "("+index+")";
+                               } else {
+                                       name = name.substring(0, 31 - index.length() - 2) + "(" +index + ")";
+                               }
+
+                               //If the sheet name is unique, then set it otherwise move on to the next number.
+                               if (getSheetIndex(name) == -1) {
+                                       setSheetName(sheets.size() - 1, name);
+                                       break;
+                               }
+                       }
+                       return clonedSheet;
+               }
+               return null;
+       }
+
+       public XSSFCellStyle createCellStyle() {
+               CTXf xf=CTXf.Factory.newInstance();
+               xf.setNumFmtId(0);
+               xf.setFontId(0);
+               xf.setFillId(0);
+               xf.setBorderId(0);
+               xf.setXfId(0);
+               int xfSize=((StylesTable)stylesSource)._getStyleXfsSize();
+               long indexXf=((StylesTable)stylesSource).putCellXf(xf);
+               XSSFCellStyle style = new XSSFCellStyle(new Long(indexXf-1).intValue(), xfSize-1, (StylesTable)stylesSource);
+               return style;
+       }
+
+       public XSSFDataFormat createDataFormat() {
+               return (XSSFDataFormat)getCreationHelper().createDataFormat();
+       }
+
+       public XSSFFont createFont() {
+               XSSFFont font= new XSSFFont();
+               stylesSource.putFont(font);
+               return font;
+       }
+
+       public XSSFName createName() {
+               XSSFName name = new XSSFName(this);
+               namedRanges.add(name);
+               return name;
+       }
+
+       public XSSFSheet createSheet() {
+               String sheetname = "Sheet" + (sheets.size() + 1);
+               return createSheet(sheetname);
+       }
+
+       public XSSFSheet createSheet(String sheetname) {
+               if (doesContainsSheetName( sheetname, sheets.size() ))
+                       throw new IllegalArgumentException( "The workbook already contains a sheet of this name" );
+               return createSheet(sheetname, XSSFSheet.newInstance());
+       }
+
+       public XSSFSheet createSheet(String sheetname, CTWorksheet worksheet) {
+               CTSheet sheet = addSheet(sheetname);
+               XSSFSheet wrapper = new XSSFSheet(sheet, worksheet, this);
+               this.sheets.add(wrapper);
+               return wrapper;
+       }
+
+       public XSSFSheet createDialogsheet(String sheetname, CTDialogsheet dialogsheet) {
+       CTSheet sheet = addSheet(sheetname);
+       XSSFDialogsheet wrapper = new XSSFDialogsheet(sheet, dialogsheet, this);
+       this.sheets.add(wrapper);
+       return wrapper;
+       }
 
        private CTSheet addSheet(String sheetname) {
                CTSheet sheet = workbook.getSheets().addNewSheet();
-        sheet.setName(sheetname);
+               sheet.setName(sheetname);
                return sheet;
        }
 
-    public XSSFFont findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) {
-       short fontNum=getNumberOfFonts();
-        for (short i = 0; i < fontNum; i++) {
-            XSSFFont xssfFont = getFontAt(i);
-
-            if (    (xssfFont.getBold() == (boldWeight == XSSFFont.BOLDWEIGHT_BOLD))
-                    && xssfFont.getColor() == color
-                    && xssfFont.getFontHeightInPoints() == fontHeight
-                    && xssfFont.getFontName().equals(name)
-                    && xssfFont.getItalic() == italic
-                    && xssfFont.getStrikeout() == strikeout
-                    && xssfFont.getTypeOffset() == typeOffset
-                    && xssfFont.getUnderline() == underline)
-            {
-                return xssfFont;
-            }
-        }
-       return null;
-    }
-
-    /**
-     * Convenience method to get the active sheet.  The active sheet is is the sheet
-     * which is currently displayed when the workbook is viewed in Excel.
-     * 'Selected' sheet(s) is a distinct concept.
-     */
-    public int getActiveSheetIndex() {
-        //activeTab (Active Sheet Index) Specifies an unsignedInt 
-        //that contains the index to the active sheet in this book view.
-        Long index = workbook.getBookViews().getWorkbookViewArray(0).getActiveTab();
-        return index.intValue();
-    }
-
-    public List getAllEmbeddedObjects() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    public List<PictureData> getAllPictures() {
-        // In OOXML pictures are referred to in sheets
-        List<PictureData> pictures = new LinkedList<PictureData>();
-        for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) {
-            try {
-                PackagePart sheetPart = getPackagePart(ctSheet);
-                if (sheetPart == null) {
-                    continue;
-                }
-                PackageRelationshipCollection prc = sheetPart.getRelationshipsByType(XSSFRelation.DRAWINGS.getRelation());
-                for (PackageRelationship rel : prc) {
-                    PackagePart drawingPart = getTargetPart(rel);
-                    PackageRelationshipCollection prc2 = drawingPart.getRelationshipsByType(XSSFRelation.IMAGES.getRelation());
-                    for (PackageRelationship rel2 : prc2) {
-                        PackagePart imagePart = getTargetPart(rel2);
-                        XSSFPictureData pd = new XSSFPictureData(imagePart);
-                        pictures.add(pd);
-                    }
-                }
-            } catch (InvalidFormatException e) {
-                throw new RuntimeException(e.getMessage(), e);
-            }
-        }
-        return pictures;
-    }
-
-    public boolean getBackupFlag() {
-        // TODO Auto-generated method stub
-        return false;
-    }
-
-    public XSSFCellStyle getCellStyleAt(short idx) {
-        return (XSSFCellStyle)stylesSource.getStyleAt(idx);
-    }
-
-    public Palette getCustomPalette() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    public XSSFFont getFontAt(short idx) {
-        return (XSSFFont)stylesSource.getFontAt(idx);
-    }
-
-    public XSSFName getNameAt(int index) {
-       return namedRanges.get(index);
-    }
-    public String getNameName(int index) {
-        return getNameAt(index).getNameName();
-    }
-    public int getNameIndex(String name) {
-       for(int i=0; i<namedRanges.size(); i++) {
-               if(namedRanges.get(i).getNameName().equals(name)) {
-                       return i;
-               }
-       }
-       return -1;
-    }
-
-    public short getNumCellStyles() {
-        return (short) ((StylesTable)stylesSource).getNumCellStyles();
-    }
-
-    public short getNumberOfFonts() {
-        return (short)((StylesTable)stylesSource).getNumberOfFonts();
-    }
-
-    public int getNumberOfNames() {
-        return namedRanges.size();
-    }
-
-    public int getNumberOfSheets() {
-        return this.workbook.getSheets().sizeOfSheetArray();
-    }
-
-    public String getPrintArea(int sheetIndex) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    public short getSelectedTab() {
-        short i = 0;
-        for (XSSFSheet sheet : this.sheets) {
-            if (sheet.isSelected()) {
-                return i;
-            }
-            ++i;
-        }
-        return -1;
-    }
+       public XSSFFont findFont(short boldWeight, short color, short fontHeight, String name, boolean italic, boolean strikeout, short typeOffset, byte underline) {
+               short fontNum=getNumberOfFonts();
+               for (short i = 0; i < fontNum; i++) {
+                       XSSFFont xssfFont = getFontAt(i);
+
+                       if (    (xssfFont.getBold() == (boldWeight == XSSFFont.BOLDWEIGHT_BOLD))
+                                       && xssfFont.getColor() == color
+                                       && xssfFont.getFontHeightInPoints() == fontHeight
+                                       && xssfFont.getFontName().equals(name)
+                                       && xssfFont.getItalic() == italic
+                                       && xssfFont.getStrikeout() == strikeout
+                                       && xssfFont.getTypeOffset() == typeOffset
+                                       && xssfFont.getUnderline() == underline)
+                       {
+                               return xssfFont;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Convenience method to get the active sheet.  The active sheet is is the sheet
+        * which is currently displayed when the workbook is viewed in Excel.
+        * 'Selected' sheet(s) is a distinct concept.
+        */
+       public int getActiveSheetIndex() {
+               //activeTab (Active Sheet Index) Specifies an unsignedInt
+               //that contains the index to the active sheet in this book view.
+               Long index = workbook.getBookViews().getWorkbookViewArray(0).getActiveTab();
+               return index.intValue();
+       }
+
+       public List getAllEmbeddedObjects() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public List<PictureData> getAllPictures() {
+               // In OOXML pictures are referred to in sheets
+               List<PictureData> pictures = new LinkedList<PictureData>();
+               for (CTSheet ctSheet : this.workbook.getSheets().getSheetArray()) {
+                       try {
+                               PackagePart sheetPart = getPackagePart(ctSheet);
+                               if (sheetPart == null) {
+                                       continue;
+                               }
+                               PackageRelationshipCollection prc = sheetPart.getRelationshipsByType(XSSFRelation.DRAWINGS.getRelation());
+                               for (PackageRelationship rel : prc) {
+                                       PackagePart drawingPart = getTargetPart(rel);
+                                       PackageRelationshipCollection prc2 = drawingPart.getRelationshipsByType(XSSFRelation.IMAGES.getRelation());
+                                       for (PackageRelationship rel2 : prc2) {
+                                               PackagePart imagePart = getTargetPart(rel2);
+                                               XSSFPictureData pd = new XSSFPictureData(imagePart);
+                                               pictures.add(pd);
+                                       }
+                               }
+                       } catch (InvalidFormatException e) {
+                               throw new RuntimeException(e.getMessage(), e);
+                       }
+               }
+               return pictures;
+       }
+
+       public boolean getBackupFlag() {
+               // TODO Auto-generated method stub
+               return false;
+       }
+
+       public XSSFCellStyle getCellStyleAt(short idx) {
+               return (XSSFCellStyle)stylesSource.getStyleAt(idx);
+       }
+
+       public Palette getCustomPalette() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public XSSFFont getFontAt(short idx) {
+               return (XSSFFont)stylesSource.getFontAt(idx);
+       }
+
+       public XSSFName getNameAt(int index) {
+               return namedRanges.get(index);
+       }
+       public String getNameName(int index) {
+               return getNameAt(index).getNameName();
+       }
+       public int getNameIndex(String name) {
+               for(int i=0; i<namedRanges.size(); i++) {
+                       if(namedRanges.get(i).getNameName().equals(name)) {
+                               return i;
+                       }
+               }
+               return -1;
+       }
+
+       public short getNumCellStyles() {
+               return (short) ((StylesTable)stylesSource).getNumCellStyles();
+       }
+
+       public short getNumberOfFonts() {
+               return (short)((StylesTable)stylesSource).getNumberOfFonts();
+       }
+
+       public int getNumberOfNames() {
+               return namedRanges.size();
+       }
+
+       public int getNumberOfSheets() {
+               return this.workbook.getSheets().sizeOfSheetArray();
+       }
+
+       public String getPrintArea(int sheetIndex) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public short getSelectedTab() {
+               short i = 0;
+               for (XSSFSheet sheet : this.sheets) {
+                       if (sheet.isSelected()) {
+                               return i;
+                       }
+                       ++i;
+               }
+               return -1;
+       }
 
        public Sheet getSheet(String name) {
-        CTSheet[] sheets = this.workbook.getSheets().getSheetArray();
-        for (int i = 0 ; i < sheets.length ; ++i) {
-            if (name.equals(sheets[i].getName())) {
-                return this.sheets.get(i);
-            }
-        }
-        return null;
-    }
-
-    public XSSFSheet getSheetAt(int index) {
-        return this.sheets.get(index);
-    }
-
-    public int getSheetIndex(String name) {
-        CTSheet[] sheets = this.workbook.getSheets().getSheetArray();
-        for (int i = 0 ; i < sheets.length ; ++i) {
-            if (name.equals(sheets[i].getName())) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-    public int getSheetIndex(Sheet sheet) {
-        return this.sheets.indexOf(sheet);
-    }
-
-    public String getSheetName(int sheet) {
-        return this.workbook.getSheets().getSheetArray(sheet).getName();
-    }
-
-    /**
-     * Are we a normal workbook (.xlsx), or a
-     *  macro enabled workbook (.xlsm)?
-     */
-    public boolean isMacroEnabled() {
-       return isMacroEnabled;
-    }
+               CTSheet[] sheets = this.workbook.getSheets().getSheetArray();
+               for (int i = 0 ; i < sheets.length ; ++i) {
+                       if (name.equals(sheets[i].getName())) {
+                               return this.sheets.get(i);
+                       }
+               }
+               return null;
+       }
+
+       public XSSFSheet getSheetAt(int index) {
+               return this.sheets.get(index);
+       }
+
+       public int getSheetIndex(String name) {
+               CTSheet[] sheets = this.workbook.getSheets().getSheetArray();
+               for (int i = 0 ; i < sheets.length ; ++i) {
+                       if (name.equals(sheets[i].getName())) {
+                               return i;
+                       }
+               }
+               return -1;
+       }
+
+       public int getSheetIndex(Sheet sheet) {
+               return this.sheets.indexOf(sheet);
+       }
+
+       public String getSheetName(int sheet) {
+               return this.workbook.getSheets().getSheetArray(sheet).getName();
+       }
+
+       /**
+        * Are we a normal workbook (.xlsx), or a
+        *  macro enabled workbook (.xlsm)?
+        */
+       public boolean isMacroEnabled() {
+               return isMacroEnabled;
+       }
 
        public void insertChartRecord() {
-        // TODO Auto-generated method stub
+               // TODO Auto-generated method stub
 
-    }
+       }
 
-    public void removeName(int index) {
-        // TODO Auto-generated method stub
+       public void removeName(int index) {
+               // TODO Auto-generated method stub
 
-    }
+       }
 
-    public void removeName(String name) {
-        // TODO Auto-generated method stub
+       public void removeName(String name) {
+               // TODO Auto-generated method stub
 
-    }
+       }
 
-    public void removePrintArea(int sheetIndex) {
-        // TODO Auto-generated method stub
+       public void removePrintArea(int sheetIndex) {
+               // TODO Auto-generated method stub
 
-    }
+       }
 
-    public void removeSheetAt(int index) {
-        this.sheets.remove(index);
-        this.workbook.getSheets().removeSheet(index);
-    }
+       public void removeSheetAt(int index) {
+               this.sheets.remove(index);
+               this.workbook.getSheets().removeSheet(index);
+       }
 
        /**
         * Retrieves the current policy on what to do when
@@ -528,269 +525,268 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook {
                this.missingCellPolicy = missingCellPolicy;
        }
 
-    /**
-     * Convenience method to set the active sheet.  The active sheet is is the sheet
-     * which is currently displayed when the workbook is viewed in Excel.
-     * 'Selected' sheet(s) is a distinct concept.
-     */
-    public void setActiveSheet(int index) {
-
-        validateSheetIndex(index);
-        //activeTab (Active Sheet Index) Specifies an unsignedInt that contains the index to the active sheet in this book view.
-        CTBookView[] arrayBook = workbook.getBookViews().getWorkbookViewArray();
-        for (int i = 0; i < arrayBook.length; i++) {
-            workbook.getBookViews().getWorkbookViewArray(i).setActiveTab(index);
-        }
-    }
-
-    private void validateSheetIndex(int index) {
-        int lastSheetIx = sheets.size() - 1;
-        if (index < 0 || index > lastSheetIx) {
-            throw new IllegalArgumentException("Sheet index ("
-                    + index +") is out of range (0.." +    lastSheetIx + ")");
-        }
-    }
-
-    public void setBackupFlag(boolean backupValue) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /**
-     * Gets the first tab that is displayed in the list of tabs in excel.
-     *
-     * @return integer that contains the index to the active sheet in this book view.
-     */
-    public int getFirstVisibleTab() {
-        CTBookViews bookViews = workbook.getBookViews();
-        CTBookView bookView = bookViews.getWorkbookViewArray(0);
-        return (short) bookView.getActiveTab();
-    }
-
-    /**
-     * Sets the first tab that is displayed in the list of tabs in excel.
-     *
-     * @param index integer that contains the index to the active sheet in this book view.
-     */
-    public void setFirstVisibleTab(int index) {
-        CTBookViews bookViews = workbook.getBookViews();
-        CTBookView bookView= bookViews.getWorkbookViewArray(0);
-        bookView.setActiveTab(index);
-    }
-
-    public void setPrintArea(int sheetIndex, String reference) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void setPrintArea(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void setRepeatingRowsAndColumns(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow) {
-        // TODO Auto-generated method stub
-
-    }
-
-    /**
-     * We only set one sheet as selected for compatibility with HSSF.
-     */
-    public void setSelectedTab(short index) {
-        for (int i = 0 ; i < this.sheets.size() ; ++i) {
-            XSSFSheet sheet = this.sheets.get(i);
-            sheet.setSelected(i == index);
-        }
-    }
-
-    public void setSheetName(int sheet, String name) {
-           if (doesContainsSheetName(name, sheet ))
-               throw new IllegalArgumentException( "The workbook already contains a sheet of this name" );
-        this.workbook.getSheets().getSheetArray(sheet).setName(name);
-    }
-
-    public void setSheetOrder(String sheetname, int pos) {
-        int idx = getSheetIndex(sheetname);
-        sheets.add(pos, sheets.remove(idx));
-        // Reorder CTSheets
-        XmlObject cts = this.workbook.getSheets().getSheetArray(idx).copy();
-        this.workbook.getSheets().removeSheet(idx);
-        CTSheet newcts = this.workbook.getSheets().insertNewSheet(pos);
-        newcts.set(cts);
-    }
-
-    public void unwriteProtectWorkbook() {
-        // TODO Auto-generated method stub
-
-    }
-
-    public void write(OutputStream stream) throws IOException {
-       // What kind of workbook are we?
-       XSSFRelation workbookRelation = XSSFRelation.WORKBOOK;
-       if(isMacroEnabled) {
-               workbookRelation = XSSFRelation.MACROS_WORKBOOK;
-       }
-
-        try {
-            // Create a package referring the temp file.
-            Package pkg = Package.create(stream);
-            // Main part
-            PackagePartName corePartName = PackagingURIHelper.createPartName(workbookRelation.getDefaultFileName());
-            // Create main part relationship
-            int rId = 1;
-            pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT, "rId" + (rId++));
-
-            // Create main document part
-            PackagePart corePart = pkg.createPart(corePartName, workbookRelation.getContentType());
-            OutputStream out;
-
-            XmlOptions xmlOptions = new XmlOptions();
-            // Requests use of whitespace for easier reading
-            xmlOptions.setSavePrettyPrint();
-            xmlOptions.setSaveOuter();
-            xmlOptions.setUseDefaultNamespace();
-
-            // Write out our sheets, updating the references
-            //  to them in the main workbook as we go
-            int drawingIndex = 1;
-            for (int i=0 ; i < this.getNumberOfSheets(); i++) {
-               int sheetNumber = (i+1);
-               XSSFSheet sheet = this.getSheetAt(i);
-                PackagePartName partName = PackagingURIHelper.createPartName(
-                               XSSFRelation.WORKSHEET.getFileName(sheetNumber));
-                PackageRelationship rel =
-                        corePart.addRelationship(partName, TargetMode.INTERNAL, XSSFRelation.WORKSHEET.getRelation(), "rId" + sheetNumber);
-                PackagePart part = pkg.createPart(partName, XSSFRelation.WORKSHEET.getContentType());
-
-                // XXX This should not be needed, but apparently the setSaveOuter call above does not work in XMLBeans 2.2
-                xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorksheet.type.getName().getNamespaceURI(), "worksheet"));
-                sheet.save(part, xmlOptions);
-
-                // Update our internal reference for the package part
-                workbook.getSheets().getSheetArray(i).setId(rel.getId());
-                workbook.getSheets().getSheetArray(i).setSheetId(sheetNumber);
-
-                // If our sheet has drawings, then write out those
-                if(sheet.getDrawings() != null) {
-                       for(Drawing drawing : sheet.getDrawings()) {
-                               XSSFRelation.VML_DRAWINGS.save(
-                                               drawing,
-                                               part,
-                                               drawingIndex
-                               );
-                               drawingIndex++;
-                       }
-                }
-
-                // If our sheet has comments, then write out those
-                if(sheet.hasComments()) {
-                       CommentsTable ct = (CommentsTable)sheet.getCommentsSourceIfExists();
-                       XSSFRelation.SHEET_COMMENTS.save(ct, part, sheetNumber);
-                }
-
-                // If our sheet has controls, then write out those
-                if(sheet.getControls() != null) {
-                       int controlIndex = 1;
-                       for(Control control : sheet.getControls()) {
-                               XSSFRelation.ACTIVEX_CONTROLS.save(
-                                               control,
-                                               part,
-                                               controlIndex
-                               );
-                               controlIndex++;
-                       }
-                }
-            }
-
-            // Write shared strings and styles
-            if(sharedStringSource != null) {
-                    SharedStringsTable sst = (SharedStringsTable)sharedStringSource;
-                    XSSFRelation.SHARED_STRINGS.save(sst, corePart);
-            }
-            if(stylesSource != null) {
-                    StylesTable st = (StylesTable)stylesSource;
-                    XSSFRelation.STYLES.save(st, corePart);
-            }
-            if(themes.size() > 0) {
-                for(int i=0; i< themes.size(); i++) {
-                    XSSFRelation.THEME.save(themes.get(i), corePart, i+1);
-                }
-            }
-
-            // Named ranges
-            if(namedRanges.size() > 0) {
-               CTDefinedNames names = CTDefinedNames.Factory.newInstance();
-               CTDefinedName[] nr = new CTDefinedName[namedRanges.size()];
-               for(int i=0; i<namedRanges.size(); i++) {
-                       nr[i] = namedRanges.get(i).getCTName();
-               }
-               names.setDefinedNameArray(nr);
-               workbook.setDefinedNames(names);
-            } else {
-               if(workbook.isSetDefinedNames()) {
-                       workbook.setDefinedNames(null);
-               }
-            }
-
-            // Macro related bits
-            if(isMacroEnabled) {
-                   // Copy VBA Macros if present
-                   if(XSSFRelation.VBA_MACROS.exists( getCorePart() )) {
-                       try {
-                               XSSFModel vba = XSSFRelation.VBA_MACROS.load(getCorePart());
-                               XSSFRelation.VBA_MACROS.save(vba, corePart);
-                       } catch(Exception e) {
-                               throw new RuntimeException("Unable to copy vba macros over", e);
-                       }
-                   }
-            }
-
-            // Now we can write out the main Workbook, with
-            //  the correct references to the other parts
-            out = corePart.getOutputStream();
-            // XXX This should not be needed, but apparently the setSaveOuter call above does not work in XMLBeans 2.2
-            xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorkbook.type.getName().getNamespaceURI(), "workbook"));
-            workbook.save(out, xmlOptions);
-            out.close();
-
-            //  All done
-            pkg.close();
-        } catch (InvalidFormatException e) {
-            // TODO: replace with more meaningful exception
-            throw new RuntimeException(e);
-        }
-    }
-
-    public void writeProtectWorkbook(String password, String username) {
-        // TODO Auto-generated method stub
-
-    }
-
-    public SharedStringSource getSharedStringSource() {
-        return this.sharedStringSource;
-    }
-    protected void setSharedStringSource(SharedStringSource sharedStringSource) {
-        this.sharedStringSource = sharedStringSource;
-    }
-
-    public StylesSource getStylesSource() {
-       return this.stylesSource;
-    }
-    protected void setStylesSource(StylesSource stylesSource) {
-       this.stylesSource = stylesSource;
-    }
-
-    public CreationHelper getCreationHelper() {
-       return new XSSFCreationHelper(this);
-    }
-
-    private boolean doesContainsSheetName(String name, int excludeSheetIdx) {
-        CTSheet[] ctSheetArray = workbook.getSheets().getSheetArray();
-        for (int i = 0; i < ctSheetArray.length; i++) {
-            if (excludeSheetIdx != i && name.equalsIgnoreCase(ctSheetArray[i].getName()))
-                return true;
-        }
-        return false;
-    }
+       /**
+        * Convenience method to set the active sheet.  The active sheet is is the sheet
+        * which is currently displayed when the workbook is viewed in Excel.
+        * 'Selected' sheet(s) is a distinct concept.
+        */
+       public void setActiveSheet(int index) {
+
+               validateSheetIndex(index);
+               //activeTab (Active Sheet Index) Specifies an unsignedInt that contains the index to the active sheet in this book view.
+               CTBookView[] arrayBook = workbook.getBookViews().getWorkbookViewArray();
+               for (int i = 0; i < arrayBook.length; i++) {
+                       workbook.getBookViews().getWorkbookViewArray(i).setActiveTab(index);
+               }
+       }
+
+       private void validateSheetIndex(int index) {
+               int lastSheetIx = sheets.size() - 1;
+               if (index < 0 || index > lastSheetIx) {
+                       throw new IllegalArgumentException("Sheet index ("
+                                       + index +") is out of range (0.." +     lastSheetIx + ")");
+               }
+       }
+
+       public void setBackupFlag(boolean backupValue) {
+               // TODO Auto-generated method stub
 
+       }
+
+       /**
+        * Gets the first tab that is displayed in the list of tabs in excel.
+        *
+        * @return integer that contains the index to the active sheet in this book view.
+        */
+       public int getFirstVisibleTab() {
+               CTBookViews bookViews = workbook.getBookViews();
+               CTBookView bookView = bookViews.getWorkbookViewArray(0);
+               return (short) bookView.getActiveTab();
+       }
+
+       /**
+        * Sets the first tab that is displayed in the list of tabs in excel.
+        *
+        * @param index integer that contains the index to the active sheet in this book view.
+        */
+       public void setFirstVisibleTab(int index) {
+               CTBookViews bookViews = workbook.getBookViews();
+               CTBookView bookView= bookViews.getWorkbookViewArray(0);
+               bookView.setActiveTab(index);
+       }
+
+       public void setPrintArea(int sheetIndex, String reference) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void setPrintArea(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void setRepeatingRowsAndColumns(int sheetIndex, int startColumn, int endColumn, int startRow, int endRow) {
+               // TODO Auto-generated method stub
+
+       }
+
+       /**
+        * We only set one sheet as selected for compatibility with HSSF.
+        */
+       public void setSelectedTab(short index) {
+               for (int i = 0 ; i < this.sheets.size() ; ++i) {
+                       XSSFSheet sheet = this.sheets.get(i);
+                       sheet.setSelected(i == index);
+               }
+       }
+
+       public void setSheetName(int sheet, String name) {
+               if (doesContainsSheetName(name, sheet ))
+                       throw new IllegalArgumentException( "The workbook already contains a sheet of this name" );
+               this.workbook.getSheets().getSheetArray(sheet).setName(name);
+       }
+
+       public void setSheetOrder(String sheetname, int pos) {
+               int idx = getSheetIndex(sheetname);
+               sheets.add(pos, sheets.remove(idx));
+               // Reorder CTSheets
+               XmlObject cts = this.workbook.getSheets().getSheetArray(idx).copy();
+               this.workbook.getSheets().removeSheet(idx);
+               CTSheet newcts = this.workbook.getSheets().insertNewSheet(pos);
+               newcts.set(cts);
+       }
+
+       public void unwriteProtectWorkbook() {
+               // TODO Auto-generated method stub
+
+       }
+
+       public void write(OutputStream stream) throws IOException {
+               // What kind of workbook are we?
+               XSSFRelation workbookRelation = XSSFRelation.WORKBOOK;
+               if(isMacroEnabled) {
+                       workbookRelation = XSSFRelation.MACROS_WORKBOOK;
+               }
+
+               try {
+                       // Create a package referring the temp file.
+                       Package pkg = Package.create(stream);
+                       // Main part
+                       PackagePartName corePartName = PackagingURIHelper.createPartName(workbookRelation.getDefaultFileName());
+                       // Create main part relationship
+                       int rId = 1;
+                       pkg.addRelationship(corePartName, TargetMode.INTERNAL, PackageRelationshipTypes.CORE_DOCUMENT, "rId" + (rId++));
+
+                       // Create main document part
+                       PackagePart corePart = pkg.createPart(corePartName, workbookRelation.getContentType());
+                       OutputStream out;
+
+                       XmlOptions xmlOptions = new XmlOptions();
+                       // Requests use of whitespace for easier reading
+                       xmlOptions.setSavePrettyPrint();
+                       xmlOptions.setSaveOuter();
+                       xmlOptions.setUseDefaultNamespace();
+
+                       // Write out our sheets, updating the references
+                       //  to them in the main workbook as we go
+                       int drawingIndex = 1;
+                       for (int i=0 ; i < this.getNumberOfSheets(); i++) {
+                               int sheetNumber = (i+1);
+                               XSSFSheet sheet = this.getSheetAt(i);
+                               PackagePartName partName = PackagingURIHelper.createPartName(
+                                               XSSFRelation.WORKSHEET.getFileName(sheetNumber));
+                               PackageRelationship rel =
+                                        corePart.addRelationship(partName, TargetMode.INTERNAL, XSSFRelation.WORKSHEET.getRelation(), "rId" + sheetNumber);
+                               PackagePart part = pkg.createPart(partName, XSSFRelation.WORKSHEET.getContentType());
+
+                               // XXX This should not be needed, but apparently the setSaveOuter call above does not work in XMLBeans 2.2
+                               xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorksheet.type.getName().getNamespaceURI(), "worksheet"));
+                               sheet.save(part, xmlOptions);
+
+                               // Update our internal reference for the package part
+                               workbook.getSheets().getSheetArray(i).setId(rel.getId());
+                               workbook.getSheets().getSheetArray(i).setSheetId(sheetNumber);
+
+                               // If our sheet has drawings, then write out those
+                               if(sheet.getDrawings() != null) {
+                                       for(Drawing drawing : sheet.getDrawings()) {
+                                               XSSFRelation.VML_DRAWINGS.save(
+                                                               drawing,
+                                                               part,
+                                                               drawingIndex
+                                               );
+                                               drawingIndex++;
+                                       }
+                               }
+
+                               // If our sheet has comments, then write out those
+                               if(sheet.hasComments()) {
+                                       CommentsTable ct = (CommentsTable)sheet.getCommentsSourceIfExists();
+                                       XSSFRelation.SHEET_COMMENTS.save(ct, part, sheetNumber);
+                               }
+
+                               // If our sheet has controls, then write out those
+                               if(sheet.getControls() != null) {
+                                       int controlIndex = 1;
+                                       for(Control control : sheet.getControls()) {
+                                               XSSFRelation.ACTIVEX_CONTROLS.save(
+                                                               control,
+                                                               part,
+                                                               controlIndex
+                                               );
+                                               controlIndex++;
+                                       }
+                               }
+                       }
+
+                       // Write shared strings and styles
+                       if(sharedStringSource != null) {
+                                SharedStringsTable sst = (SharedStringsTable)sharedStringSource;
+                                XSSFRelation.SHARED_STRINGS.save(sst, corePart);
+                       }
+                       if(stylesSource != null) {
+                                StylesTable st = (StylesTable)stylesSource;
+                                XSSFRelation.STYLES.save(st, corePart);
+                       }
+                       if(themes.size() > 0) {
+                               for(int i=0; i< themes.size(); i++) {
+                                       XSSFRelation.THEME.save(themes.get(i), corePart, i+1);
+                               }
+                       }
+
+                       // Named ranges
+                       if(namedRanges.size() > 0) {
+                               CTDefinedNames names = CTDefinedNames.Factory.newInstance();
+                               CTDefinedName[] nr = new CTDefinedName[namedRanges.size()];
+                               for(int i=0; i<namedRanges.size(); i++) {
+                                       nr[i] = namedRanges.get(i).getCTName();
+                               }
+                               names.setDefinedNameArray(nr);
+                               workbook.setDefinedNames(names);
+                       } else {
+                               if(workbook.isSetDefinedNames()) {
+                                       workbook.setDefinedNames(null);
+                               }
+                       }
+
+                       // Macro related bits
+                       if(isMacroEnabled) {
+                               // Copy VBA Macros if present
+                               if(XSSFRelation.VBA_MACROS.exists( getCorePart() )) {
+                                       try {
+                                               BinaryPart vba = XSSFRelation.VBA_MACROS.load(getCorePart());
+                                               XSSFRelation.VBA_MACROS.save(vba, corePart);
+                                       } catch(Exception e) {
+                                               throw new RuntimeException("Unable to copy vba macros over", e);
+                                       }
+                               }
+                       }
+
+                       // Now we can write out the main Workbook, with
+                       //  the correct references to the other parts
+                       out = corePart.getOutputStream();
+                       // XXX This should not be needed, but apparently the setSaveOuter call above does not work in XMLBeans 2.2
+                       xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorkbook.type.getName().getNamespaceURI(), "workbook"));
+                       workbook.save(out, xmlOptions);
+                       out.close();
+
+                       //  All done
+                       pkg.close();
+               } catch (InvalidFormatException e) {
+                       // TODO: replace with more meaningful exception
+                       throw new RuntimeException(e);
+               }
+       }
+
+       public void writeProtectWorkbook(String password, String username) {
+               // TODO Auto-generated method stub
+
+       }
+
+       public SharedStringSource getSharedStringSource() {
+               return this.sharedStringSource;
+       }
+       protected void setSharedStringSource(SharedStringSource sharedStringSource) {
+               this.sharedStringSource = sharedStringSource;
+       }
+
+       public StylesSource getStylesSource() {
+               return this.stylesSource;
+       }
+       protected void setStylesSource(StylesSource stylesSource) {
+               this.stylesSource = stylesSource;
+       }
+
+       public CreationHelper getCreationHelper() {
+               return new XSSFCreationHelper(this);
+       }
+
+       private boolean doesContainsSheetName(String name, int excludeSheetIdx) {
+               CTSheet[] ctSheetArray = workbook.getSheets().getSheetArray();
+               for (int i = 0; i < ctSheetArray.length; i++) {
+                       if (excludeSheetIdx != i && name.equalsIgnoreCase(ctSheetArray[i].getName()))
+                               return true;
+               }
+               return false;
+       }
 }