【问题标题】:Replaced picture content control with picture - Word reports Catastrophic failure when opening file用图片替换图片内容控件 - 打开文件时 Word 报告灾难性故障
【发布时间】:2016-06-02 13:27:48
【问题描述】:

我需要用图片替换图片内容控件。代码运行正常,但是当 Word 尝试打开文件时它报告 Catastophic failure

代码基本上是来自 docx4j 示例的 ImageAdd 类的调整版本。有趣的是,转换为 PDF 的文档显示正常。

List<SdtElement> contentControls = findContentControls(wordMLPackage.getMainDocumentPart(InputStream));

for (SdtElement contentControl : contentControls) {
    for (Object ob : contentControl.getSdtContent().getContent()) {
        traverseEelements(ob, value);
    }
}

static List<SdtElement> findContentControls(ContentAccessor container) throws Docx4JException, JAXBException {
    List<SdtElement> sdtElements = new LinkedList<SdtElement>();
    for (Object o : container.getContent()) {
        Object unwrapped = XmlUtils.unwrap(o);
        if (unwrapped instanceof SdtElement) {
            sdtElements.add((SdtElement) unwrapped);
        }
        if (unwrapped instanceof ContentAccessor) {
            List<SdtElement> list = findContentControls((ContentAccessor) unwrapped);
            sdtElements.addAll(list);
        }
    }
    return sdtElements;
}

private void traverseEelements(Object object, String value) {
    if (object instanceof org.docx4j.wml.Text) {
        Text text = (org.docx4j.wml.Text) object;
        text.setValue(value);
    } else if (object instanceof ContentAccessor) {
        ContentAccessor contentAccessor = (ContentAccessor) object;
        for (Object ob : contentAccessor.getContent()) {
            traverseEelements(ob, value);
        }
    } else if (object instanceof JAXBElement) {
        Object v = ((JAXBElement<?>) object).getValue();
        if (v instanceof ContentAccessor) {
            ContentAccessor contentAccessor = (ContentAccessor) v;
            for (Object ob : contentAccessor.getContent()) {
                traverseEelements(ob, value);
            }
        } else if (v instanceof org.docx4j.wml.Text) {
            Text text = (org.docx4j.wml.Text) v;
            text.setValue(value);
        } else if (v instanceof org.docx4j.wml.Drawing) {
            Drawing drawing = (Drawing) v;
            try {
                File file = new File("C://Users//user//Pictures//test.png" );
                java.io.InputStream is = new java.io.FileInputStream(file );
                long length = file.length();  
                if (length > Integer.MAX_VALUE) {
                    System.out.println("File too large!!");
                }
                byte[] bytes = new byte[(int)length];
                int offset = 0;
                int numRead = 0;
                while (offset < bytes.length
                        && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
                    offset += numRead;
                }
                // Ensure all the bytes have been read in
                if (offset < bytes.length) {
                    System.out.println("Could not completely read file "+file.getName());
                }
                is.close();
                String filenameHint = null;
                String altText = null;
                int id1 = 0;
                int id2 = 1;
                BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes );
                Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false);
                drawing.getAnchorOrInline().add(inline);
            } catch(Exception e) {
                logger.error(e);
            }
        } else {
            logger.error("unspupported element found: " + object.getClass());
        }
    } else {
        logger.error("unspupported element found: " + object.getClass());
    }
}

编辑

Link to the file

【问题讨论】:

  • 在某处上传 docx?
  • 嗨,Jason,我期待你 :) 我在问题末尾添加了文件链接

标签: java image docx4j word-2013


【解决方案1】:

你有一个 w:drawing 包含 wp:anchor 和 wp:inline:

       <w:drawing>
          <wp:anchor distT="0" distB="0" distL="114300" distR="114300" simplePos="false" relativeHeight="251658240" behindDoc="true" locked="false" layoutInCell="true" allowOverlap="true">
            <wp:simplePos x="0" y="0"/>
            <wp:positionH relativeFrom="column">
              <wp:posOffset>0</wp:posOffset>
            </wp:positionH>
            <wp:positionV relativeFrom="paragraph">
              <wp:posOffset>0</wp:posOffset>
            </wp:positionV>
            <wp:extent cx="18288" cy="18288"/>
            <wp:effectExtent l="0" t="0" r="0" b="0"/>
            <wp:wrapNone/>
            <wp:docPr id="1" name="Picture 1"/>
            <wp:cNvGraphicFramePr>
              <a:graphicFrameLocks noChangeAspect="true"/>
            </wp:cNvGraphicFramePr>
            <a:graphic>
              <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
                <pic:pic>
                  <pic:nvPicPr>
                    <pic:cNvPr id="0" name="Picture 1"/>
                    <pic:cNvPicPr>
                      <a:picLocks noChangeAspect="true" noChangeArrowheads="true"/>
                    </pic:cNvPicPr>
                  </pic:nvPicPr>
                  <pic:blipFill>
                    <a:blip cstate="print" r:embed="rId4">
                      <a:extLst>
                        <a:ext uri="{28A0092B-C50C-407E-A947-70E740481C1C}">
                          <a14:useLocalDpi xmlns:a14="http://schemas.microsoft.com/office/drawing/2010/main" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" val="0"/>
                        </a:ext>
                      </a:extLst>
                    </a:blip>
                    <a:srcRect/>
                    <a:stretch>
                      <a:fillRect/>
                    </a:stretch>
                  </pic:blipFill>
                  <pic:spPr bwMode="auto">
                    <a:xfrm>
                      <a:off x="0" y="0"/>
                      <a:ext cx="18288" cy="18288"/>
                    </a:xfrm>
                    <a:prstGeom prst="rect">
                      <a:avLst/>
                    </a:prstGeom>
                    <a:noFill/>
                    <a:ln>
                      <a:noFill/>
                    </a:ln>
                  </pic:spPr>
                </pic:pic>
              </a:graphicData>
            </a:graphic>
          </wp:anchor>
          <wp:inline distT="0" distB="0" distL="0" distR="0">
            <wp:extent cx="952500" cy="333375"/>
            <wp:effectExtent l="0" t="0" r="0" b="0"/>
            <wp:docPr id="0" name="" descr=""/>
            <wp:cNvGraphicFramePr>
              <a:graphicFrameLocks noChangeAspect="true"/>
            </wp:cNvGraphicFramePr>
            <a:graphic>
              <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
                <pic:pic>
                  <pic:nvPicPr>
                    <pic:cNvPr id="1" name=""/>
                    <pic:cNvPicPr/>
                  </pic:nvPicPr>
                  <pic:blipFill>
                    <a:blip r:embed="rId7"/>
                    <a:stretch>
                      <a:fillRect/>
                    </a:stretch>
                  </pic:blipFill>
                  <pic:spPr>
                    <a:xfrm>
                      <a:off x="0" y="0"/>
                      <a:ext cx="952500" cy="333375"/>
                    </a:xfrm>
                    <a:prstGeom prst="rect">
                      <a:avLst/>
                    </a:prstGeom>
                  </pic:spPr>
                </pic:pic>
              </a:graphicData>
            </a:graphic>
          </wp:inline>
        </w:drawing>

这是导致失败的原因。

【讨论】:

  • Jason,我已经阅读过它here 并且因为在我的情况下图片内容控件设置为浮动在文本后面(即生成锚元素),我尝试不使用此选项。现在我看到了同样的错误,但在 w:drawing 中我有两个 wp:inline。好像我不需要添加图像而是编辑现有的 - 需要更改代码。打算进一步检查...
  • 一般来说,如果您希望图片浮动,最好将图片放在富文本内容控件中,因为 Microsoft 不支持浮动图片内容控件。在 Word 中有很多方法可以做到这一点,但在过去的一两年里,他们已经将其中一些方法变成灰色。
【解决方案2】:

感谢 Jason 的 answer,让我清楚了是什么在困扰我。 我的问题是我正在添加新的内联图像,而我已经从图片内容控件中获得了一个。快速获胜是删除这个内联并添加你以编程方式准备的那个

BinaryPartAbstractImage imagePart = 
    BinaryPartAbstractImage.createImagePart(wordMLPackage, bytesImage);
Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false);
Inline inlineOriginal = (Inline) drawing.getAnchorOrInline().get(0);            
drawing.getAnchorOrInline().add(inline);            
drawing.getAnchorOrInline().remove(inlineOriginal);

我会尝试更多地解决这个问题,并希望找到更通用的模板和代码方法(我会尝试编辑这个答案)。我需要检查的是如何在文档中维护/添加锚定图像,但这是我要处理的另一个具体问题。再次感谢杰森!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-04
    • 2016-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多