Ja, du hast Recht. Der Unterschied zwischen diesen beiden Implementierungen besteht darin, dass die Stream-Version Daten direkt in den Stream schreibt und speichert, wobei die angegebene Anzahl von Zeilen im Speicher liegt (der Standardwert ist 100 und wird in SXSSFWorkbook.DEFAULT_WINDOW_SIZE gespeichert). Aus diesem Grund können Sie nach dem Schreiben in den Ausgabestream keine Zeilendaten abrufen. Ein großer Vorteil der Stream-Implementierung ist die geringere Speichernutzung. Wenn Sie viele Daten exportieren müssen, verwenden Sie einfach SXSSFWorkbook.
Beispiel:
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;
}
}
}
Ausgang:
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
Wie Sie sehen Reihe 1 nicht zugänglich ist, nicht mehr nach mit SXSSFWorkbook zu Ausgabestrom zu schreiben.
Vielen Dank für Ihre Antwort, aber eigentlich habe ich eine ganz andere Sache gefragt. Ich frage mich, ob meine vorhandene Implementierung, die Arbeitsmappe als Grundlage für das Erstellen von Xlsx-Datei verwendet, Stream wird, wenn ich beginnen werde, Arbeitsmappe zu erstellen, die sxssfworkbook Klasse statt Xssf verwendet. –
Wie ich schrieb, ist der Unterschied in der Verfügbarkeit von Zeilen in Arbeitsmappe gespeichert. Wenn Sie nach dem Schreiben in den Ausgabe-Steam keine Zeilen mehr benötigen, können Sie sie verwenden. – pepuch
@pepuch Nur 'SXSSFWorkbook' hat die Methode' dispose() ', mit der die temporären Dateien entfernt werden. Wie würden Sie dies zur Klasse 'WorkbookExample' hinzufügen (oder nicht)? Besetzung? Instanz von? –