gpt4 book ai didi

java - Apache Poi Word 文档打开报 NullPointerException

转载 作者:行者123 更新时间:2023-11-30 10:06:33 27 4
gpt4 key购买 nike

我编写了一个程序,可以打开 Microsoft Word 文档进行读写。

此程序读取 Word 段落和表格并替换占位符。运行后,程序将文档保存在与读取时相同的文件路径下。

如果我使用此选项打开文档,我得到一个 NullPointerException:

String filePath = "...";
XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath));
// Replace paragraphs.
doc.write(new FileOutputStream(filePath));
doc.close();

这是堆栈跟踪:

java.lang.NullPointerException
at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:147)
at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:225)
Caused by: java.lang.NullPointerException
at org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream.read(ZipSecureFile.java:211)
at org.apache.xerces.impl.XMLEntityManager$RewindableInputStream.readAndBuffer(Unknown Source)
at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
at org.apache.poi.util.DocumentHelper.readDocument(DocumentHelper.java:140)
at org.apache.poi.POIXMLTypeLoader.parse(POIXMLTypeLoader.java:163)
at org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument$Factory.parse(Unknown Source)
at org.apache.poi.POIXMLProperties.<init>(POIXMLProperties.java:78)
at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:145)

如果我使用这个选项:

String filePath = "...";
InputStream fis = new FileInputStream(filePath);
XWPFDocument doc = new XWPFDocument(OPCPackage.open(fis));
// Replace paragraphs.
doc.write(new FileOutputStream(filePath));
doc.close();

工作正常。我尝试将文档保存在另一个路径中,并且这种情况正常。

所以我不明白为什么在使用open(String path)方法打开Word文档时会出现错误信息。

OPCPackage.open(InputStream in) 和 OPCPackage.open(String path) 方法有什么区别?为什么我有 NullPointerException?

最佳答案

public static OPCPackage open(java.io.InputStream in)状态:

Open a package. Note - uses quite a bit more memory than open(String), which doesn't need to hold the whole zip file in memory, and can take advantage of native methods

那是什么意思呢? public static OPCPackage open(java.lang.String path)以及 public static OPCPackage open(java.io.File file) 正在打开 ZipPackage文件系统直接来自 *.docx 文件。这比 public static OPCPackage open(java.io.InputStream in) 使用更少的内存首先使用 InputStreamZIP 文件系统读入内存.但另一方面,*.docx 文件现在也已打开,每次尝试向该打开的文件中写入内容都会导致错误(多种不同,并不总是 NPE,对我来说是 java.io.EOFException: Unexpected end of ZLIB input stream using apache poi 4.0.1 [1]) 只要写入操作不是真的只写入打开的 ZIP 文件系统,但进入打开的 *.docx 文件。

[1]:刚刚测试,我在 Windows 10 上使用 apache poi 3.17 得到了你的 NPE。Ubuntu Linux 只是崩溃。

结论:

直接从File 打开OPCPackage (ZipPackage) 然后写入另一个File 是可行的。直接从 File 打开 OPCPackage 然后写入同一个 File 是行不通的。

对于在 apache poi 中使用 ZipPackage 处理的所有 Office Open XML 文件格式都是如此。

由于使用 File 而不是 InputStream 而在创建 XWPFDocument 时获得使用较少内存的优势,并且仍然能够写入到同一个文件中,我们可以使用该文件的临时副本,如下所示:

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));
}

}

当然这有使用额外文件存储的缺点,即使是临时的。

关于java - Apache Poi Word 文档打开报 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54601006/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com