From 3cc54a8dffae84470ef50f56bb0747c28c139e52 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Tue, 31 Dec 2019 06:34:51 +0000 Subject: [PATCH] Bug 63960: Write pre-evaluated string-values in formula cells with the correct type git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1872130 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/ss/usermodel/Cell.java | 5 +-- .../poi/xssf/streaming/SheetDataWriter.java | 26 +++++++-------- .../poi/xssf/usermodel/TestSXSSFBugs.java | 33 +++++++++++++++++-- 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/java/org/apache/poi/ss/usermodel/Cell.java b/src/java/org/apache/poi/ss/usermodel/Cell.java index c6a017b26b..5f8f2fe418 100644 --- a/src/java/org/apache/poi/ss/usermodel/Cell.java +++ b/src/java/org/apache/poi/ss/usermodel/Cell.java @@ -132,12 +132,9 @@ public interface Cell { /** * Only valid for formula cells * - * Will return {@link CellType} in a future version of POI. - * For forwards compatibility, do not hard-code cell type literals in your code. - * * @return one of ({@link CellType#NUMERIC}, {@link CellType#STRING}, * {@link CellType#BOOLEAN}, {@link CellType#ERROR}) depending - * on the cached value of the formula + * on the cached value of the formula */ CellType getCachedFormulaResultType(); diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java index 560dae8c23..8e98f7eaf2 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SheetDataWriter.java @@ -53,7 +53,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; */ public class SheetDataWriter implements Closeable { private static final POILogger logger = POILogFactory.getLogger(SheetDataWriter.class); - + private final File _fd; private final Writer _out; private int _rownum; @@ -78,11 +78,11 @@ public class SheetDataWriter implements Closeable { this._sharedStringSource = sharedStringsTable; } /** - * Create a temp file to write sheet data. + * Create a temp file to write sheet data. * By default, temp files are created in the default temporary-file directory - * with a prefix "poi-sxssf-sheet" and suffix ".xml". Subclasses can override + * with a prefix "poi-sxssf-sheet" and suffix ".xml". Subclasses can override * it and specify a different temp directory or filename or suffix, e.g. .gz - * + * * @return temp file to write sheet data */ public File createTempFile() throws IOException { @@ -91,7 +91,7 @@ public class SheetDataWriter implements Closeable { /** * Create a writer for the sheet data. - * + * * @param fd the file to write to */ public Writer createWriter(File fd) throws IOException { @@ -106,7 +106,7 @@ public class SheetDataWriter implements Closeable { return new BufferedWriter( new OutputStreamWriter(decorated, StandardCharsets.UTF_8)); } - + /** * Override this to translate (such as encrypt or compress) the file output stream * as it is being written to disk. @@ -122,7 +122,7 @@ public class SheetDataWriter implements Closeable { } /** - * flush and close the temp data writer. + * flush and close the temp data writer. * This method must be invoked before calling {@link #getWorksheetXMLInputStream()} */ public void close() throws IOException { @@ -133,7 +133,7 @@ public class SheetDataWriter implements Closeable { protected File getTempFile() { return _fd; } - + /** * @return a stream to read temp file with the sheet data */ @@ -147,7 +147,7 @@ public class SheetDataWriter implements Closeable { throw e; } } - + /** * Override this to translate (such as decrypt or expand) the file input stream * as it is being read from disk. @@ -233,7 +233,7 @@ public class SheetDataWriter implements Closeable { if(row.getCollapsed() != null) { writeAttribute("collapsed", row.getCollapsed() ? "1" : "0"); } - + _out.write(">\n"); this._rownum = rownum; } @@ -252,7 +252,7 @@ public class SheetDataWriter implements Closeable { CellStyle cellStyle = cell.getCellStyle(); if (cellStyle.getIndex() != 0) { // need to convert the short to unsigned short as the indexes can be up to 64k - // ideally we would use int for this index, but that would need changes to some more + // ideally we would use int for this index, but that would need changes to some more // APIs writeAttribute("s", Integer.toString(cellStyle.getIndex() & 0xffff)); } @@ -268,7 +268,7 @@ public class SheetDataWriter implements Closeable { writeAttribute("t", "n"); break; case STRING: - writeAttribute("t", STCellType.S.toString()); + writeAttribute("t", STCellType.STR.toString()); break; case BOOLEAN: writeAttribute("t", "b"); @@ -438,7 +438,7 @@ public class SheetDataWriter implements Closeable { static boolean replaceWithQuestionMark(char c) { return c < ' ' || ('\uFFFE' <= c && c <= '\uFFFF'); } - + /** * Deletes the temporary file that backed this sheet on disk. * @return true if the file was deleted, false if it wasn't. diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java index 3aee0c54c9..174b1c4905 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java @@ -17,6 +17,7 @@ package org.apache.poi.xssf.usermodel; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -43,6 +44,7 @@ import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.junit.Ignore; import org.junit.Test; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellType; public final class TestSXSSFBugs extends BaseTestBugzillaIssues { public TestSXSSFBugs() { @@ -67,7 +69,7 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { CellRangeAddress cra = CellRangeAddress.valueOf("C2:D3"); // No print settings before repeating - Sheet s1 = wb1.createSheet(); + Sheet s1 = wb1.createSheet(); s1.setRepeatingColumns(cra); s1.setRepeatingRows(cra); @@ -93,7 +95,7 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { wb1.close(); wb2.close(); } - + // bug 60197: setSheetOrder should update sheet-scoped named ranges to maintain references to the sheets before the re-order @Test @Override @@ -209,4 +211,31 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { out.flush(); } } + + @Test + public void test63960() throws Exception { + try (Workbook workbook = new SXSSFWorkbook(100)) { + Sheet sheet = workbook.createSheet("RawData"); + + Row row = sheet.createRow(0); + Cell cell; + + cell = row.createCell(0); + cell.setCellValue(123); + cell = row.createCell(1); + cell.setCellValue(""); + cell.setCellFormula("=TEXT(A1,\"#\")"); + + /*try (FileOutputStream out = new FileOutputStream(File.createTempFile("test63960", ".xlsx"))) { + workbook.write(out); + }*/ + + try (Workbook wbBack = SXSSFITestDataProvider.instance.writeOutAndReadBack(workbook)) { + assertNotNull(wbBack); + Cell rawData = wbBack.getSheet("RawData").getRow(0).getCell(1); + + assertEquals(STCellType.STR, ((XSSFCell) rawData).getCTCell().getT()); + } + } + } }