]> source.dussan.org Git - poi.git/commitdiff
allow sheet names longer than 31 chars in XSSF, enforce name uniqueness on the first...
authorYegor Kozlov <yegor@apache.org>
Tue, 7 Sep 2010 07:09:49 +0000 (07:09 +0000)
committerYegor Kozlov <yegor@apache.org>
Tue, 7 Sep 2010 07:09:49 +0000 (07:09 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@993246 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java

index cac2afc44905bb54197fb8d2ffd7be4ca60885cd..135bb70d55027cee53d59694621152f5984e2a69 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.7-beta3" date="2010-??-??">
+           <action dev="poi-developers" type="fix">49887 - allow sheet names longer than 31 chars in XSSF, enforce name uniqueness on the first 31 chars</action>
            <action dev="poi-developers" type="fix">49878 - improved API for hiding sheets</action>
            <action dev="poi-developers" type="fix">49875 - fixed  XSSFWorkbook.createSheet to throw exception if sheet name begins or ends with a single quote (')</action>
            <action dev="poi-developers" type="fix">49873 - fixed  XSSFFormulaEvaluator to support blank cells</action>
index 71a42677bb0058e30690a2ac2565b33f1f59ca9a..42ce4bcb87c743e177b408e7856dfb521b1c1c94 100644 (file)
@@ -89,6 +89,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
      */
     public static final float DEFAULT_CHARACTER_WIDTH = 7.0017f;
 
+    /**
+     * Excel silently truncates long sheet names to 31 chars.
+     * This constant is used to ensure uniqueness in the first 31 chars
+     */
+    private static final int MAX_SENSITIVE_SHEET_NAME_LEN = 31;
+
     /**
      * The underlying XML bean
      */
@@ -1216,6 +1222,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
 
     /**
      * Determines whether a workbook contains the provided sheet name.
+     * For the purpose of comparison, long names are truncated to 31 chars.
      *
      * @param name the name to test (case insensitive match)
      * @param excludeSheetIdx the sheet to exclude from the check or -1 to include all sheets in the check.
@@ -1225,8 +1232,17 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
         CTSheet[] ctSheetArray = new CTSheet[workbook.getSheets().getSheetList().size()];
         workbook.getSheets().getSheetList().toArray(ctSheetArray);
         
+        if (name.length() > MAX_SENSITIVE_SHEET_NAME_LEN) {
+            name = name.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN);
+        }
+
         for (int i = 0; i < ctSheetArray.length; i++) {
-            if (excludeSheetIdx != i && name.equalsIgnoreCase(ctSheetArray[i].getName()))
+            String ctName = ctSheetArray[i].getName();
+            if (ctName.length() > MAX_SENSITIVE_SHEET_NAME_LEN) {
+                ctName = ctName.substring(0, MAX_SENSITIVE_SHEET_NAME_LEN);
+            }
+
+            if (excludeSheetIdx != i && name.equalsIgnoreCase(ctName))
                 return true;
         }
         return false;
index 67abf51b537d558ea76e30d4bdeda06af7e4b9ba..ba733d068a488e1021b62f5b56480e9723024d88 100644 (file)
@@ -114,6 +114,44 @@ public abstract class BaseTestWorkbook extends TestCase {
         assertEquals(2, wb.getSheetIndex("I changed!"));
     }
 
+    /**
+     * POI allows creating sheets with names longer than 31 characters.
+     *
+     * Excel opens files with long sheet names without error or warning.
+     * However, long sheet names are silently truncated to 31 chars.  In order to
+     * avoid funny duplicate sheet name errors, POI enforces uniqueness on only the first 31 chars.
+     * but for the purpose of uniqueness long sheet names are silently truncated to 31 chars.
+     */
+    public final void testCreateSheetWithLongNames() {
+        Workbook wb = _testDataProvider.createWorkbook();
+
+        String sheetName1 = "My very long sheet name which is longer than 31 chars";
+        Sheet sh1 = wb.createSheet(sheetName1);
+        assertEquals(sheetName1, sh1.getSheetName());
+        assertSame(sh1, wb.getSheet(sheetName1));
+
+        String sheetName2 = "My very long sheet name which is longer than 31 chars " +
+                "and sheetName2.substring(0, 31) == sheetName1.substring(0, 31)";
+        try {
+            Sheet sh2 = wb.createSheet(sheetName2);
+            fail("expected exception");
+        } catch (IllegalArgumentException e) {
+            // expected during successful test
+            assertEquals("The workbook already contains a sheet of this name", e.getMessage());
+        }
+
+        String sheetName3 = "POI allows creating sheets with names longer than 31 characters";
+        Sheet sh3 = wb.createSheet(sheetName3);
+        assertEquals(sheetName3, sh3.getSheetName());
+        assertSame(sh3, wb.getSheet(sheetName3));
+
+        //serialize and read again
+        wb = _testDataProvider.writeOutAndReadBack(wb);
+        assertEquals(2, wb.getNumberOfSheets());
+        assertEquals(0, wb.getSheetIndex(sheetName1));
+        assertEquals(1, wb.getSheetIndex(sheetName3));
+    }
+
     public final void testRemoveSheetAt() {
         Workbook workbook = _testDataProvider.createWorkbook();
         workbook.createSheet("sheet1");