I have one question. Am I right that if I have a workbook which is created through xssf
constructor then it is enough to change the constructor to sxssf
workbook (with xssf
wb passed as an argument) to make it work in a stream mode
? Thanks a lof for your answers.
Solution: It all depends on the classes which you use for streaming. If your class gathers more stream buffers than it can hold, this thing won't work. Otherwise it will
Yes, you're right. The difference between these two implementations is that stream version writes data directly to stream and stores at most specified number of rows in memory (default value is 100 and it's stored in SXSSFWorkbook.DEFAULT_WINDOW_SIZE). Because of that you won't be able to get some row data after writing to output stream. Big benefit of using stream implementation is less memory usage. If you need to export a lot of data just use SXSSFWorkbook.
Example:
public static void main(String[] args) throws IOException {
FileOutputStream inMemoryOut = new FileOutputStream(new File("inMemoryWorkbook.xlsx"));
XSSFWorkbook workbook = new XSSFWorkbook();
WorkbookExample example = new WorkbookExample(workbook, inMemoryOut);
example.export();
FileOutputStream streamOut = new FileOutputStream(new File("streamWorkbook.xlsx"));
SXSSFWorkbook streamWorkbook = new SXSSFWorkbook();
WorkbookExample streamExample = new WorkbookExample(streamWorkbook, streamOut);
streamExample.export();
}
public class WorkbookExample {
private Logger logger = Logger.getLogger(WorkbookExample.class.getName());
private Workbook workbook;
private OutputStream out;
public WorkbookExample(Workbook workbook, OutputStream out) {
this.workbook = workbook;
this.out = out;
}
public void export() throws IOException {
logger.info("export start for " + workbook.getClass().getName());
List<Person> persons = new ArrayList<Person>();
for (int i = 0; i < 1000; i++) {
persons.add(new Person(String.valueOf("user_" + i)));
}
Sheet sheet = workbook.createSheet();
for (int i = 0; i < persons.size(); i++) {
Person p = persons.get(i);
Row row = sheet.createRow(i);
Cell cell = row.createCell(0);
cell.setCellValue(p.getName());
}
workbook.write(out);
logger.info("Is row 1 accessible after writing to output stream? " + String.valueOf(sheet.getRow(1) != null));
out.close();
workbook.close();
logger.info("export finished for " + workbook.getClass().getName());
}
public static class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
Output:
kwi 21, 2015 7:56:14 PM pepuch.html2pdf.WorkbookExample export
INFO: export start for org.apache.poi.xssf.usermodel.XSSFWorkbook
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
INFO: Is row 1 accessible after writing to output stream? true
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
INFO: export finished for org.apache.poi.xssf.usermodel.XSSFWorkbook
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
INFO: export start for org.apache.poi.xssf.streaming.SXSSFWorkbook
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
INFO: Is row 1 accessible after writing to output stream? false
kwi 21, 2015 7:56:15 PM pepuch.html2pdf.WorkbookExample export
INFO: export finished for org.apache.poi.xssf.streaming.SXSSFWorkbook
As you see row 1 is not accessible any more after writing to output stream with SXSSFWorkbook.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With