Я открываю файл Excel (исходный код) в Java с помощью рабочей книги Apache POI, изменяю данные в определенном наборе ячеек, сохраняю рабочую книгу в отдельный файл, затем закрываю рабочую книгу (поскольку в документации говорится о закрытии Рабочая тетрадь, даже если она доступна только для чтения).
POI каждый раз изменяет данные в исходном файле Excel. Я пробовал несколько разных способов предотвратить это в соответствии с рекомендациями из документации POI, но эти методы не сработали
Вот две попытки, которые должны работать теоретически, но не работают.
Попытка 1 - установить исходный файл только для чтения
File file = new File("{path-to-existing-source-file}");
file.setReadOnly();
Workbook workbook = WorkbookFactory.create(file); // throws a FileNotFoundException
A FileNotFoundException
для «Доступ запрещен» выбрасывается на WorkbookFactory.create(file)
:
java.io.FileNotFoundException: {path-to-source-file-that-exists} (Access is denied)
at java.io.RandomAccessFile.open0(Native Method)
at java.io.RandomAccessFile.open(RandomAccessFile.java:316)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:243)
at org.apache.poi.poifs.nio.FileBackedDataSource.newSrcFile(FileBackedDataSource.java:158)
at org.apache.poi.poifs.nio.FileBackedDataSource.<init>(FileBackedDataSource.java:60)
at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:224)
at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:172)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:298)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:271)
at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:252)
at com.stackoverflow.MyClass(MyClass.java:71)
Исходный файл существует, и он действительно только для чтения.
Попытка 2 - использовать конструктор API POI, который позволяет явно установить только для чтения
File file = new File("{path-to-existing-source-file}");
Workbook workbook = WorkbookFactory.create(file, null, true); // true is read-only
// dataBean is just a container bean with the appropriate reference values
Sheet sheet = workbook.getSheet(dataBean.getSheetName());
Row row = sheet.getRow(dataBean.getRowNumber());
Cell cell = row.getCell(dataBean.getColumnNumber());
cell.setCellValue(dataBean.getValue());
// target is another File reference
OutputStream outStream = new FileOutputStream(new File("path-to-target-file"));
workbook.write(outStream); // throws InvalidOperationException
InvalidOperationException
выбрасывается во время вызова записи:
Caused by: org.apache.poi.openxml4j.exceptions.InvalidOperationException:
Operation not allowed, document open in read only mode!
at org.apache.poi.openxml4j.opc.OPCPackage.throwExceptionIfReadOnly(OPCPackage.java:551)
at org.apache.poi.openxml4j.opc.OPCPackage.removePart(OPCPackage.java:955)
at org.apache.poi.openxml4j.opc.PackagePart.getOutputStream(PackagePart.java:531)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.commit(XSSFWorkbook.java:1770)
at org.apache.poi.ooxml.POIXMLDocumentPart.onSave(POIXMLDocumentPart.java:463)
at org.apache.poi.ooxml.POIXMLDocument.write(POIXMLDocument.java:236)
at com.stackoverflow.MyClass(MyClass.java:90)
«Операция не разрешена, документ открыт в режиме только для чтения!». Конечно, он установлен только для чтения; Я не хочу, чтобы источник записывался, я просто хочу, чтобы все данные перешли к новой цели.
Что можно установить или изменить, чтобы не изменять источник при использовании POI?
Нашим текущим решением является создание дубликата исходного файла, но это не очень хорошее решение.