Eccezione quando si scrive sul documento xlsx più volte usando apache poi 3.7

Sto ottenendo la seguente eccezione durante il tentativo di scrivere un file .xlsx usando il POI di Apache: org.apache.xmlbeans.impl.values.XmlValueDisconnectedException

Sembra che il problema stia usando il metodo write () la seconda volta. Quando si lavora con un HSSFWorkbook di questo problema non si pone.

Ecco il codice:

 public class SomeClass{ XSSFWorkbook workbook; public SomeClass() throws IOException{ File excelFile = new File("workbook.xlsx"); InputStream inp = new FileInputStream(excelFile); workbook = new XSSFWorkbook(inp); inp.close(); } void method(int i) throws InvalidFormatException, IOException { XSSFSheet sheet = workbook.getSheetAt(0); XSSFRow row = sheet.getRow(i); if (row == null) { row = sheet.createRow(i); } XSSFCell cell = row.getCell(i); if (cell == null) cell = row.createCell(i); cell.setCellType(Cell.CELL_TYPE_STRING); cell.setCellValue("a test"); // Write the output to a file FileOutputStream fileOut = new FileOutputStream("workbook.xlsx"); workbook.write(fileOut); fileOut.close(); } public static void main(String[] args) throws Exception { SomeClass sc = new SomeClass(); sc.method(1); sc.method(2); } } 

Questo è probabilmente un bug.

https://issues.apache.org/bugzilla/show_bug.cgi?id=49940

Ti suggerisco di iscriverti a quel ticket per ricevere notifiche sugli attuali miglioramenti / alternative.

Se trovo una soluzione, ti farò sapere.

Ho avuto lo stesso problema oggi. Ho notato che molte persone hanno fatto la stessa domanda in molti forum diversi, ma non ho mai visto una risposta. Quindi, ecco cosa mi è venuto in mente. È tutt’altro che ideale (posso pensare ad almeno due scenari in cui questa potrebbe essere una ctriggers idea), e potrebbe non soddisfare ogni esigenza, ma funziona!

Dopo ogni operazione di salvataggio all’interno della class di cui l’object cartella di lavoro è una proprietà, ricarico la cartella di lavoro dal file in cui l’ho appena salvata.

Usando il tuo esempio di codice sopra, vorrei modificare il metodo in questo modo:

 void method(int i) throws InvalidFormatException, IOException { ... // Write the output to a file FileOutputStream fileOut = new FileOutputStream("workbook.xlsx"); workbook.write(fileOut); fileOut.close(); // Reload the workbook, workaround for bug 49940 // https://issues.apache.org/bugzilla/show_bug.cgi?id=49940 workbook = new XSSFWorkbook(new FileInputStream("workbook.xlsx")); } 

Ho provato questo nel mio codice, e ha risolto bene il problema. Assicurati di leggerlo di nuovo dallo stesso file in cui lo hai salvato e non da una versione precedente o diversa.

La soluzione che ho trovato per questo, e ho cercato per un po ‘, è di assicurarsi di non aprire la Workbook di Workbook con il File che si utilizza per aprire FileOutputStream per salvare la Workbook . Invece, utilizzare un FileInputStream per aprire la Workbook .

Qualcosa di simile funzionerà perfettamente

  File inputFile = new File("Your-Path"); this.inputStream = new FileInputStream(inputFile); this.opc = OPCPackage.open(this.inputStream); this.workbook = WorkbookFactory.create(opc); ... this.outputStream = new FileOutputStream(inputFile); this.workbook.write(this,outputStream); 

Non dimenticare di chiudere tutti gli stream aperti e l’ OPCPackage .

Ciò si verifica solo quando proviamo a scrivere più di una volta nello stesso file anche per un file .xlsx. Sono venuto attraverso lo stesso problema e l’ho risolto da ..

  1. In precedenza stavo scrivendo due volte
  2. Ora rimosso la prima chiamata di scrittura
  3. Passata la stessa istanza della cartella di lavoro al metodo e impostazione dei valori nella nuova cella
  4. alla fine ha apportato altre modifiche alla cartella di lavoro scrivendo poche altre colonne e celle
  5. Quindi ha scritto usando il stream di output del file.

Stava funzionando

Anch’io ho affrontato lo stesso problema quando uso Apache Poi 3.10. Ma dopo aver aggiunto gli ultimi file jar apache poi, ha funzionato per me. Si prega di provare dopo aver aggiornato i vasi al più tardi.

Ho avuto lo stesso problema anche io. Più tardi, ho provato un altro metodo e ha risolto.
In questo caso, possiamo spostare il codice:

 FileOutputStream fileOut = new FileOutputStream("workbook.xlsx"); workbook.write(fileOut); fileOut.close(); 

fuori dal metodo (int i), e quindi nel metodo principale, possiamo usare:

  sc.method(1); sc.method(2); FileOutputStream fileOut = new FileOutputStream("workbook.xlsx"); workbook.write(fileOut); fileOut.close(); 

Quindi, workbook.write viene utilizzato solo una volta. Inoltre i dati potrebbero essere modificati più volte.

Questo sembra essere un bug in XSSFSheet.createRow (int index). Finché il bug non viene corretto, l’uso di questa class come soluzione alternativa dovrebbe fare il trucco:

 import java.util.Iterator; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; public class PoiHacks { // Fix of XSSFSheet.createRow(int index) public static Row createRow(Sheet sheet, int index) { Row row = sheet.getRow(index); if(row==null) return sheet.createRow(index); Iterator it = row.iterator(); while(it.hasNext()) { it.next(); it.remove(); } return row; } } 

Uso :

 PoiHacks.createRow(sheet, 0);