XWPFDocument

时间:2017-08-03 08:44:16

标签: apache-poi xwpf

我遇到'XWPFDocument'问题。我的程序部分获取'docx'文件,并将所有内容从它们复制到一个输出'docx'文件。包括文字,表格,图片和公式。我在这方面有一个很好的结果,但最近我得到了一个错误:一张图片没有被复制到结果中。 this is sourcethis is result 结果,您可以看到“3.1.6.2”部分中的哪些图像被成功复制,但“3.1.6.1”中没有。

我是如何做到的:

for (XWPFRun run : oldParagraph.getRuns()) {

        XWPFRun newRun = newParagraph.createRun()

        if (run.getText(0) != null && !run.getText(0).isEmpty()) {
            .... copy text ....
        }
        if (run.getEmbeddedPictures() != null && run.getEmbeddedPictures().size() > 0) {
            for (XWPFPicture pic : run.getEmbeddedPictures()) {

                byte[] img = pic.getPictureData().getData()
                long cx = pic.getCTPicture().getSpPr().getXfrm().getExt().getCx()
                long cy = pic.getCTPicture().getSpPr().getXfrm().getExt().getCy()
                int pictureType = pic.getPictureData().getPictureType()

                XWPFDocument document = newParagraph.getDocument()

                String blipId = document.addPictureData(new ByteArrayInputStream(img), pictureType)
                createPictureCxCy(document, blipId, document.getNextPicNameNumber(pictureType), cx, cy)
            }
        }
    }

这里的关键点是:

 for (XWPFPicture pic : run.getEmbeddedPictures())

我从'run'获取嵌入的图片。 在坏文件中我有5个'段落',每个内部有1个'运行',其中4个有文本,1个是空的。通常,这个空的'run'正好嵌入了图片,并按照图片的顺序来判断。现在它空了。 但是在XWPFDocument中,这张图片存在于'pictures'和'packagePictures'列表中。

问题:此列表包含'XWPFPictureData'对象,不包含有关文档中位置和图片比例的信息。但'run.getEmbeddedPictures()'包含'XWPFPicture' - 我们需要什么。 有没有办法摆脱这种情况?

第一条评论的更新。

我查了一下:

        for(XWPFParagraph paragraph: document.getParagraphs()) {
            for (XWPFRun run : paragraph.getRuns()) {
                println "run text: " + run.getText(0)
                println "embedded picture count: " + run.getEmbeddedPictures().size()
            }
        }
        println "*** for document picture count: " + document.allPictures.size()

结果是:

run text:      3.1.6.1 В ряде районов сейсмические нагрузки  на СПБУ ...
embedded picture count: 0
run text:      Интегральное сейсмическое воздействие на  СПБУ ...
embedded picture count: 0
run text: null
embedded picture count: 0
run text:  Рис. 3.1.6.1 Обообщенный коэффициент динамичности: ...
embedded picture count: 0
run text:      Р01 — низшая частота горизонтальных колебаний
embedded picture count: 0
*** for document picture count: 4

我不知道为什么图片计数为4。 第二,关于锚。我没找到它。而且,我没有找到它和其他人 - 正确的文件。在一篇文章中我读到: “对象可以通过两种方式放置在文档中:内联或浮动。” - 只有浮动物体才有锚。

1 个答案:

答案 0 :(得分:1)

该文件不包含简单的图片,而是Add a drawing to a document中提到的绘图画布

此绘图画布包含彼此对齐的两个图片。

您可以在Word中打开后看到此内容,因为您可以选择三个对象。画布和其中的两个图片:

enter image description here

此绘图画布在document.xml元素的AlternateContent中表示:

<mc:AlternateContent>
 <mc:Choice Requires="wpg">
  <w:drawing>
   <wp:inline distT="0" distB="0" distL="0" distR="0">
    ...
   </wp:inline>
  </w:drawing>
 </mc:Choice>
 <mc:Fallback>
  <w:pict>
   ...
  </w:pict>
 </mc:Fallback>
</mc:AlternateContent>

Apache poi无法解释此XML。至少到现在为止。

可以编写自己的方法来解释这个XML。但这将是一项更大的任务。

如果这些文件不是太多,您可以做的最好的事情是使用*.docx打开Word,选择并将整个画布剪切到剪贴板,然后将其粘贴回{{ 1}}图片使用Paste Special。然后再次保存JPEG

或者从文档中获取两张图片。但它们有两次,因为*.docx元素提供了一个AlternateContent元素,其画布内容再次作为Base64编码的Fallback存档,并且还具有图片引用。这就是ZIP

的原因

只需解压缩*** for document picture count: 4存档,然后查看*.docx即可查看此内容。