2015-04-21 30 views
5

Mam jedno pytanie. Czy mam rację, jeśli mam skoroszyt utworzony za pomocą konstruktora xssf, wystarczy zmienić konstruktora na skoroszyt sxssf (z xssf wb przekazanym jako argument), aby działał on w stream mode? Dziękuję za odpowiedzi.Apache POI SXSSF i XSSF

Rozwiązanie: Wszystko zależy od klas, z których korzystasz podczas przesyłania strumieniowego. Jeśli twoja klasa zbierze więcej buforów strumieniowych niż może pomieścić, ta rzecz nie zadziała. W przeciwnym razie będzie to

Odpowiedz

9

Tak, masz rację. Różnica między tymi dwiema implementacjami polega na tym, że wersja strumieniowa zapisuje dane bezpośrednio do strumienia i przechowuje co najwyżej określoną liczbę wierszy w pamięci (domyślna wartość to 100 i jest przechowywana w SXSSFWorkbook.DEFAULT_WINDOW_SIZE). Z tego powodu po zapisaniu do strumienia wyjściowego nie będzie można uzyskać danych wiersza. Dużą korzyścią z używania implementacji strumienia jest mniejsze zużycie pamięci. Jeśli chcesz wyeksportować dużo danych, po prostu użyj SXSSFWorkbook.

Przykład:

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; 
     } 

    } 

} 

wyjściowa:

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 

Jak widać rząd 1 nie jest dłużej dostępny po wpisaniu do strumienia wyjściowego z SXSSFWorkbook.

+0

Dziękuję za odpowiedź, ale faktycznie zadawałem zupełnie inną. Zastanawiam się, czy moja istniejąca implementacja, która używa skoroszytu jako podstawy do tworzenia pliku xlsx, stanie się strumieniem, jeśli zacznę tworzyć skoroszyt przy użyciu klasy sxssfworkbook zamiast xssf. –

+0

Jak napisałem, różnica polega na dostępności wierszy przechowywanych w skoroszycie. Jeśli nie potrzebujesz uzyskać wierszy po napisaniu do wyjścia steeam, możesz go użyć. – pepuch

+0

@pepuch Tylko 'SXSSFWorkbook' ma metodę" dispose() ", używaną do usuwania plików tymczasowych. Jak dodać (lub nie) do klasy "WorkbookExample"? Odlew? Wystąpienie? –