使用POI使用完整的POIFSFileSystem来读写文档

时间:2018-12-27 07:57:03

标签: java apache-poi doc

我遇到了以下问题,就像每个人一样,我想用Word doc中的其他项目替换某些项目。 问题在于,该文档包含POIFSFileSystem中的页眉和页脚(我知道这一点是因为读取FS /回写文档-不做任何更改-会丢失这些信息,而读取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

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

现在的问题是,如何在“另存为”整个文件系统的同时更新文档,还是有一种方法可以强制文档包含文件系统中的所有内容?

1 个答案:

答案 0 :(得分:0)

HWPF总是放在暂存器中,因为DOC二进制文件格式是所有H可怕格式中最可怕的。因此,它实际上还没有准备好,并且在许多情况下也将成为越野车。

但是在您的特殊情况下,您的观察结果不可重现。使用apache poi 4.0.1HWPFDocument包含从*.doc文件创建后的页眉故事,也包含页脚故事。所以以下对我有用:

来源:

enter image description here

代码:

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

 }
}

结果:

enter image description here

因此,请再次进行检查,并确切告诉我们哪些内容对您不起作用。因为我们需要重现该代码,所以请像我对代码所做的那样提供minimal, complete, and verifiable example