Java Apache POI:从 .doc 文件读取/写入问题 [英] Java Apache POI : Read / Write from .doc file issue

查看:44
本文介绍了Java Apache POI:从 .doc 文件读取/写入问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写代码来读取 .doc 文件作为模板,并在多次迭代后将数据写入新的 .doc 文件中.我的代码似乎有一些我无法弄清楚的简单问题.

I am writing a code to read a .doc file as a template and write data in new .doc file after various iterations. My code seems to have some simple issue that I am not able to figure out.

下面是我写的代码,[我只在 stackoverflow 的某个地方得到了基本的骨架.]

Below is the code I have written, [I got basic skeleton somewhere on stackoverflow only.]

public class HWPFTest {

  public static void main(String[] args) {
        String inputFile = "F:\\docx\\input.doc";
        String outputFile = "F:\\docx\\output.doc";
        POIFSFileSystem fs = null;

        try {
              for (int i = 0; i < 3; i++) {
                    fs = new POIFSFileSystem(new FileInputStream(inputFile));
                    HWPFDocument doc = new HWPFDocument(fs);
                    System.out.println("LOOOOOOOOOOOOP ----> " + i);
                    doc = replaceText(doc, "$count", String.valueOf(i));
                    doc = replaceText(doc, "$filename", "FileName" + i);
                    doc = replaceText(doc, "$inputFile", "Input" + i);
                    doc = replaceText(doc, "$outputFile", "Output" + i);
                    doc = replaceText(doc, "$message", "Message" + i);
                    doc = replaceText(doc, "$snap", "Snapshot" + i);
                    saveWord(outputFile, doc);
              }
              System.out.println("DONE...");
        }
        catch (FileNotFoundException e) {
              e.printStackTrace();
        } catch (IOException e) {
              e.printStackTrace();
        }
  }

  private static HWPFDocument replaceText(HWPFDocument doc, String findText, String replaceText) {
        Range r1 = doc.getRange();
        for (int i = 0; i < r1.numSections(); ++i) {
              Section s = r1.getSection(i);
              for (int x = 0; x < s.numParagraphs(); x++) {
                    Paragraph p = s.getParagraph(x);
                    for (int z = 0; z < p.numCharacterRuns(); z++) {
                          CharacterRun run = p.getCharacterRun(z);
                          String text = run.text();
                          if (text.contains(findText)) {
                               run.replaceText(findText, replaceText);
                               System.out.println("findText: " + findText + " replaceText: " + replaceText);
                          }
                    }
              }
        }
        return doc;
  }


  private static void saveWord(String filePath, HWPFDocument doc) throws FileNotFoundException, IOException {
        FileOutputStream out = null;
        try {
              // Add true to make the data append possible in output stream.
              out = new FileOutputStream(filePath, true);
              doc.write(out);
              out.flush();
        } catch (Exception ex) {
              ex.printStackTrace();
        } finally {
              out.close();
        }
  }

}

代码运行没有任何问题.这是 input.doc 的样子,

The code works without any issues. Here is how the input.doc looks,

运行成功后,也会生成output.doc.但问题是它只包含第一个循环的数据.

After the successful run, the output.doc is also generated. But the issue is that it contains data for only first loop.

理想情况下,它应该包含所有 3 次迭代的数据,但它只包含第一个的数据,然后什么都没有.它在执行过程中也不会显示任何错误/异常.我还确保 outputstream 将 append 选项设置为 true.

Ideaally, it should contain data for all the 3 iterations, but it contains data for only first and then there is nothing. It doesn't show any error / exception during execution as well. I have also made sure that outputstream will have append option as true.

这是 output.doc 的样子,

This is how the output.doc looks,

不确定,我做错了什么.

Not sure, what I am doing wrong.

当我运行程序时,我可以在下面的输出中看到,

When I run the program, I can see in the output below,

<代码>LOOOOOOOOOOOOP ----> 0查找文本:$count 替换文本:0findText: $filename 替换文本: FileName0findText:$inputFile 替换文本:Input0findText: $outputFile replaceText: Output0findText: $message replaceText: Message0findText: $snap replaceText: Snapshot0LOOOOOOOOOOOOP ----> 1查找文本:$count 替换文本:1findText: $filename replaceText: FileName1findText:$inputFile 替换文本:Input1findText: $outputFile replaceText: Output1findText: $message replaceText: Message1findText: $snap replaceText: Snapshot1LOOOOOOOOOOOOP ----> 2查找文本:$count 替换文本:2findText: $filename replaceText: FileName2findText:$inputFile 替换文本:Input2findText: $outputFile replaceText: Output2findText: $message replaceText: Message2findText: $snap replaceText: Snapshot2完毕...

因为我在每次迭代中都将输入文件初始化为新文件.所以我确实在迭代过程中找到了所有的 $ 元素.只是它们没有附加到最终文件中.

As I am initiating the input file as new in every iteration. So I do find all the $ elements during iteration. It's just that they don't get appended in final file.

有人可以帮忙吗?非常感谢.

Can someone please help here? Thanks a lot.

推荐答案

显然且令人惊讶的是,Apache POI 没有任何方法可以将附加内容写入现有的 Word 文档.所以上述方法不起作用.

Apparently and surprisingly, Apache POI doesn't have any method to write with append to an existing word document. So above approach doesn't work.

我也尝试过 Apache FileUtils,但它没有保留 word 文档的格式.我也尝试过 docx4j,但仅适用于 docx 文件并且它的合并实用程序类是付费的.

I also tried Apache FileUtils, but it doesn't retain the formating of the word document. I also tried docx4j, but in only works on docx files and its merging utility class is paid.

还有另一个框架 Aspose Words,它提供了更好的控制和灵活性.它允许您将内容附加到现有文档,限制为 1150 个字符.但这对我的要求来说太过分了,因为我的写作没有超过设定的限制.

There is another framework, Aspose Words, which provides much better control and flexibility. It lets you append the content to existing document, with a limitation of 1150 characters. But that's way too much for my requirement to worry for as my writing wasn't more than the set limit.

所以我用它来实现我想做的事.终于成功了.

So I used that to achieve what I wanted to do. It's a success finally.

感谢@D 的帮助.克劳昌卡

Thanks for the help @D. Krauchanka

这篇关于Java Apache POI:从 .doc 文件读取/写入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆