2013-05-23 16 views
9

Ora ho questo problema. Voglio scrivere un file excel da tenere in questo XSSFWorkbook (cartella di lavoro) obj in un file zip es. (Esempio.zip mentre contiene questo file example.xlsx) su un server remoto. Ho provato in seguito, ma non funziona, ha creato una cartella con alcuni file dispari nel file zipscrivere un XSSFWorkbook in un file zip

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

in modo da qualcuno sa qual è il modo giusto per fare questo? Grazie in anticipo

ps workbook.write (fileoutputstream) funziona ma scrive solo sul disco locale come un file flat, ad es. Test.xlsx invece che all'interno di un zip come ho bisogno.

risposta

4

Mancano alcune chiamate necessarie sul numero ZipOutputStream. Dovrai creare un ZipEntry per il tuo foglio di lavoro, quindi scriverlo. Avrete bisogno di qualcosa di simile a

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

Poi si dovrebbe essere in grado di chiamare

workbook.write(zipstream); 

Ma dopo che avrete bisogno di chiudere l'ingresso prima di chiudere il flusso.

zipstream.closeEntry(); 

Vedere "Write And Read .Zip File From Java" per i dettagli su come utilizzare Java ZipOutputStream.

Inoltre, si tenga presente che i file .xlsx sono già file zip compressi, quindi posizionarlo in un file .zip potrebbe non comprimerlo molto.

+0

Hi E 'il mio errore di dire che ho fatto già, quello che ho effettivamente fatto è che XSSFWorkbook cartella di lavoro = new XSSFWorkbook(); // aggiungi alcuni dati Zipoutputstream zipstream = new Zipoutputstream (// destinazione outputstream); zipstream.putNextEntry (new ZipEntry ("example.xlsx")); workbook.write (zipstream); zipstream.closeEntry(); il problema con questo è XSSFWorkbook.write chiuderà automaticamente il flusso. Quindi lo cambio in HSSFWorkbook. Ora ho il file ma non riesco ad aprirlo, dice che il contenuto è stato danneggiato qualcosa. Qualcuno sa cosa c'è che non va? Grazie. – user1721910

+0

Il file * .zip contiene il foglio di calcolo con il nome file del suo percorso assoluto? –

14

Passando a un numero da ZipOutputStream a XSSFWorkbook.write, il flusso di lavoro verrà dirottato e chiuso dalla cartella di lavoro. Ciò è dovuto al fatto che un scrive un .xlsx che è esso stesso un archivio zip di xml e altri file (è possibile decomprimere qualsiasi .xslx per vedere cosa c'è dentro). Se siete in grado di adattare il file excel in memoria, ho trovato questo per lavorare bene:

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 su ByteArrayOutputStream non ha effetto e può ancora essere scritti zos.

0

Un mio collega, M. Bunshaft, ha suggerito una soluzione simile a quella di Klugscheißer ma che non richiede l'uso di un ByteArrayOutputStream, e quindi può accogliere un output maggiore. L'idea è di sottoclasse ZipOutputStream, sovrascrivendo il metodo close() in modo che non esegua una chiusura.

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

Quindi, è sufficiente utilizzare il modo si può usare lo 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

Sono in grado di ottenere un file zip, in cui il contenuto del file XLSX è allo stesso livello, invece di essere all'interno. –