diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 0bfd8534e..b72f05ebe 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 53404 - Fixed compatibility bug with modifying xls files created by POI-3.6 and earlier 53979 - Support fetching properties of Numbered Lists from PPT files 53784 - Partial HSMF support for fixed sized properties 53943 - added method processSymbol() to allow converting word symbols diff --git a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java index 88b9d63ef..a989c32b9 100644 --- a/src/java/org/apache/poi/hssf/model/InternalWorkbook.java +++ b/src/java/org/apache/poi/hssf/model/InternalWorkbook.java @@ -740,15 +740,6 @@ public final class InternalWorkbook { boundsheets.add(bsr); getOrCreateLinkTable().checkExternSheet(sheetnum); fixTabIdRecord(); - } else { - // Ensure we have enough tab IDs - // Can be a few short if new sheets were added - if(records.getTabpos() > 0) { - TabIdRecord tir = ( TabIdRecord ) records.get(records.getTabpos()); - if(tir._tabids.length < boundsheets.size()) { - fixTabIdRecord(); - } - } } } @@ -787,15 +778,19 @@ public final class InternalWorkbook { /** * make the tabid record look like the current situation. * + * @return number of bytes written in the TabIdRecord */ - private void fixTabIdRecord() { + private int fixTabIdRecord() { TabIdRecord tir = ( TabIdRecord ) records.get(records.getTabpos()); + int sz = tir.getRecordSize(); short[] tia = new short[ boundsheets.size() ]; for (short k = 0; k < tia.length; k++) { tia[ k ] = k; } tir.setTabIdArray(tia); + return tir.getRecordSize() - sz; + } /** @@ -1066,6 +1061,22 @@ public final class InternalWorkbook { return pos; } + /** + * Perform any work necessary before the workbook is about to be serialized. + * + * Include in it ant code that modifies the workbook record stream and affects its size. + */ + public void preSerialize(){ + // Ensure we have enough tab IDs + // Can be a few short if new sheets were added + if(records.getTabpos() > 0) { + TabIdRecord tir = ( TabIdRecord ) records.get(records.getTabpos()); + if(tir._tabids.length < boundsheets.size()) { + fixTabIdRecord(); + } + } + } + public int getSize() { int retval = 0; diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java index add83e7e6..c21877588 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFWorkbook.java @@ -1241,8 +1241,10 @@ public final class HSSFWorkbook extends POIDocument implements org.apache.poi.ss HSSFSheet[] sheets = getSheets(); int nSheets = sheets.length; + // before getting the workbook size we must tell the sheets that // serialization is about to occur. + workbook.preSerialize(); for (int i = 0; i < nSheets; i++) { sheets[i].getSheet().preSerialize(); sheets[i].preSerialize(); diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 8f4a4ec65..7dd8591b8 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -40,10 +40,7 @@ import org.apache.poi.ss.usermodel.*; import org.apache.poi.util.TempFile; import java.io.*; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; +import java.util.*; /** * Testcases for bugs entered in bugzilla @@ -2297,4 +2294,23 @@ if(1==2) { wb = writeOutAndReadBack((HSSFWorkbook) wb); } + + public void test53404(){ + Workbook wb = openSample("53404.xls"); + Sheet sheet = wb.getSheet("test-sheet"); + int rowCount = sheet.getLastRowNum() + 1; + int newRows = 5; + for (int r = rowCount; r < rowCount + newRows; r++) { + Row row = sheet.createRow((short) r); + row.createCell(0).setCellValue(1.03 * (r + 7)); + row.createCell(1).setCellValue(new Date()); + row.createCell(2).setCellValue(Calendar.getInstance()); + row.createCell(3).setCellValue(String.format("row:%d/col:%d", r, 3)); + row.createCell(4).setCellValue(true); + row.createCell(5).setCellType(Cell.CELL_TYPE_ERROR); + row.createCell(6).setCellValue("added cells."); + } + + wb = writeOutAndReadBack((HSSFWorkbook) wb); + } } diff --git a/test-data/spreadsheet/53404.xls b/test-data/spreadsheet/53404.xls new file mode 100644 index 000000000..d436e1e86 Binary files /dev/null and b/test-data/spreadsheet/53404.xls differ