2008-12-18 11 views
8

Chcę, aby użytkownicy aplikacji WWW pobierać niektóre dane jako plik Excel.Jak uzyskać strumień wejściowy z obiektu HSSFWorkbook Object

Mam następną funkcję do wysyłania strumienia wejściowego w obiekcie odpowiedzi.

public static void sendFile(InputStream is, HttpServletResponse response) throws IOException { 
     BufferedInputStream in = null; 
     try { 
      int count; 
      byte[] buffer = new byte[BUFFER_SIZE]; 
      in = new BufferedInputStream(is); 
      ServletOutputStream out = response.getOutputStream(); 
      while(-1 != (count = in.read(buffer))) 
       out.write(buffer, 0, count); 
      out.flush();    
     } catch (IOException ioe) { 
      System.err.println("IOException in Download::sendFile"); 
      ioe.printStackTrace(); 
     } finally { 
      if (in != null) { 
       try { in.close(); 
       } catch (IOException ioe) { ioe.printStackTrace(); } 
      } 
     } 
    } 

Chciałbym przekształcić mój obiekt HSSFWorkbook na strumień wejściowy i przekazać go do poprzedniej metody.

public InputStream generateApplicationsExcel() { 
    HSSFWorkbook wb = new HSSFWorkbook(); 
    // Populate the excel object 
    return null; // TODO. return the wb as InputStream 
} 

http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFWorkbook.html

Odpowiedz

10

Problem z twoim pytaniem polega na tym, że miksujesz OutputStreams i InputStreams. InputStream jest czymś, z czego czytasz, a OutputStream jest czymś, do czego piszesz.

W ten sposób napisz obiekt POI do strumienia wyjściowego.

// this part is important to let the browser know what you're sending 
response.setContentType("application/vnd.ms-excel"); 
// the next two lines make the report a downloadable file; 
// leave this out if you want IE to show the file in the browser window 
String fileName = "Blah_Report.xls"; 
response.setHeader("Content-Disposition", "attachment; filename=" + fileName); 

// get the workbook from wherever 
HSSFWorkbook wb = getWorkbook(); 
OutputStream out = response.getOutputStream(); 
try { 
    wb.write(out); 
}  
catch (IOException ioe) { 
    // if this happens there is probably no way to report the error to the user 
    if (!response.isCommited()) { 
    response.setContentType("text/html"); 
    // show response text now 
    } 
} 

Jeśli chciał ponownie wykorzystać istniejący kod trzeba by zapisać dane POI gdzieś następnie kolei, że do strumienia wejściowego. Można to łatwo zrobić, pisząc do ByteArrayOutputStream, a następnie odczytując te bajty za pomocą metody ByteArrayInputStream, ale nie polecam jej. Istniejąca metoda będzie bardziej przydatna jako ogólna implementacja potoku, w której można przesyłać dane z obiektu InputStream do obiektu OutputStream, ale nie jest to potrzebne do pisania obiektów POI.

+0

+1 na przykład. Ale w jaki sposób mogę uzyskać rozmiar pliku HSSFWorkbook? Chcę dodać nagłówek 'Content-Length' – MyTitle

+0

@MyTitle Myślę, że jeśli chciałbyś ustawić nagłówek długości treści, musisz najpierw napisać strumień do ByteArrayOutputStream, następnie uzyskać jego długość, a następnie napisać do HTTP odpowiedź. –

0

Chyba rozumiem, co próbujesz zrobić (może mam bliskiego, chociaż)

naprawdę nie potrzeba tyle code - sprawdź metodę zapisu -

HSSFWorkbook wb = new HSSFWorkBook(); 
//populate 

ServletOutputStream out = response.getOutputStream(); 
try { 
    wb.write(out); 
    out.flush(); 
}  
catch (IOException ioe) { 
    //whatever 
} 
out.close(); 

O ile pamiętam, kiedy pracowałem w/POI, to właśnie zrobiłem. Jeśli znajdujesz się w środowisku sieciowym, być może będziesz musiał go finlizować, aby struktura nie próbowała zrobić czegoś z tym ServletOutputStream po zamknięciu. Jeśli spróbuje, otrzymasz wyjątek rzucający informujący, że strumień wyjściowy jest już zamknięty.

Powiązane problemy