From 05593e6902ea5e75b6fa3cf1346818453576a1af Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Tue, 7 Sep 2010 07:09:49 +0000 Subject: [PATCH] allow sheet names longer than 31 chars in XSSF, enforce name uniqueness on the first 31 chars git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@993246 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../poi/xssf/usermodel/XSSFWorkbook.java | 18 ++++++++- .../poi/ss/usermodel/BaseTestWorkbook.java | 38 +++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index cac2afc44..135bb70d5 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 49887 - allow sheet names longer than 31 chars in XSSF, enforce name uniqueness on the first 31 chars 49878 - improved API for hiding sheets 49875 - fixed XSSFWorkbook.createSheet to throw exception if sheet name begins or ends with a single quote (') 49873 - fixed XSSFFormulaEvaluator to support blank cells diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java index 71a42677b..42ce4bcb8 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java @@ -89,6 +89,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable 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; diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java index 67abf51b5..ba733d068 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestWorkbook.java @@ -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");