]> source.dussan.org Git - poi.git/commitdiff
A partial fix for bug #30978, but something still remains, which seems to be related...
authorNick Burch <nick@apache.org>
Wed, 18 Jun 2008 11:35:04 +0000 (11:35 +0000)
committerNick Burch <nick@apache.org>
Wed, 18 Jun 2008 11:35:04 +0000 (11:35 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@669140 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/poi/hssf/model/Workbook.java
src/testcases/org/apache/poi/hssf/data/30978-alt.xls [new file with mode: 0644]
src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java

index 5b38935f4c593d38cc4858ae4686e4b675212c29..fa22cfb6889161f94b5d25ff75caf828d251bf1a 100644 (file)
@@ -604,8 +604,28 @@ public class Workbook implements Model
             fixTabIdRecord();
         }
         
-        // If we decide that we need to fix up
-        //  NameRecords, do it here
+        // Within NameRecords, it's ok to have the formula
+        //  part point at deleted sheets. It's also ok to
+        //  have the ExternSheetNumber point at deleted
+        //  sheets. 
+        // However, the sheet index must be adjusted, or
+        //  excel will break. (Sheet index is either 0 for
+        //  global, or 1 based index to sheet)
+        int sheetNum1Based = sheetnum + 1;
+        for(int i=0; i<getNumNames(); i++) {
+               NameRecord nr = getNameRecord(i);
+               
+               if(nr.getIndexToSheet() == sheetNum1Based) {
+                       // Excel re-writes these to point to no sheet
+                       nr.setEqualsToIndexToSheet((short)0);
+               } else if(nr.getIndexToSheet() > sheetNum1Based) {
+                       // Bump down by one, so still points
+                       //  at the same sheet
+                       nr.setEqualsToIndexToSheet((short)(
+                                       nr.getEqualsToIndexToSheet()-1
+                       ));
+               }
+        }
     }
 
     /**
diff --git a/src/testcases/org/apache/poi/hssf/data/30978-alt.xls b/src/testcases/org/apache/poi/hssf/data/30978-alt.xls
new file mode 100644 (file)
index 0000000..c591582
Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/30978-alt.xls differ
index cbe175a0e3bba0446be779c87b3a72eb5b67892d..ab247b7c8a336039c58fd56b58ba79cf6fcc328a 100644 (file)
@@ -28,7 +28,10 @@ import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
 
 import org.apache.poi.hssf.HSSFTestDataSamples;
+import org.apache.poi.hssf.model.Workbook;
 import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord;
+import org.apache.poi.hssf.record.NameRecord;
+import org.apache.poi.hssf.record.formula.DeletedArea3DPtg;
 import org.apache.poi.hssf.util.Region;
 import org.apache.poi.util.TempFile;
 
@@ -989,4 +992,63 @@ public final class TestBugs extends TestCase {
                fail();
         } catch(FileNotFoundException e) {}
     }
+    
+    /**
+     * Test that we can delete sheets without
+     *  breaking the build in named ranges
+     *  used for printing stuff.
+     * Currently broken, as we change the Ptg
+     */
+    public void BROKENtest30978() throws Exception {
+        HSSFWorkbook wb = openSample("30978-alt.xls");
+        assertEquals(1, wb.getNumberOfNames());
+        assertEquals(3, wb.getNumberOfSheets());
+        
+        // Check all names fit within range, and use
+        //  DeletedArea3DPtg
+        Workbook w = wb.getWorkbook();
+        for(int i=0; i<w.getNumNames(); i++) {
+               NameRecord r = w.getNameRecord(i);
+               assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
+               
+               List nd = r.getNameDefinition();
+               assertEquals(1, nd.size());
+               assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
+        }
+        
+        
+        // Delete the 2nd sheet
+        wb.removeSheetAt(1);
+        
+        
+        // Re-check
+        assertEquals(1, wb.getNumberOfNames());
+        assertEquals(2, wb.getNumberOfSheets());
+        
+        for(int i=0; i<w.getNumNames(); i++) {
+               NameRecord r = w.getNameRecord(i);
+               assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
+               
+               List nd = r.getNameDefinition();
+               assertEquals(1, nd.size());
+               assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
+        }
+        
+        
+        // Save and re-load
+        wb = writeOutAndReadBack(wb);
+        w = wb.getWorkbook();
+        
+        assertEquals(1, wb.getNumberOfNames());
+        assertEquals(2, wb.getNumberOfSheets());
+        
+        for(int i=0; i<w.getNumNames(); i++) {
+               NameRecord r = w.getNameRecord(i);
+               assertTrue(r.getIndexToSheet() <= wb.getNumberOfSheets());
+               
+               List nd = r.getNameDefinition();
+               assertEquals(1, nd.size());
+               assertTrue(nd.get(0) instanceof DeletedArea3DPtg);
+        }
+    }
 }