【问题标题】:Using POI To read/write a doc with the full POIFSFileSystem使用 POI 读取/写入具有完整 POIFSFileSystem 的文档
【发布时间】:2018-12-27 07:57:03
【问题描述】:

我有以下问题,就像大家一样,我想用 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

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

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

【问题讨论】:

    标签: java apache-poi doc


    【解决方案1】:

    HWPF 的东西总是在暂存器中,因为DOC 二进制文件格式是所有Horrible 格式中最可怕的。所以它真的没有准备好,而且在很多情况下也会有问题。

    但在您的特殊情况下,您的观察结果是不可重复的。使用apache poi 4.0.1HWPFDocument 包含从*.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();
    
     }
    }
    

    结果:

    所以请再次检查并告诉我们究竟是什么不适合您。因为我们需要复制它,所以请提供minimal, complete, and verifiable example,就像我对我的代码所做的那样。

    【讨论】:

    • 我很想给你造成麻烦的文件,但无法完成。我所知道的是标题部分存在,但其中有一张图片完全丢失了。 (模板不是使用 POI 创建的,但可能是使用 word 创建的)。无论哪种方式,我都会使用 DOCX,因为这个问题不受此问题的困扰......(将文件另存为......抑制它或 POI 正确处理它。)
    • @gougoul:“标题部分存在,但其中有一张图片完全丢失了”:也无法复制。如果我的TemplateDOCWithHeaderFooter.doc在标题中包含图片,运行我的代码后它不会丢失在我的ResultDOCWithHeaderFooter.doc中。 “无论如何,我都会使用 DOCX”:是的,如果可能的话,这可能是最好的。在 21 世纪,那些可怕的二进制文档格式,如 *.doc 应该默默地消亡。
    • 是的,这绝对是真的。还是要谢谢你的帮助 !十年前,我花了很长时间编写一些代码来生成 XLS 文件。真是一团糟
    猜你喜欢
    • 1970-01-01
    • 2016-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    • 1970-01-01
    • 2012-03-10
    • 2017-03-25
    相关资源
    最近更新 更多