TestDeferredSXSSFWorkbook.java
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.apache.poi.xssf.streaming;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import org.apache.poi.ss.tests.usermodel.BaseTestXWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.DeferredSXSSFITestDataProvider;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
public final class TestDeferredSXSSFWorkbook extends BaseTestXWorkbook {
public TestDeferredSXSSFWorkbook() {
super(DeferredSXSSFITestDataProvider.instance);
}
@AfterEach
void tearDown() {
((DeferredSXSSFITestDataProvider) _testDataProvider).cleanup();
}
/**
* cloning of sheets is not supported in SXSSF
*/
@Override
@Test
public void cloneSheet() throws IOException {
RuntimeException e = assertThrows(RuntimeException.class, super::cloneSheet);
assertEquals("Not Implemented", e.getMessage());
}
/**
* cloning of sheets is not supported in SXSSF
*/
@Override
@Test
public void sheetClone() {
RuntimeException e = assertThrows(RuntimeException.class, super::sheetClone);
assertEquals("Not Implemented", e.getMessage());
}
/**
* Skip this test, as SXSSF doesn't update formulas on sheet name changes.
*/
@Override
@Disabled("SXSSF doesn't update formulas on sheet name changes, as most cells probably aren't in memory at the time")
protected void setSheetName() {}
@Override
@Disabled("DeferredSXSSF code disposes rows in a way that breaks this test")
protected void parentReferences() {}
@Override
@Disabled("DeferredSXSSF code disposes rows in a way that breaks this test")
protected void unicodeInAll() {}
@Test
void existingWorkbook() throws IOException {
try (XSSFWorkbook xssfWb1 = new XSSFWorkbook()) {
xssfWb1.createSheet("S1");
try (DeferredSXSSFWorkbook wb1 = new DeferredSXSSFWorkbook(xssfWb1);
XSSFWorkbook xssfWb2 = DeferredSXSSFITestDataProvider.instance.writeOutAndReadBack(wb1)) {
assertTrue(wb1.dispose());
try (DeferredSXSSFWorkbook wb2 = new DeferredSXSSFWorkbook(xssfWb2)) {
assertEquals(1, wb2.getNumberOfSheets());
Sheet sheet = wb2.getStreamingSheetAt(0);
assertNotNull(sheet);
assertEquals("S1", sheet.getSheetName());
assertTrue(wb2.dispose());
}
}
}
}
@Test
void addToExistingWorkbook() throws IOException {
try (XSSFWorkbook xssfWb1 = new XSSFWorkbook()) {
xssfWb1.createSheet("S1");
Sheet sheet = xssfWb1.createSheet("S2");
Row row = sheet.createRow(1);
Cell cell = row.createCell(1);
cell.setCellValue("value 2_1_1");
try (DeferredSXSSFWorkbook wb1 = new DeferredSXSSFWorkbook(xssfWb1);
XSSFWorkbook xssfWb2 = DeferredSXSSFITestDataProvider.instance.writeOutAndReadBack(wb1)) {
assertTrue(wb1.dispose());
try (DeferredSXSSFWorkbook wb2 = new DeferredSXSSFWorkbook(xssfWb2)) {
// Add a row to the existing empty sheet
DeferredSXSSFSheet ssheet1 = wb2.getStreamingSheetAt(0);
ssheet1.setRowGenerator((ssxSheet) -> {
Row row1_1 = ssxSheet.createRow(1);
Cell cell1_1_1 = row1_1.createCell(1);
cell1_1_1.setCellValue("value 1_1_1");
});
// Add a row to the existing non-empty sheet
DeferredSXSSFSheet ssheet2 = wb2.getStreamingSheetAt(1);
ssheet2.setRowGenerator((ssxSheet) -> {
Row row2_2 = ssxSheet.createRow(2);
Cell cell2_2_1 = row2_2.createCell(1);
cell2_2_1.setCellValue("value 2_2_1");
});
// Add a sheet with one row
DeferredSXSSFSheet ssheet3 = wb2.createSheet("S3");
ssheet3.setRowGenerator((ssxSheet) -> {
Row row3_1 = ssxSheet.createRow(1);
Cell cell3_1_1 = row3_1.createCell(1);
cell3_1_1.setCellValue("value 3_1_1");
});
try (XSSFWorkbook xssfWb3 = DeferredSXSSFITestDataProvider.instance.writeOutAndReadBack(wb2)) {
assertEquals(3, xssfWb3.getNumberOfSheets());
// Verify sheet 1
XSSFSheet sheet1 = xssfWb3.getSheetAt(0);
assertEquals("S1", sheet1.getSheetName());
assertEquals(1, sheet1.getPhysicalNumberOfRows());
XSSFRow row1_1 = sheet1.getRow(1);
assertNotNull(row1_1);
XSSFCell cell1_1_1 = row1_1.getCell(1);
assertNotNull(cell1_1_1);
assertEquals("value 1_1_1", cell1_1_1.getStringCellValue());
// Verify sheet 2
XSSFSheet sheet2 = xssfWb3.getSheetAt(1);
assertEquals("S2", sheet2.getSheetName());
assertEquals(2, sheet2.getPhysicalNumberOfRows());
Row row2_1 = sheet2.getRow(1);
assertNotNull(row2_1);
Cell cell2_1_1 = row2_1.getCell(1);
assertNotNull(cell2_1_1);
assertEquals("value 2_1_1", cell2_1_1.getStringCellValue());
XSSFRow row2_2 = sheet2.getRow(2);
assertNotNull(row2_2);
XSSFCell cell2_2_1 = row2_2.getCell(1);
assertNotNull(cell2_2_1);
assertEquals("value 2_2_1", cell2_2_1.getStringCellValue());
// Verify sheet 3
XSSFSheet sheet3 = xssfWb3.getSheetAt(2);
assertEquals("S3", sheet3.getSheetName());
assertEquals(1, sheet3.getPhysicalNumberOfRows());
XSSFRow row3_1 = sheet3.getRow(1);
assertNotNull(row3_1);
XSSFCell cell3_1_1 = row3_1.getCell(1);
assertNotNull(cell3_1_1);
assertEquals("value 3_1_1", cell3_1_1.getStringCellValue());
}
}
}
}
}
@Test
void inMemoryWrite() throws IOException {
try (XSSFWorkbook xssfWb1 = new XSSFWorkbook()) {
xssfWb1.createSheet("S1");
Sheet sheet = xssfWb1.createSheet("S2");
Row row = sheet.createRow(1);
Cell cell = row.createCell(1);
cell.setCellValue("value 2_1_1");
try (DeferredSXSSFWorkbook wb1 = new DeferredSXSSFWorkbook(xssfWb1);
XSSFWorkbook xssfWb2 = DeferredSXSSFITestDataProvider.instance.writeOutAndReadBack(wb1)) {
assertTrue(wb1.dispose());
try (DeferredSXSSFWorkbook wb2 = new DeferredSXSSFWorkbook(xssfWb2)) {
// Add a row to the existing empty sheet
DeferredSXSSFSheet ssheet1 = wb2.getStreamingSheetAt(0);
ssheet1.setRowGenerator((ssxSheet) -> {
Row row1_1 = ssxSheet.createRow(1);
Cell cell1_1_1 = row1_1.createCell(1);
cell1_1_1.setCellValue("value 1_1_1");
});
// Add a row to the existing non-empty sheet
DeferredSXSSFSheet ssheet2 = wb2.getStreamingSheetAt(1);
ssheet2.setRowGenerator((ssxSheet) -> {
Row row2_2 = ssxSheet.createRow(2);
Cell cell2_2_1 = row2_2.createCell(1);
cell2_2_1.setCellValue("value 2_2_1");
});
// Add a sheet with one row
DeferredSXSSFSheet ssheet3 = wb2.createSheet("S3");
ssheet3.setRowGenerator((ssxSheet) -> {
Row row3_1 = ssxSheet.createRow(1);
Cell cell3_1_1 = row3_1.createCell(1);
cell3_1_1.setCellValue("value 3_1_1");
});
try (XSSFWorkbook xssfWb3 = DeferredSXSSFITestDataProvider.instance.inMemoryWriteOutAndReadBack(wb2)) {
assertEquals(3, xssfWb3.getNumberOfSheets());
// Verify sheet 1
XSSFSheet sheet1 = xssfWb3.getSheetAt(0);
assertEquals("S1", sheet1.getSheetName());
assertEquals(1, sheet1.getPhysicalNumberOfRows());
XSSFRow row1_1 = sheet1.getRow(1);
assertNotNull(row1_1);
XSSFCell cell1_1_1 = row1_1.getCell(1);
assertNotNull(cell1_1_1);
assertEquals("value 1_1_1", cell1_1_1.getStringCellValue());
// Verify sheet 2
XSSFSheet sheet2 = xssfWb3.getSheetAt(1);
assertEquals("S2", sheet2.getSheetName());
assertEquals(2, sheet2.getPhysicalNumberOfRows());
Row row2_1 = sheet2.getRow(1);
assertNotNull(row2_1);
Cell cell2_1_1 = row2_1.getCell(1);
assertNotNull(cell2_1_1);
assertEquals("value 2_1_1", cell2_1_1.getStringCellValue());
XSSFRow row2_2 = sheet2.getRow(2);
assertNotNull(row2_2);
XSSFCell cell2_2_1 = row2_2.getCell(1);
assertNotNull(cell2_2_1);
assertEquals("value 2_2_1", cell2_2_1.getStringCellValue());
// Verify sheet 3
XSSFSheet sheet3 = xssfWb3.getSheetAt(2);
assertEquals("S3", sheet3.getSheetName());
assertEquals(1, sheet3.getPhysicalNumberOfRows());
XSSFRow row3_1 = sheet3.getRow(1);
assertNotNull(row3_1);
XSSFCell cell3_1_1 = row3_1.getCell(1);
assertNotNull(cell3_1_1);
assertEquals("value 3_1_1", cell3_1_1.getStringCellValue());
}
}
}
}
}
@Test
void sheetdataWriter() throws IOException {
try (DeferredSXSSFWorkbook wb = new DeferredSXSSFWorkbook()) {
SXSSFSheet sh = wb.createSheet();
assertSame(sh.getClass(), DeferredSXSSFSheet.class);
SheetDataWriter wr = sh.getSheetDataWriter();
assertNull(wr);
}
}
@Test
void removeSheet() throws IOException {
try (DeferredSXSSFWorkbook wb = new DeferredSXSSFWorkbook()) {
DeferredSXSSFSheet sheet1 = wb.createSheet("sheet1");
sheet1.setRowGenerator((sh) -> {
Row row = sh.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("sheet1");
});
DeferredSXSSFSheet sheet2 = wb.createSheet("sheet2");
sheet2.setRowGenerator((sh) -> {
Row row = sh.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("sheet2");
});
wb.removeSheetAt(0);
try (XSSFWorkbook wb2 = DeferredSXSSFITestDataProvider.instance.writeOutAndReadBack(wb)) {
assertNull(wb2.getSheet( "sheet1"));
XSSFSheet xssfSheet = wb2.getSheet( "sheet2");
assertNotNull(xssfSheet);
assertEquals("sheet2", xssfSheet.getRow(0).getCell(0).getStringCellValue());
}
}
}
@Test
void gzipSheetdataWriter() throws IOException {
try (DeferredSXSSFWorkbook wb = new DeferredSXSSFWorkbook()) {
final int rowNum = 1000;
final int sheetNum = 5;
populateData(wb);
try (XSSFWorkbook xwb = DeferredSXSSFITestDataProvider.instance.writeOutAndReadBack(wb)) {
for (int i = 0; i < sheetNum; i++) {
Sheet sh = xwb.getSheetAt(i);
assertEquals("sheet" + i, sh.getSheetName());
for (int j = 0; j < rowNum; j++) {
Row row = sh.getRow(j);
assertNotNull(row, "row[" + j + "]");
Cell cell1 = row.getCell(0);
assertEquals(new CellReference(cell1).formatAsString(), cell1.getStringCellValue());
Cell cell2 = row.getCell(1);
assertEquals(i, (int) cell2.getNumericCellValue());
Cell cell3 = row.getCell(2);
assertEquals(j, (int) cell3.getNumericCellValue());
}
}
assertTrue(wb.dispose());
}
}
}
@ParameterizedTest
@ValueSource(booleans = {false, true})
void workbookDispose(boolean compressTempFiles) throws IOException {
try (DeferredSXSSFWorkbook wb = new DeferredSXSSFWorkbook()) {
// compressTempFiles == false: the underlying writer is SheetDataWriter
// compressTempFiles == true: the underlying writer is GZIPSheetDataWriter
wb.setCompressTempFiles(compressTempFiles);
populateData(wb);
for (Sheet sheet : wb) {
DeferredSXSSFSheet sxSheet = (DeferredSXSSFSheet) sheet;
assertNull(sxSheet.getSheetDataWriter());
}
assertTrue(wb.dispose());
for (Sheet sheet : wb) {
DeferredSXSSFSheet sxSheet = (DeferredSXSSFSheet) sheet;
assertNull(sxSheet.getSheetDataWriter());
}
}
}
private static void populateData(DeferredSXSSFWorkbook wb) {
for (int i = 0; i < 5; i++) {
DeferredSXSSFSheet sheet = wb.createSheet("sheet" + i);
int index = i;
sheet.setRowGenerator((sh) -> {
for (int j = 0; j < 1000; j++) {
Row row = sh.createRow(j);
Cell cell1 = row.createCell(0);
cell1.setCellValue(new CellReference(cell1).formatAsString());
Cell cell2 = row.createCell(1);
cell2.setCellValue(index);
Cell cell3 = row.createCell(2);
cell3.setCellValue(j);
}
});
}
}
@Override
@Disabled("not implemented")
protected void changeSheetNameWithSharedFormulas() {
}
}