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
This commit is contained in:
Dominik Stadler 2019-12-31 06:34:51 +00:00
parent bc0dcdf369
commit 3cc54a8dff
3 changed files with 45 additions and 19 deletions

View File

@ -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();

View File

@ -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. <code>.gz</code>
*
*
* @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 <em>must</em> 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.

View File

@ -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());
}
}
}
}