From fa249495207b19593937d427193fc91bb2b0b046 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Wed, 27 Jul 2016 18:15:54 +0000 Subject: [PATCH] Bug 55384: Handle setting pre-evaluation string correctly in SXSSF as well git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1754328 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/xssf/streaming/SXSSFCell.java | 12 ++- .../ss/usermodel/BaseTestBugzillaIssues.java | 79 ++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java index 6c6574443..e6994b8de 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFCell.java @@ -338,7 +338,11 @@ public class SXSSFCell implements Cell { } if(_value.getType()==CellType.FORMULA) - ((StringFormulaValue)_value).setPreEvaluatedValue(value); + if(_value instanceof NumericFormulaValue) { + ((NumericFormulaValue) _value).setPreEvaluatedValue(Double.parseDouble(value)); + } else { + ((StringFormulaValue) _value).setPreEvaluatedValue(value); + } else ((PlainStringValue)_value).setValue(value); } else { @@ -956,6 +960,7 @@ public class SXSSFCell implements Cell { } /*package*/ void setFormulaType(CellType type) { + Value prevValue = _value; switch(type) { case NUMERIC: @@ -983,6 +988,11 @@ public class SXSSFCell implements Cell { throw new IllegalArgumentException("Illegal type " + type); } } + + // if we had a Formula before, we should copy over the _value of the formula + if(prevValue instanceof FormulaValue) { + ((FormulaValue)_value)._value = ((FormulaValue)prevValue)._value; + } } //TODO: implement this correctly @NotImplemented diff --git a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java index a832635c1..bdd09bfd6 100644 --- a/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java +++ b/src/testcases/org/apache/poi/ss/usermodel/BaseTestBugzillaIssues.java @@ -33,9 +33,12 @@ import java.awt.font.FontRenderContext; import java.awt.font.TextAttribute; import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; +import java.io.FileInputStream; import java.io.IOException; import java.text.AttributedString; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.junit.Assert.*; @@ -1606,4 +1609,78 @@ public abstract class BaseTestBugzillaIssues { assertNull("Sheet0 after write", wb2.getPrintArea(0)); // CURRENTLY FAILS with "Sheet0!$A$1:$C$6" assertEquals("Sheet1 after write", "Sheet1!$A$1:$A$1", wb2.getPrintArea(1)); } -} + + + @Test + public void test55384() throws Exception { + Workbook wb = _testDataProvider.createWorkbook(); + try { + Sheet sh = wb.createSheet(); + for (int rownum = 0; rownum < 10; rownum++) { + org.apache.poi.ss.usermodel.Row row = sh.createRow(rownum); + for (int cellnum = 0; cellnum < 3; cellnum++) { + Cell cell = row.createCell(cellnum); + cell.setCellValue(rownum + cellnum); + } + } + Row row = sh.createRow(10); + // setting no precalculated value works just fine. + Cell cell1 = row.createCell(0); + cell1.setCellFormula("SUM(A1:A10)"); + + // but setting a precalculated STRING value fails totally in SXSSF + Cell cell2 = row.createCell(1); + cell2.setCellFormula("SUM(B1:B10)"); + cell2.setCellValue("55"); + + // setting a precalculated int value works as expected + Cell cell3 = row.createCell(2); + cell3.setCellFormula("SUM(C1:C10)"); + cell3.setCellValue(65); + + assertEquals(CellType.FORMULA, cell1.getCellTypeEnum()); + assertEquals(CellType.FORMULA, cell2.getCellTypeEnum()); + assertEquals(CellType.FORMULA, cell3.getCellTypeEnum()); + + assertEquals("SUM(A1:A10)", cell1.getCellFormula()); + assertEquals("SUM(B1:B10)", cell2.getCellFormula()); + assertEquals("SUM(C1:C10)", cell3.getCellFormula()); + + /*String name = wb.getClass().getCanonicalName(); + String ext = (wb instanceof HSSFWorkbook) ? ".xls" : ".xlsx"; + OutputStream output = new FileOutputStream("/tmp" + name + ext); + try { + wb.write(output); + } finally { + output.close(); + }*/ + + Workbook wbBack = _testDataProvider.writeOutAndReadBack(wb); + checkFormulaPreevaluatedString(wbBack); + wbBack.close(); + } finally { + wb.close(); + } + } + + private void checkFormulaPreevaluatedString(Workbook readFile) { + Sheet sheet = readFile.getSheetAt(0); + Row row = sheet.getRow(sheet.getLastRowNum()); + assertEquals(10, row.getRowNum()); + + for (Cell cell : row) { + String cellValue = null; + switch (cell.getCellTypeEnum()) { + case STRING: + cellValue = cell.getRichStringCellValue().getString(); + break; + case FORMULA: + cellValue = cell.getCellFormula(); + break; + } + assertNotNull(cellValue); + cellValue = cellValue.isEmpty() ? null : cellValue; + assertNotNull(cellValue); + } + } +} \ No newline at end of file