Sì, hai ragione. La differenza tra queste due implementazioni è che la versione di flusso scrive i dati direttamente nello stream e archivia al numero di righe specificato nella memoria (il valore predefinito è 100 ed è memorizzato in SXSSFWorkbook.DEFAULT_WINDOW_SIZE). Per questo motivo non sarai in grado di ottenere alcuni dati di riga dopo la scrittura sul flusso di output. Il grande vantaggio di utilizzare l'implementazione del flusso è un minor utilizzo di memoria. Se hai bisogno di esportare molti dati usa SXSSFWorkbook.
Esempio:
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;
}
}
}
uscita:
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
Come vedi riga 1 non è accessibile più dopo aver scritto al flusso di output con SXSSFWorkbook.
Grazie per la risposta, ma in realtà stavo chiedendo una cosa diversa. Mi chiedevo se la mia implementazione esistente che utilizza la cartella di lavoro come base per la creazione di file xlsx diventi stream se inizierò a creare la cartella di lavoro usando la classe sxssfworkbook invece di xssf. –
Come ho scritto la differenza è nella disponibilità di righe memorizzate nella cartella di lavoro. Se non hai bisogno di ottenere righe dopo aver scritto per produrre steeam puoi usarlo. – pepuch
@pepuch Solo 'SXSSFWorkbook' ha il metodo' dispose() ', usato per rimuovere i file temporanei. Come aggiungere (o meno) questo alla classe 'WorkbookExample'? Cast? InstanceOf? –