diff --git a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java index f8a9de584..4442c8751 100644 --- a/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java +++ b/src/ooxml/java/org/apache/poi/xssf/streaming/SXSSFSheet.java @@ -970,8 +970,7 @@ public class SXSSFSheet implements Sheet */ @NotImplemented @Override - public void shiftRows(int startRow, int endRow, int n) - { + public void shiftRows(int startRow, int endRow, int n) { throw new RuntimeException("NotImplemented"); } @@ -1730,9 +1729,12 @@ public class SXSSFSheet implements Sheet * @return the {@link CellRange} of cells affected by this change */ @Override - public CellRange setArrayFormula(String formula, CellRangeAddress range) - { - return _sh.setArrayFormula(formula, range); + public CellRange setArrayFormula(String formula, CellRangeAddress range) { + // the simple approach via _sh does not work as it creates rows in the XSSFSheet and thus causes + // corrupted .xlsx files as rows appear multiple times in the resulting sheetX.xml files + // return _sh.setArrayFormula(formula, range); + + throw new RuntimeException("NotImplemented"); } /** @@ -1742,9 +1744,12 @@ public class SXSSFSheet implements Sheet * @return the {@link CellRange} of cells affected by this change */ @Override - public CellRange removeArrayFormula(Cell cell) - { - return _sh.removeArrayFormula(cell); + public CellRange removeArrayFormula(Cell cell) { + // the simple approach via _sh does not work as it creates rows in the XSSFSheet and thus causes + // corrupted .xlsx files as rows appear multiple times in the resulting sheetX.xml files + // return _sh.removeArrayFormula(cell); + + throw new RuntimeException("NotImplemented"); } @Override 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 5cb6afa77..2d0aec167 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestSXSSFBugs.java @@ -18,15 +18,22 @@ package org.apache.poi.xssf.usermodel; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; import java.io.IOException; +import org.apache.poi.ss.ITestDataProvider; import org.apache.poi.ss.usermodel.BaseTestBugzillaIssues; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.PrintSetup; +import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.SXSSFITestDataProvider; +import org.apache.poi.xssf.XSSFITestDataProvider; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.junit.Ignore; import org.junit.Test; @@ -99,4 +106,64 @@ public final class TestSXSSFBugs extends BaseTestBugzillaIssues { } } } + + @Test + public void bug61648() throws Exception { + // works as expected + writeWorkbook(new XSSFWorkbook(), "/tmp/61648.xlsx", XSSFITestDataProvider.instance); + + // does not work + try { + writeWorkbook(new SXSSFWorkbook(), "/tmp/61648s.xlsx", SXSSFITestDataProvider.instance); + fail("Should catch exception here"); + } catch (RuntimeException e) { + // this is not implemented yet + } + } + + void writeWorkbook(Workbook wb, String filename, ITestDataProvider testDataProvider) throws IOException { + Sheet sheet = wb.createSheet("array formula test"); + + int rowIndex = 0; + int colIndex = 0; + Row row = sheet.createRow(rowIndex++); + + Cell cell = row.createCell(colIndex++); + cell.setCellType(CellType.STRING); + cell.setCellValue("multiple"); + cell = row.createCell(colIndex++); + cell.setCellType(CellType.STRING); + cell.setCellValue("unique"); + + writeRow(sheet, rowIndex++, 80d, "INDEX(A2:A7, MATCH(FALSE, ISBLANK(A2:A7), 0))"); + writeRow(sheet, rowIndex++, 30d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B2, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); + writeRow(sheet, rowIndex++, 30d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B3, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); + writeRow(sheet, rowIndex++, 2d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B4, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); + writeRow(sheet, rowIndex++, 30d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B5, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); + writeRow(sheet, rowIndex++, 2d, "IFERROR(INDEX(A2:A7, MATCH(1, (COUNTIF(B2:B6, A2:A7) = 0) * (NOT(ISBLANK(A2:A7))), 0)), \"\")"); + + /*FileOutputStream fileOut = new FileOutputStream(filename); + wb.write(fileOut); + fileOut.close();*/ + + Workbook wbBack = testDataProvider.writeOutAndReadBack(wb); + assertNotNull(wbBack); + wbBack.close(); + + wb.close(); + } + + void writeRow(Sheet sheet, int rowIndex, Double col0Value, String col1Value) { + int colIndex = 0; + Row row = sheet.createRow(rowIndex); + + // numeric value cell + Cell cell = row.createCell(colIndex++); + cell.setCellType(CellType.NUMERIC); + cell.setCellValue(col0Value); + + // formula value cell + CellRangeAddress range = new CellRangeAddress(rowIndex, rowIndex, colIndex, colIndex); + sheet.setArrayFormula(col1Value, range); + } }