Bug 46885

Summary: [Patch] - setting cached formula result corrupts workbook
Product: POI Reporter: Josh Micich <josh>
Component: XSSFAssignee: POI Developers List <dev>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 3.5-dev   
Target Milestone: ---   
Hardware: All   
OS: All   
URL: http://mail-archives.apache.org/mod_mbox/poi-user/200903.mbox/<20090320192839.7F44F2700@courageux.xo.com>

Description Josh Micich 2009-03-21 13:50:12 UTC
This bug was created due to the poi-user posting by Paul Dobson on Mar 20.

The following code will cause Excel to report the workbook as corrupted, and attempt a repair on it:

String xlsxFilePath = "empty.xlsx";
FileInputStream in = new FileInputStream(xlsxFilePath);
Workbook wb = WorkbookFactory.create(in);
Sheet sh = wb.getSheet("Sheet1");
Row row = sh.createRow(1);
Cell cell = row.createCell(1);
cell.setCellFormula("NA()");
cell.setCellValue("Help, I will not change!"); //corrupts workbook
in.close();
FileOutputStream out = new FileOutputStream("out.xlsx");
wb.write(out);
out.close();


With some investigation, I found that Excel is missing the type attribute from the following XML fragment:
<c r="B2">
  <f>NA()</f>
  <v>Help, I will not change!</v>
</c>

By adding 't="str"' (as follows) the workbook opens properly.
<c r="B2" t="str">
  <f>NA()</f>
  <v>Help, I will not change!</v>
</c>


Here is a patch that seems to have the desired effect.  Can someone review please?

$ svn diff src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
Index: src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java
===================================================================
--- src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java  (revision 755692)
+++ src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCell.java  (working copy)
@@ -217,6 +217,7 @@
             case CELL_TYPE_ERROR:
             case CELL_TYPE_FORMULA:
                 cell.setV(String.valueOf(value));
+                cell.setT(STCellType.N);
                 break;
             default:
                 cell.setT(STCellType.N);
@@ -303,6 +304,7 @@
         switch(cellType){
             case Cell.CELL_TYPE_FORMULA:
                 cell.setV(str.getString());
+                cell.setT(STCellType.STR);
                 break;
             default:
                 if(cell.getT() == STCellType.INLINE_STR) {
Comment 1 Yegor Kozlov 2009-03-22 08:14:57 UTC
Good catch, Josh!

fixed in r757198

Thanks,
Yegor