diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index 808bea2a9..f6f0bce1a 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -37,6 +37,7 @@ + Fix cell.getRichStringCellValue() for formula cells with string results 45365 - Handle more excel number formatting rules in FormatTrackingHSSFListener / XLS2CSVmra 45373 - Improve the performance of HSSFSheet.shiftRows 45367 - Fixed bug when last row removed from sheet is row zero diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 21d279ada..4e95db323 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + Fix cell.getRichStringCellValue() for formula cells with string results 45365 - Handle more excel number formatting rules in FormatTrackingHSSFListener / XLS2CSVmra 45373 - Improve the performance of HSSFSheet.shiftRows 45367 - Fixed bug when last row removed from sheet is row zero diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 7d2a53d20..dd1770f56 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -601,13 +601,28 @@ public class HSSFCell // Set the 'pre-evaluated result' for the formula // note - formulas do not preserve text formatting. FormulaRecordAggregate fr = (FormulaRecordAggregate) record; - // must make new sr because fr.getStringRecord() may be null - StringRecord sr = new StringRecord(); - sr.setString(value.getString()); // looses format - fr.setStringRecord(sr); + + // Save the string into a String Record, creating + // one if required + StringRecord sr = fr.getStringRecord(); + if(sr == null) { + // Wasn't a string before, need a new one + sr = new StringRecord(); + fr.setStringRecord(sr); + } + + // Save, loosing the formatting + sr.setString(value.getString()); + // Update our local cache to the un-formatted version + stringValue = new HSSFRichTextString(sr.getString()); + + // All done return; } + // If we get here, we're not dealing with a formula, + // so handle things as a normal rich text cell + if (cellType != CELL_TYPE_STRING) { setCellType(CELL_TYPE_STRING, false, row, col, styleIndex); } diff --git a/src/testcases/org/apache/poi/hssf/data/43623.xls b/src/testcases/org/apache/poi/hssf/data/43623.xls new file mode 100644 index 000000000..401cb2a88 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/43623.xls differ diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java index 20826b979..115efc808 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestBugs.java @@ -31,9 +31,7 @@ import org.apache.poi.hssf.HSSFTestDataSamples; import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.record.CellValueRecordInterface; import org.apache.poi.hssf.record.EmbeddedObjectRefSubRecord; -import org.apache.poi.hssf.record.FormulaRecord; import org.apache.poi.hssf.record.NameRecord; -import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate; import org.apache.poi.hssf.record.formula.DeletedArea3DPtg; import org.apache.poi.hssf.util.Region; @@ -1151,10 +1149,12 @@ public final class TestBugs extends TestCase { s.createRow(0); HSSFCell c1 = s.getRow(0).createCell((short)0); HSSFCell c2 = s.getRow(0).createCell((short)1); + HSSFCell c3 = s.getRow(0).createCell((short)2); // As number and string c1.setCellFormula("70164"); c2.setCellFormula("\"70164\""); + c3.setCellFormula("\"90210\""); // Check the formulas assertEquals("70164.0", c1.getCellFormula()); @@ -1165,20 +1165,31 @@ public final class TestBugs extends TestCase { assertEquals("", c1.getRichStringCellValue().getString()); assertEquals(0.0, c2.getNumericCellValue(), 0.00001); assertEquals("", c2.getRichStringCellValue().getString()); + assertEquals(0.0, c3.getNumericCellValue(), 0.00001); + assertEquals("", c3.getRichStringCellValue().getString()); - // Now evaluate + // Try changing the cached value on one of the string + // formula cells, so we can see it updates properly + c3.setCellValue(new HSSFRichTextString("test")); + assertEquals(0.0, c3.getNumericCellValue(), 0.00001); + assertEquals("test", c3.getRichStringCellValue().getString()); + + + // Now evaluate, they should all be changed HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb); eval.setCurrentRow(s.getRow(0)); eval.evaluateFormulaCell(c1); eval.evaluateFormulaCell(c2); + eval.evaluateFormulaCell(c3); - // Check + // Check that the cells now contain + // the correct values assertEquals(70164.0, c1.getNumericCellValue(), 0.00001); assertEquals("", c1.getRichStringCellValue().getString()); assertEquals(0.0, c2.getNumericCellValue(), 0.00001); - - // TODO - why isn't this working? -// assertEquals("70164", c2.getRichStringCellValue().getString()); + assertEquals("70164", c2.getRichStringCellValue().getString()); + assertEquals(0.0, c3.getNumericCellValue(), 0.00001); + assertEquals("90210", c3.getRichStringCellValue().getString()); // Write and read @@ -1186,12 +1197,15 @@ public final class TestBugs extends TestCase { HSSFSheet ns = nwb.getSheetAt(0); HSSFCell nc1 = ns.getRow(0).getCell((short)0); HSSFCell nc2 = ns.getRow(0).getCell((short)1); + HSSFCell nc3 = ns.getRow(0).getCell((short)2); // Re-check assertEquals(70164.0, nc1.getNumericCellValue(), 0.00001); assertEquals("", nc1.getRichStringCellValue().getString()); assertEquals(0.0, nc2.getNumericCellValue(), 0.00001); assertEquals("70164", nc2.getRichStringCellValue().getString()); + assertEquals(0.0, nc3.getNumericCellValue(), 0.00001); + assertEquals("90210", nc3.getRichStringCellValue().getString()); // Now check record level stuff too ns.getSheet().setLoc(0); @@ -1204,15 +1218,27 @@ public final class TestBugs extends TestCase { if(fn == 0) { assertEquals(70164.0, fr.getFormulaRecord().getValue(), 0.0001); assertNull(fr.getStringRecord()); - } else { + } else if (fn == 1) { assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001); assertNotNull(fr.getStringRecord()); assertEquals("70164", fr.getStringRecord().getString()); + } else { + assertEquals(0.0, fr.getFormulaRecord().getValue(), 0.0001); + assertNotNull(fr.getStringRecord()); + assertEquals("90210", fr.getStringRecord().getString()); } fn++; } } - assertEquals(2, fn); + assertEquals(3, fn); + } + + /** + * Problem with "Vector Rows" + * @throws Exception + */ + public void test43623() throws Exception { + } }