Java ApachePOI Word文档打开时出现NullPointerException
我编写了一个程序,可以打开MicrosoftWord文档进行读写 该程序读取单词段落和表格,并替换占位符。运行后,程序将文档保存在与读取相同的文件路径 如果使用此选项打开文档,则会出现NullPointerException:Java ApachePOI Word文档打开时出现NullPointerException,java,apache,ms-word,apache-poi,Java,Apache,Ms Word,Apache Poi,我编写了一个程序,可以打开MicrosoftWord文档进行读写 该程序读取单词段落和表格,并替换占位符。运行后,程序将文档保存在与读取相同的文件路径 如果使用此选项打开文档,则会出现NullPointerException: String filePath = "..."; XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath)); // Replace paragraphs. doc.write(new FileOutput
String filePath = "...";
XWPFDocument doc = new XWPFDocument(OPCPackage.open(filePath));
// Replace paragraphs.
doc.write(new FileOutputStream(filePath));
doc.close();
以下是stacktrace:
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)
工作正常。
我试图将文档保存在另一个路径中,这种情况可以正常工作
因此,我不明白为什么在使用open(stringpath)
方法打开Word文档时会收到错误消息
OPCPackage.open(InputStream in)和OPCPackage.open(String path)方法之间有什么区别?为什么我会有NullPointerException?状态:
打开一个包裹。注意-使用的内存比打开的(字符串)内存要多得多,
它不需要将整个zip文件保存在内存中,并且可以
本地方法的优势
那是什么意思?以及publicstaticopcpackage open(java.io.File文件)
都是直接从*.docx
文件打开文件系统。它使用的内存少于publicstaticopcpackage open(java.io.InputStream in)
首先使用InputStream将ZIP
文件系统读入内存的内容。但另一方面,*.docx
文件现在也打开了,每次尝试向打开的文件中写入内容都会导致错误(多个不同的,不一定是NPE,对我来说它是java.io.EOFException:使用ApachePOI4.0.1
[1]的ZLIB输入流意外结束)只要写入操作不仅写入打开的ZIP
文件系统,而且写入打开的*.docx
文件
[1] :刚刚测试过,我在Windows10上使用ApachePOI3.17获得了您的NPE。Ubuntu Linux只是崩溃了
结论:
直接从文件
打开OPCPackage
(ZipPackage
),然后写入另一个文件
即可。直接从文件
打开OPCPackage
,然后写入同一文件
不起作用
这适用于所有使用apache poi
中的ZipPackage
处理的Office Open XML文件格式
为了在创建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));
}
}
当然,这样做的缺点是使用额外的文件存储,即使是临时的。可能与@Zephyr重复:并非所有NPE都是Q/a的重复。在这里,NPE是从ApachePOI
库深处的类抛出的。因此,必须允许询问为什么会发生这种情况。否则,使用库就完全过时了,因为每个用户都必须深入挖掘库的内部,才能了解NPE发生的原因。@AxelRichter-I,无可否认,没有仔细检查堆栈跟踪。我撤回了投票决定结束投票。谢谢:)
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));
}
}