java - 使用 POI 读取/写入具有完整 POIFSFileSystem 的文档
问题描述
我有以下问题,就像每个人一样,我想用 Word doc 中的其他项目替换一些项目。问题的问题是,文档包含页眉和页脚,它们是其中的一部分POIFSFileSystem
(我知道这是因为读取 FS / 写回 doc - 没有任何更改 - 会丢失这些信息,而读取 FS / 将其写回作为新的文件没有)。
目前我这样做:
POIFSFileSystem pfs = new POIFSFileSystem(fis);
HWPFDocument document = new HWPFDocument(pfs);
Range r1 = document.getRange();
…
document.write();
ByteArrayOutputStream bos = new ByteArrayOutputStream(50000);
pfs.writeFilesystem(bos);
pfs.close();
但是,这失败了,并出现以下错误:
Opened read-only or via an InputStream, a Writeable File is required
如果我不重写文档,它可以正常工作,但我的更改会丢失。相反,如果我只保存文档而不是文件系统,我会丢失页眉/页脚。
现在的问题是,如何在“另存为”整个文件系统的同时更新文档,或者有没有办法强制文档包含文件系统中的所有内容?
解决方案
这些HWPF
东西总是在暂存器中,因为二进制文件格式是所有可恶格式DOC
中最可怕的。H
所以它真的没有准备好,而且在很多情况下也会有问题。
但是在您的特殊情况下,您的观察结果是不可重复的。从文件创建后apache poi 4.0.1
,使用HWPFDocument
包含页眉故事,其中还包含页脚故事。*.doc
所以以下对我有用:
资源:
代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hwpf.*;
import org.apache.poi.hwpf.usermodel.*;
public class ReadAndWriteDOCWithHeaderFooter {
public static void main(String[] args) throws Exception {
HWPFDocument document = new HWPFDocument(new FileInputStream("TemplateDOCWithHeaderFooter.doc"));
Range bodyRange = document.getRange();
System.out.println(bodyRange);
for (int p = 0; p < bodyRange.numParagraphs(); p++) {
System.out.println(bodyRange.getParagraph(p).text());
if (bodyRange.getParagraph(p).text().contains("<<NAME>>"))
bodyRange.getParagraph(p).replaceText("<<NAME>>", "Axel Richter");
if (bodyRange.getParagraph(p).text().contains("<<DATE>>"))
bodyRange.getParagraph(p).replaceText("<<DATE>>", "12/21/1964");
if (bodyRange.getParagraph(p).text().contains("<<AMOUNT>>"))
bodyRange.getParagraph(p).replaceText("<<AMOUNT>>", "1,234.56");
System.out.println(bodyRange.getParagraph(p).text());
}
System.out.println("==============================================================================");
Range overallRange = document.getOverallRange();
System.out.println(overallRange);
for (int p = 0; p < overallRange.numParagraphs(); p++) {
System.out.println(overallRange.getParagraph(p).text()); // contains all inclusive header and footer
}
FileOutputStream out = new FileOutputStream("ResultDOCWithHeaderFooter.doc");
document.write(out);
out.close();
document.close();
}
}
结果:
因此,请再次检查并准确告诉我们什么不适合您。因为我们需要复制它,所以请提供一个最小的、完整的和可验证的示例,就像我对我的代码所做的那样。
推荐阅读
- python-3.x - 如何在与 RHEL 相同的 python 3.7 shell 提示符下获取执行的命令历史记录
- mysql - 尝试插入新表时出现 MySQL 错误 1064 (42000)
- angular - 如何绑定 PrimeNG MenuItem 的“禁用”属性?
- nativescript - 像 nativescript 插件一样实现 IRLDocumentScanner CocoaPods
- javascript - Internet连接丢失时PWA黑屏(死机白屏)?
- python - 如何在 Django 中使用 BeautifulSoup?
- angular - 即使在 angular.json 中有正确的路径,Angular 也会显示样式 scss 错误
- javascript - 具有隐藏表单值选项的远程用户地址
- javascript - 页面可见性检测 - 不知道如何设置初始状态
- asp.net-mvc - Asp.Net MVC EF Web 应用的 Azure SQL 用户和连接字符串