首页 > 解决方案 > 使用 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

如果我不重写文档,它可以正常工作,但我的更改会丢失。相反,如果我只保存文档而不是文件系统,我会丢失页眉/页脚。

现在的问题是,如何在“另存为”整个文件系统的同时更新文档,或者有没有办法强制文档包含文件系统中的所有内容?

标签: javaapache-poidoc

解决方案


这些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();

 }
}

结果:

在此处输入图像描述

因此,请再次检查并准确告诉我们什么不适合您。因为我们需要复制它,所以请提供一个最小的、完整的和可验证的示例,就像我对我的代码所做的那样。


推荐阅读