2013-05-23 15 views
9

Ich habe jetzt dieses Problem. Ich möchte eine Excel-Datei in diesem XSSFWorkbook (Arbeitsbuch) -Obj in eine Zip-Datei schreiben (zB example.zip mit dieser example.xlsx-Datei) auf einen entfernten Server. Ich habe versucht, folgende aber nicht funktioniert, erstellt es einen Ordner mit einigen ungeradeen Dateien in der Zip-Dateiein XSSFWorkbook in eine Zip-Datei schreiben

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

So tun jemand weiß, was der richtige Weg, dies zu tun? Vielen Dank im Voraus

ps workbook.write (fileoutputstream) funktioniert, aber es nur auf lokale Festplatte als eine flache Datei schreiben zB test.xlsx statt in einem Zip, wie ich brauche.

Antwort

4

Ihnen fehlen einige notwendige Anrufe auf Ihrem ZipOutputStream. Sie müssen für Ihre Tabellenkalkulationsdatei eine ZipEntry erstellen und dann aufschreiben. Sie werden so etwas wie

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

brauchen Dann sollten Sie in der Lage sein

workbook.write(zipstream); 

zu nennen, aber nach, dass Sie den Eintrag schließen müssen, bevor der Strom geschlossen wird.

zipstream.closeEntry(); 

Bitte sehen "Write And Read .Zip File From Java" für Details, wie ZipOutputStream Java zu verwenden.

Beachten Sie auch, dass .xlsx-Dateien bereits komprimierte ZIP-Dateien sind. Daher kann es bei der Platzierung in einer ZIP-Datei möglicherweise nicht sehr komprimiert werden.

+0

Hallo Es ist mein Fehler, zu erwähnen, dass ich es tat schon, was ich tat, ist eigentlich, dass XSSFWorkbook Arbeitsmappe = new XSSFWorkbook(); // einige Daten hinzufügen Zipoutputstream zipstream = neuer Zipoutputstream (// Ziel-Ausgabestrom); zipstream.putNextEntry (neuer ZipEntry ("example.xlsx")); workbook.write (zipstream); zipstream.closeEntry(); das Problem damit ist XSSFWorkbook.write wird automatisch den Stream zu schließen. Also ändere ich es in HSSFWorkbook. Jetzt habe ich die Datei aber ich kann sie nicht öffnen, es heißt der Inhalt wurde etwas beschädigt. Weiß jemand, was falsch ist? Vielen Dank. – user1721910

+0

Enthält die * .zip-Datei das Spreadsheet mit dem Dateinamen seines absoluten Pfads? –

14

Das Übergeben einer a ZipOutputStream an XSSFWorkbook.write führt dazu, dass der Stream von der Arbeitsmappe gekapert und geschlossen wird. Das liegt daran, dass ein XSSFWorkbook einen .xlsx schreibt, der selbst ein Zip-Archiv von XML und anderen Dateien ist (Sie können alle .xslx entpacken, um zu sehen, was da drin ist). Wenn Sie in der Lage sind, die Excel-Datei in den Speicher zu passen, habe ich festgestellt, diese gut zu funktionieren:

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(); 

Aufruf close auf ByteArrayOutputStream keine Wirkung hat und noch zu zos geschrieben werden können.

0

Ein Kollege von mir, M. Bunshaft, schlug eine Lösung ähnlich der von Klugscheißer vor, aber das erfordert nicht die Verwendung eines ByteArrayOutputStream, und kann daher größere Ausgabe aufnehmen. Die Idee ist es, ZipOutputStream von der Methode close() zu entfernen, damit es nicht geschlossen wird.

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

Dann verwenden Sie es einfach so, wie Sie die ZipOutputStream verwenden würden.

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

Ich bin in der Lage, eine Zip-Datei zu erhalten, in der der Inhalt der XLSX-Datei auf dem gleichen Niveau ist, anstatt darin zu sein. –