git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@993246 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_7_BETA3
@@ -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> |
@@ -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; |
@@ -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"); |