2013-05-23 41 views
9

Tôi hiện có vấn đề này. Tôi muốn viết một tập tin excel giữ trong XSSFWorkbook (workbook) obj vào một tập tin zip ví dụ (ví dụ.zip trong khi chứa tập tin example.xlsx) đến một máy chủ từ xa. Tôi đã thử sau nhưng không làm việc, nó tạo ra một thư mục với một số tác phẩm lẻ trong file zipviết XSSFWorkbook vào một tệp zip

XSSFWorkbook workbook = new XSSFWorkbook(); 
    //add some data 
    Zipoutputstream zipstream=new Zipoutputstream(//destination outputstream); 
    workbook.write(zipstream); 

Vì vậy, làm bất cứ ai biết đúng cách để làm điều này là những gì? Cảm ơn trước

ps workbook.write (fileoutputstream) hoạt động nhưng nó chỉ ghi vào đĩa cục bộ dưới dạng tệp phẳng, ví dụ: test.xlsx thay vì bên trong mã zip như tôi cần.

Trả lời

4

Bạn đang thiếu một số cuộc gọi cần thiết trên số ZipOutputStream. Bạn sẽ cần phải tạo một ZipEntry cho tệp bảng tính của mình, sau đó viết nó ra. Bạn sẽ cần một cái gì đó giống như

zipstream.putNextEntry(new ZipEntry("example.xlsx")); 

Sau đó, bạn sẽ có thể gọi

workbook.write(zipstream); 

Nhưng sau đó bạn sẽ cần phải đóng các mục nhập trước khi chốt suối.

zipstream.closeEntry(); 

Vui lòng xem "Write And Read .Zip File From Java" để biết chi tiết về cách sử dụng Java ZipOutputStream.

Ngoài ra, hãy lưu ý rằng các tệp .xlsx đã được nén các tệp zip, vì vậy việc đặt tệp trong tệp .zip có thể không nén nhiều.

+0

Hi Đó là sai lầm của tôi kể rằng tôi đã làm nó đã có, những gì tôi thực sự đã là XSSFWorkbook workbook = new XSSFWorkbook(); // thêm một số dữ liệu Zipoutputstream zipstream = new Zipoutputstream (// destination outputstream); zipstream.putNextEntry (mới ZipEntry ("example.xlsx")); workbook.write (zipstream); zipstream.closeEntry(); vấn đề với đó là XSSFWorkbook.write sẽ tự động đóng luồng. Vì vậy, tôi thay đổi nó thành HSSFWorkbook. Bây giờ tôi có các tập tin nhưng tôi không thể mở nó, nó nói rằng nội dung đã bị hỏng một cái gì đó. Có ai biết điều gì sai? Cảm ơn. – user1721910

+0

Tệp * .zip có chứa Bảng tính có tên tệp của đường dẫn tuyệt đối không? –

14

Chuyển số ZipOutputStream tới XSSFWorkbook.write sẽ dẫn đến luồng bị xâm nhập và đóng bởi sổ làm việc. Điều này là do một số XSSFWorkbook viết một .xlsx mà chính nó là một kho lưu trữ zip của xml và các tệp khác (bạn có thể giải nén mọi tệp .xslx để xem nội dung trong đó). Nếu bạn có thể để phù hợp với tập tin excel trong ký ức, tôi đã thấy điều này để làm việc tốt:

ZipOutputStream zos = new ZipOutputStream(//destination outputstream); 
zos.putNextEntry(new ZipEntry("AnExcelFile.xlsx")); 
ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
workbook.write(bos); 
bos.writeTo(zos); 
zos.closeEntry(); 
// Add other entries as needed 
zos.close(); 

Calling close trên ByteArrayOutputStream không có tác dụng và vẫn có thể được ghi vào zos.

0

Một đồng nghiệp của tôi, M. Bunshaft, đã đề xuất một giải pháp tương tự như của Klugscheißer nhưng điều đó không yêu cầu sử dụng ByteArrayOutputStream, và do đó có thể đáp ứng đầu ra lớn hơn. Ý tưởng là để phân lớp ZipOutputStream, ghi đè phương thức close() để nó không đóng lại.

public class UncloseableZipOutputStream extends ZipOutputStream 
 
{ 
 
\t OutputStream os; 
 
\t 
 
\t public UncloseableZipOutputStream(OutputStream os) 
 
\t { 
 
\t \t super(os); 
 
\t } 
 
\t 
 
\t @Override 
 
\t /** just flush but do not close */ 
 
\t public void close() throws IOException 
 
\t { 
 
\t \t flush(); 
 
\t } 
 
\t 
 
\t public void reallyClose() throws IOException 
 
\t { 
 
\t \t super.close(); 
 
\t } 
 
}

Sau đó, chỉ cần sử dụng nó theo cách bạn sẽ sử dụng ZipOutputStream.

UncloseableZipOutputStream zos = new UncloseableZipOutputStream(//destination outputstream); 
 
zos.putNextEntry(new ZipEntry("AnExcelFile.xlsx")); 
 
workbook.write(zos); 
 
zos.closeEntry();  // now this will not cause a close of the stream 
 
// Add other entries as needed 
 
zos.reallyClose();

+0

Tôi có thể nhận tệp zip, trong đó nội dung của tệp XLSX ở cùng cấp, thay vì ở bên trong. –

Các vấn đề liên quan