Wie wird die Aufforderung "Save changes?" Für xlsx-Dateien entfernt, die mit dem Apache POI XSSF erstellt wurden?

Nach dem Öffnen und sofortigen Schließen einer mit Apache POI XSSF erstellten xlsx-Datei werde ich aufgefordert, nicht gespeicherte Änderungen zu speichern. Soweit ich das beurteilen kann, geschieht dies, weil ich Formeln in der xlsx-Datei verwende.

aut javadoc sollte dies umgangen werden, indem @ gesetzt wirXSSFWorkbook.setForceFormulaRecalculation(true) Dies löst jedoch nicht das Problem.

Ich habe auch versucht, die Formeln manuell neu zu berechnen, bevor ich die Datei gespeichert habe.

SSCCE:

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class XSSFExample {

    public static void main(String[] args) {
        // Create workbook and sheet
        Workbook wb = new XSSFWorkbook();
        Sheet sheet = wb.createSheet("Sheet 1");

        // Create a row and put some cells in it.
        Row row = sheet.createRow((short) 0);
        row.createCell(0).setCellValue(5.0);
        row.createCell(1).setCellValue(5.0);
        row.createCell(2).setCellFormula("A1/B1");


        // Write the output to a file
        try (FileOutputStream fileOut = new FileOutputStream("XSSFExample.xlsx")) {
            wb.setForceFormulaRecalculation(false);
            System.out.println(wb.getForceFormulaRecalculation()); // prints "false"
            XSSFFormulaEvaluator.evaluateAllFormulaCells((XSSFWorkbook) wb); // this doesn't seem to make any difference
            wb.write(fileOut);
        } catch (IOException ex) {
            Logger.getLogger(XSSFExample.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Was kann ich tun, um die Datei zu erstellen, ohne nach dem ersten Öffnen zum Speichern aufgefordert zu werden?

Aktualisieren
Wie erwähnthere (https://poi.apache.org/spreadsheet/eval.html#recalculation Ich habe auch versucht, eine andere Methode manuell neu zu berechnen, ohne Erfolg. Selbst das erneute Lesen der Datei nach dem Speichern, erneuten Berechnen und Speichern als zweite Datei funktioniert nicht.

Update 2:
Betrachtet man die akzeptierte Antwort, konnte ich das Problem lösen, indem ich der obigen SSCCE folgende Codezeilen hinzufügte:
(Bitte beachten Sie, dass dies nur ein "schneller und schmutziger" Versuch war, das Problem zu lösen. Es sind wahrscheinlich viele Verbesserungen möglich.)

ZipFile zipFile = new ZipFile("XSSFExample.xlsx");
final ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("XSSFExample_NoSave.xlsx"));
for (Enumeration e = zipFile.entries(); e.hasMoreElements();) {
    ZipEntry entryIn = (ZipEntry) e.nextElement();
    if (!entryIn.getName().equalsIgnoreCase("xl/workbook.xml")) {
        zos.putNextEntry(entryIn);
        InputStream is = zipFile.getInputStream(entryIn);
        byte[] buf = new byte[1024];
        int len;
        while ((len = (is.read(buf))) > 0) {
            zos.write(buf, 0, len);
        }
    } else {
        zos.putNextEntry(new ZipEntry("xl/workbook.xml"));
        InputStream is = zipFile.getInputStream(entryIn);
        byte[] buf = new byte[1024];
        int len;
        while (is.read(buf) > 0) {
            String s = new String(buf);
            String searchFileVersion = "/relationships\"><workbookPr";
            String replaceFileVersion = "/relationships\"><fileVersion appName=\"xl\" lastEdited=\"5\" lowestEdited=\"5\" rupBuild=\"9303\"/><workbookPr";
            String searchCalcId = "<calcPr calcId=\"0\"/>";
            String replaceCalcId = "<calcPr calcId=\"" + String.valueOf(Integer.MAX_VALUE) + "\"/>";
            if (s.contains(searchFileVersion)) {
                s = s.replaceAll(searchFileVersion, replaceFileVersion);
            }
            if (s.contains(searchCalcId)) {
                s = s.replaceAll(searchCalcId, replaceCalcId);
            }
            len = s.trim().length();
            buf = s.getBytes();
            zos.write(buf, 0, (len < buf.length) ? len : buf.length);
        }
    }
    zos.closeEntry();
}
zos.close();

Antworten auf die Frage(4)

Ihre Antwort auf die Frage