问题描述
在使用poi-tl word模版工具时,发现生成的文档中,图片格式为嵌入型,有的图片甚至被表格遮挡一半。而自己想要的图片格式为上下型环绕,并且图片需要居中。
问题分析
poi-tl渲染图片,使用的是org.apache.poi.xwpf.usermodel.XWPFRun的addPicture方法,该方法中有一段代码:CTInline inline = drawing.addNewInline();意思就是默认将图片转为inline类型,即行内元素。
然后我们把生成的嵌入型图片的文档转换成xml文件,然后再新建一个文档,插入图片后,设置图片为上下型环绕,保存为另一个xml,比较下两个xml的区别。嵌入型图片的xml是:
我们看到两种格式的图片标签分别为inline和anchor。所以如果我们想把图片设置为上下型环绕,需要重写poi的addPicture方法,把图片转为anchor类型。
我们仿照org.apache.poi.xwpf.usermodel.XWPFRun的addPicture方法,将CTInline inline = drawing.addNewInline();换成 CTAnchor anchor = drawing.addNewAnchor();,然后对比着xml,依次对anchor的字段进行赋值。结果发现生成的word无法正常打开,查了很多资料,都说poi的CTAnchor有问题,使用后无法正常打开生成的word。
此路不通,那我们就尝试另一种思路,我们不通过CTAnchor来生成anchor标签,而是直接使用xml,将xml赋给poi的drawing。具体的处理方式在后面。
xml标签和图片格式解析
在word中,在图片上右键,选择大小和位置,就可以看到如下界面:
图中的上下型对应的是xml中的<wp:wrapTopAndBottom/>标签,不同环绕方式该标签值不一样。如果需要其他格式,可以设置好后,把文档保存为xml,找到对应的标签。
图中的距正文上下左右距离,对应的是<wp:anchor distT=”71755″ distB=”71755″ distL=”114300″ distR=”114300″ …>中的disT、disB、disL、disR属性。
图中位置一栏,水平对齐方式居中、相对于栏对应的是xml中的<wp:positionH relativeFrom=”column”><wp:align>center</wp:align></wp:positionH>。
垂直-绝对位置0.1cm,下侧段落对应的是xml中的<wp:positionV relativeFrom=”paragraph”><wp:posOffset>36195</wp:posOffset></wp:positionV>。
我们可以根据不同的需要来设置不同的xml。
我使用的xml是
String xml = "<wp:anchor allowOverlap=\"0\" layoutInCell=\"1\" locked=\"0\" behindDoc=\"0\" relativeHeight=\"0\" simplePos=\"0\" distR=\"0\" distL=\"0\" distB=\"0\" distT=\"0\" " + " xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\"" + " xmlns:wp14=\"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing\"" + " xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" >" + "<wp:simplePos y=\"0\" x=\"0\"/>" + "<wp:positionH relativeFrom=\"column\">" + "<wp:align>center</wp:align>" + "</wp:positionH>" + "<wp:posit<a>本文来源gao($daima.com搞@代@#码8网^</a>ionV relativeFrom=\"paragraph\">" + "<wp:posOffset>0</wp:posOffset>" + "</wp:positionV>" + "<wp:extent cy=\""+height+"\" cx=\""+width+"\"/>" + "<wp:effectExtent b=\"0\" r=\"0\" t=\"0\" l=\"0\"/>" + "<wp:wrapTopAndBottom/>" + "<wp:docPr descr=\"Picture Alt\" name=\"Picture Hit\" id=\"0\"/>" + "<wp:cNvGraphicFramePr>" + "<a:graphicFrameLocks noChangeAspect=\"true\" xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" />" + "</wp: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=\""+relationId+"\"/>" + "<a:stretch>" + "<a:fillRect/>" + "</a:stretch>" + "</pic:blipFill>" + "<pic:spPr>" + "<a:xfrm>" + "<a:off y=\"0\" x=\"0\"/>" + "<a:ext cy=\""+height+"\" cx=\""+width+"\"/>" + "</a:xfrm>" + "<a:prstGeom prst=\"rect\">" + "<a:avLst/>" + "</a:prstGeom>" + "</pic:spPr>" + "</pic:pic>" + "</a:graphicData>" + "</a:graphic>" + "<wp14:sizeRelH relativeFrom=\"margin\">" + "<wp14:pctWidth>0</wp14:pctWidth>" + "</wp14:sizeRelH>" + "<wp14:sizeRelV relativeFrom=\"margin\">" + "<wp14:pctHeight>0</wp14:pctHeight>" + "</wp14:sizeRelV>" + "</wp:anchor>";