Bug 60339 - POI cannot add Picture to docx by CTAnchor
Summary: POI cannot add Picture to docx by CTAnchor
Status: RESOLVED FIXED
Alias: None
Product: POI
Classification: Unclassified
Component: XWPF (show other bugs)
Version: 3.14-FINAL
Hardware: PC All
: P2 normal (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-11-04 10:08 UTC by apache
Modified: 2016-12-15 06:22 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description apache 2016-11-04 10:08:40 UTC
POI XWPF usage anchor tag add position picture failure. 
Using inline is ok, but using anchor can not open word, prompt /word/document.xml line 2, col ...

docx4j is ok.

//========================================
// code: @see org.apache.poi.xwpf.usermodel.XWPFRun#addPicture
//========================================
XWPFDocument doc = new XWPFDocument();
XWPFParagraph p = doc.createParagraph();
XWPFRun r = p.createRun();

String relationId = doc.addPictureData(new FileInputStream(filename), XWPFDocument.PICTURE_TYPE_PNG);

String xml = readFile("doc.xml");
xml = xml.replaceAll("embed=\"rId3\"", "embed=\"" + relationId + "\"");

CTDrawing drawing = r.getCTR().addNewDrawing();
drawing.set(XmlToken.Factory.parse(xml, DEFAULT_XML_OPTIONS));

CTPicture pic = getCTPictures(drawing).get(0);

XWPFPicture xwpfPicture = new XWPFPicture(pic, r);
r.getEmbeddedPictures().add(xwpfPicture);

... 
public List<CTPicture> getCTPictures(XmlObject o) {
        List<CTPicture> pictures = new ArrayList<CTPicture>();
        XmlObject[] picts = o.selectPath("declare namespace pic='" 
            + CTPicture.type.getName().getNamespaceURI() + "' .//pic:pic");
        for (XmlObject pict : picts) {
            if (pict instanceof XmlAnyTypeImpl) {
                // Pesky XmlBeans bug - see Bugzilla #49934
                try {
                    pict = CTPicture.Factory.parse(pict.toString(), 
                        DEFAULT_XML_OPTIONS);
                } catch (XmlException e) {
                    throw new POIXMLException(e);
                }
            }
            if (pict instanceof CTPicture) {
                pictures.add((CTPicture) pict);
            }
        }
        return pictures;
}

//==============================
// doc.xml:
//==============================
<anchor allowOverlap="true" layoutInCell="false" locked="false" behindDoc="false" relativeHeight="0" simplePos="false" distR="0" distL="0" distB="0" distT="0">
	<simplePos y="0" x="0"/>
	<positionH relativeFrom="margin">
		<align>right</align>
	</positionH>
	<positionV relativeFrom="page">
		<posOffset>360000</posOffset>
	</positionV>
	<extent cy="4997254" cx="5732145"/>
	<effectExtent b="0" r="0" t="0" l="0"/>
	<wrapNone/>
	<docPr descr="Picture Alt" name="Picture Hit" id="0"/>
	<cNvGraphicFramePr>
		<a:graphicFrameLocks noChangeAspect="true" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" />
	</cNvGraphicFramePr>
	<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
		<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
			<pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
				<pic:nvPicPr>
					<pic:cNvPr name="Picture Hit" id="1"/>
					<pic:cNvPicPr/>
				</pic:nvPicPr>
				<pic:blipFill>
					<a:blip r:embed="rId3"/>
					<a:stretch>
						<a:fillRect/>
					</a:stretch>
				</pic:blipFill>
				<pic:spPr>
					<a:xfrm>
						<a:off y="0" x="0"/>
						<a:ext cy="4997254" cx="5732145"/>
					</a:xfrm>
					<a:prstGeom prst="rect">
						<a:avLst/>
					</a:prstGeom>
				</pic:spPr>
			</pic:pic>
		</a:graphicData>
	</a:graphic>
</anchor>
Comment 1 apache 2016-12-15 06:22:17 UTC
The problem has been resolved.
By reference docx4j project, it is found that XML is missing a namespace prefix.
Resolved by modify doc.xml.