0

我需要用图片替换图片内容控件。代码运行正常,但当 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());
    }
}

编辑

链接到文件

4

2 回答 2

1

你有 aw: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>

这就是失败的原因。

于 2016-06-07T06:49:04.027 回答
0

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

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

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

于 2016-06-07T08:39:43.760 回答