открытый статический открытый OPCPackage (java.io.InputStream in) сообщает:
Открыть пакет.Примечание - использует немного больше памяти, чем open (String), которому не нужно хранить весь zip-файл в памяти, и он может использовать нативные методы
Так что это значит? открытый статический открытый OPCPackage (путь java.lang.String) , а также public static OPCPackage open(java.io.File file)
открывают файловую систему ZipPackage непосредственно из файла *.docx
.При этом используется меньше памяти, чем public static OPCPackage open(java.io.InputStream in)
, что сначала считывает файловую систему ZIP
в память, используя InputStream
.Но, с другой стороны, файл *.docx
теперь тоже открыт, и каждая попытка что-то записать в этот открытый файл должна приводить к ошибкам (несколько разных, не всегда NPE, для меня это java.io.EOFException: Unexpected end of ZLIB input stream
с использованием apache poi 4.0.1
[1]) до тех пор, пока действие записи не только выполняет запись в открытую файловую систему ZIP
, но и в открытый файл *.docx
.
[1]: Только что протестировано, я получаю именно ваш NPE, используя apache poi 3.17
в Windows 10. Ubuntu Linux просто падает.
Вывод:
Открытие OPCPackage
(ZipPackage
) из File
напрямую и последующая запись в другой File
работает.Открытие OPCPackage
из File
напрямую, а затем запись в тот же File
не работает.
Это верно для всех форматов файлов Office Open XML, которые обрабатываются с использованием ZipPackage
в apache poi
.
Чтобы получить преимущество от использования меньшего количества памяти при создании XWPFDocument
из-за использования File
вместо InputStream
и, тем не менее, возможности записи в один и тот же файл, мы могли бы использовать временную копиюфайл выглядит следующим образом:
import java.io.FileOutputStream;
import java.io.File;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
public class WordReadAndReWrite {
public static void main(String[] args) throws Exception {
String filePath = "WordDocument.docx";
String tmpFilePath = "~$WordDocument.docx";
File file = Files.copy(Paths.get(filePath), Paths.get(tmpFilePath), StandardCopyOption.REPLACE_EXISTING).toFile();
XWPFDocument doc = new XWPFDocument(OPCPackage.open(file));
// Replace paragraphs.
FileOutputStream out = new FileOutputStream(filePath);
doc.write(out);
out.close();
doc.close();
Files.deleteIfExists(Paths.get(tmpFilePath));
}
}
Конечно, недостатком является использование дополнительного хранилища файлов, даже временного.