Je reçois l'exception suivante lors de la tentative d'écriture d'un fichier .xlsx
à l'aide d'un POI Apache: org.Apache.xmlbeans.impl.values.XmlValueDisconnectedException
Il semble que le problème utilise la méthode write () une seconde fois. Lorsque vous travaillez avec un HSSFWorkbook de ce problème ne se pose pas.
Voici le code:
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);
}
}
C'est probablement un bug.
https://issues.Apache.org/bugzilla/show_bug.cgi?id=49940
Je vous suggère de vous abonner à ce ticket pour être averti des améliorations/alternatives en cours.
Si je trouve une solution de contournement, je vous le ferai savoir.
J'ai eu le même problème aujourd'hui. J'ai remarqué que beaucoup de gens posaient la même question sur de nombreux forums différents, mais je n'ai vu aucune réponse nulle part. Alors, voici ce que je suis venu avec. C'est loin d'être idéal (je peux penser à au moins deux scénarios où cela pourrait être une mauvaise idée), et peut ne pas répondre à tous les besoins, mais cela fonctionne!
Après chaque opération de sauvegarde à l'intérieur de la classe dont l'objet de classeur est une propriété, je recharge le classeur à partir du fichier dans lequel je viens de l'enregistrer.
En utilisant votre exemple de code ci-dessus, je modifierais la méthode comme suit:
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"));
}
J'ai testé cela dans mon code et cela a bien résolu le problème. Assurez-vous simplement de le relire à partir du même fichier que celui dans lequel vous l'avez enregistré, et non d'une version antérieure ou différente.
La solution que j'ai trouvée pour cela, et que je cherchais depuis un moment, est de s'assurer que vous n'ouvrez pas votre Workbook
avec la File
que vous utilisez pour ouvrir la FileOutputStream
afin de sauvegarder la Workbook
. Utilisez plutôt une FileInputStream
pour ouvrir la Workbook
.
Quelque chose comme ça fonctionnera parfaitement
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);
N'oubliez pas de fermer tous les flux ouverts et la OPCPackage
.
Cela se produit uniquement lorsque nous essayons d’écrire plusieurs fois dans le même fichier qu’un fichier .xlsx. Je suis tombé sur le même problème et je l'ai résolu en ..
Ça fonctionnait
Moi aussi, j'ai rencontré le même problème avec Apache poi 3.10. Mais après l’ajout des derniers fichiers Apache poi jar, cela a fonctionné pour moi. S'il vous plaît essayez après la mise à jour des pots au plus tard.
J'ai eu le même problème aussi. Plus tard, j'ai essayé une autre méthode et celle-ci a été résolue.
Dans ce cas, nous pouvons déplacer le code:
FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
workbook.write(fileOut);
fileOut.close();
hors de la méthode (int i), puis dans la méthode principale, on peut utiliser:
sc.method(1);
sc.method(2);
FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
workbook.write(fileOut);
fileOut.close();
Ensuite, le classeur.write n'est utilisé qu'une seule fois. Les données peuvent également être modifiées plusieurs fois.