问题描述
有人知道Office Open XML wrapPolygon
中x
和y
的含义和单位是什么吗?
这与图片大小本身无关.它可以是所有可能大小的正方形或矩形大小的图片.
因此,此坐标的原点应由父 XML 元素指定."并且多边形从图片左上角的 x
=0 和 y
=0 开始,单位不能是 EMU
宽度和高度.而且由于21600 x 21600的正方形多边形如果图片是矩形会导致矩形包点,所以连多边形本身的含义都不清楚.
这是否记录在某处?
好吧,似乎没有人回答.所以我至少会提供一个例子来说明为什么这个规则:一个正方形的多边形 21600 x 21600 会导致完全宽度 x 高度的包裹点,而与图片大小无关."可能有用.
如果需要设置更复杂的环绕点,例如椭圆,只需将此椭圆描绘为 21600 x 21600 的正方形,与图片大小无关.这比根据实际图片大小计算包裹点要简单得多.因此,我们可以强制 Word
将文字紧紧地包裹在图片周围.
示例代码:
import java.io.FileOutputStream;导入 java.io.FileInputStream;导入 java.io.InputStream;导入 org.apache.poi.xwpf.usermodel.*;导入 org.apache.poi.util.Units;导入 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;导入 org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;导入 org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;公共类 WordPicturesWrapTight {私有静态 CTAnchor getAnchorWithGraphic(CTGraphicalObject 图形对象,字符串绘图描述,整数宽度,整数高度,int left, int top) 抛出异常 {字符串anchorXML ="<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "+"simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"1\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"+"<wp:simplePos x=\"0\" y=\"0\"/>"+"<wp:positionH relativeFrom=\"column\"><wp:posOffset>"+left+"</wp:posOffset></wp:positionH>"+"<wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>"+top+"</wp:posOffset></wp:positionV>"+"<wp:extent cx=\""+width+"\" cy=\""+height+"\"/>"+"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"+"<wp:wrapTight wrapText=\"bothSides\">"+"<wp:wrapPolygon 编辑=\"1\">";//设置edited 1,所以Word不会破坏换行点.//一个正方形的多边形 21600 x 21600 导致以完全宽 x 高的方式包裹点,而与图片大小无关.//所以如果需要设置更复杂的包裹点,比如一个椭圆,只描绘这个椭圆//需要一个 21600 x 21600 的正方形,与图片大小无关.长[] x = 新长[5];长[] y = 新长[5];for (int i = 0; i ";}for (int i = 3; i > -1; i--) {anchorXML += "<wp:lineTo x=\""+(x[i]+10800)+"\" y=\""+(10800+y[i])+"\"/>";}for (int i = 1; i ";}for (int i = 3; i > -1; i--) {anchorXML += "<wp:lineTo x=\""+(10800-x[i])+"\" y=\""+(10800-y[i])+"\"/>";}anchorXML += "</wp:wrapPolygon>"+"</wp:wrapTight>"+"<wp:docPr id=\"1\" name=\"绘图 0\" descr=\""+drawingDescr+"\"/><wp:cNvGraphicFramePr/>"+"</wp:anchor>";CTDrawing 绘图 = CTDrawing.Factory.parse(anchorXML);CTAnchor 锚点 =drawing.getAnchorArray(0);anchor.setGraphic(graphicalobject);回锚;}public static void main(String[] args) 抛出异常 {XWPFDocument 文档 = 新 XWPFDocument();XWPFParagraph 段落 = document.createParagraph();XWPFRun 运行 = 段落.createRun();InputStream in = new FileInputStream("ellipticSample.png");run.addPicture(in, Document.PICTURE_TYPE_PNG, "ellipticSample.png", Units.toEMU(100), Units.toEMU(60));附寄();CTDrawing 绘图 = run.getCTR().getDrawingArray(0);CTGraphicalObject 图形对象 = drawing.getInlineArray(0).getGraphic();CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "ellipticSample.png",Units.toEMU(100), Units.toEMU(60),Units.toEMU(100), Units.toEMU(16));draw.setAnchorArray(new CTAnchor[]{anchor});draw.removeInline(0);运行 = 段落.createRun();run.setText("图片被锚定包裹紧.这意味着文本将根据包裹点描述的多边形包裹它.似乎正方形多边形 21600 x 21600 导致以完全宽度 x 高度独立于图片大小的包裹点.所以如果需要设置更复杂的包裹点,例如一个椭圆,只需要将这个椭圆描绘成一个 21600 x 21600 的正方形,而与图片大小无关.如果设置更复杂的包裹点,这会简单得多.但这是一种耻辱,这个功能似乎没有记录.那么我们是否可以依赖它?");document.write(new FileOutputStream("WordPicturesWrapTight.docx"));文档.close();}}
结果:
Does someone knows what is the meaning and unit of x
and y
in Office Open XML wrapPolygon
?
The documentation states:
"Specifies a coordinate on the x-axis. The origin point for this coordinate shall be specified by the parent XML element. ...The possible values for this attribute are defined by the ST_Coordinate simple type (§ 5.1.12.16)."
That sounds like it should be describing a polygon starting at x
=0 and y
=0 in top left point of the picture. And the unit would be EMU
.
But this cannot be true because if used in the code Change image layout or wrap in DOCX with Apache POI, then, if I do something like:
...
+"<wp:wrapTight wrapText=\"bothSides\">"
+"<wp:wrapPolygon edited=\"0\">"
+"<wp:start x=\"0\" y=\"0\"/>"
+"<wp:lineTo x=\"0\" y=\""+height+"\"/>"
+"<wp:lineTo x=\""+width+"\" y=\""+height+"\"/>"
+"<wp:lineTo x=\""+width+"\" y=\"0\"/>"
+"<wp:lineTo x=\"0\" y=\"0\"/>"
+"</wp:wrapPolygon>"
+"</wp:wrapTight>"
...
then the resulting wrap points are much far outside the picture.
Instead describing a square polygon 21600 x 21600
...
+"<wp:wrapPolygon edited=\"0\">"
+"<wp:start x=\"0\" y=\"0\"/>"
+"<wp:lineTo x=\"0\" y=\"21600\"/>"
+"<wp:lineTo x=\"21600\" y=\"21600\"/>"
+"<wp:lineTo x=\"21600\" y=\"0\"/>"
+"<wp:lineTo x=\"0\" y=\"0\"/>"
+"</wp:wrapPolygon>"
...
leads to wrap points which are in fully width x height of the picture.
And this is independent of the pictures size itself. It may be a square or rectangle sized picture in all possible sizes.
So while "The origin point for this coordinate shall be specified by the parent XML element." and the polygon starts at x
=0 and y
=0 in top left point of the picture, the unit cannot be EMU
as for width and height. And since a square polygon 21600 x 21600 leads to rectangle wrap points if the picture is a rectangle, even the meaning of the polygon itself is not clear.
Is this documented somewhere?
Well, seems nobody answers. So I will at least providing an example for why this rule: "A square polygon 21600 x 21600 leads to wrap points in fully width x height independent of picture size." could be useful.
If the need is setting more complex wrap points, a ellipse for example, only depicting this ellipse to a square 21600 x 21600 is needed, independent of picture size. This is much more simple than calculating the wrap points dependent on the really picture size. So we can forcing Word
having really wrapping text tight around the picture.
Example Code:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.Units;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
public class WordPicturesWrapTight {
private static CTAnchor getAnchorWithGraphic(CTGraphicalObject graphicalobject,
String drawingDescr, int width, int height,
int left, int top) throws Exception {
String anchorXML =
"<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
+"simplePos=\"0\" relativeHeight=\"0\" behindDoc=\"1\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
+"<wp:simplePos x=\"0\" y=\"0\"/>"
+"<wp:positionH relativeFrom=\"column\"><wp:posOffset>"+left+"</wp:posOffset></wp:positionH>"
+"<wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>"+top+"</wp:posOffset></wp:positionV>"
+"<wp:extent cx=\""+width+"\" cy=\""+height+"\"/>"
+"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/>"
+"<wp:wrapTight wrapText=\"bothSides\">"
+"<wp:wrapPolygon edited=\"1\">"; //Set edited 1, so Word will not destroying the wrap points.
//A square polygon 21600 x 21600 leads to wrap points in fully width x height independent of picture size.
//So if the need is setting more complex wrap points, a ellipse for example, only depicting this ellipse
//to a square 21600 x 21600 is needed independent of picture size.
long[] x = new long[5];
long[] y = new long[5];
for (int i = 0; i < 5; i++) {
x[i] = i * 2700L; //2700 = 21600/2/4
y[i] = Math.round(Math.sqrt(116640000d - Math.pow(i * 2700d, 2d))); //116640000 = (21600/2)^2
}
anchorXML += "<wp:start x=\""+(x[0]+10800)+"\" y=\""+(10800-y[0])+"\"/>";
for (int i = 1; i < 5; i++) {
anchorXML += "<wp:lineTo x=\""+(x[i]+10800)+"\" y=\""+(10800-y[i])+"\"/>";
}
for (int i = 3; i > -1; i--) {
anchorXML += "<wp:lineTo x=\""+(x[i]+10800)+"\" y=\""+(10800+y[i])+"\"/>";
}
for (int i = 1; i < 5; i++) {
anchorXML += "<wp:lineTo x=\""+(10800-x[i])+"\" y=\""+(10800+y[i])+"\"/>";
}
for (int i = 3; i > -1; i--) {
anchorXML += "<wp:lineTo x=\""+(10800-x[i])+"\" y=\""+(10800-y[i])+"\"/>";
}
anchorXML += "</wp:wrapPolygon>"
+"</wp:wrapTight>"
+"<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\""+drawingDescr+"\"/><wp:cNvGraphicFramePr/>"
+"</wp:anchor>";
CTDrawing drawing = CTDrawing.Factory.parse(anchorXML);
CTAnchor anchor = drawing.getAnchorArray(0);
anchor.setGraphic(graphicalobject);
return anchor;
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
InputStream in = new FileInputStream("ellipticSample.png");
run.addPicture(in, Document.PICTURE_TYPE_PNG, "ellipticSample.png", Units.toEMU(100), Units.toEMU(60));
in.close();
CTDrawing drawing = run.getCTR().getDrawingArray(0);
CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "ellipticSample.png",
Units.toEMU(100), Units.toEMU(60),
Units.toEMU(100), Units.toEMU(16));
drawing.setAnchorArray(new CTAnchor[]{anchor});
drawing.removeInline(0);
run = paragraph.createRun();
run.setText("The picture is anchored wrap tight. This means text will wrap this according to a polygon described by wrap points. Seems a square polygon 21600 x 21600 leads to wrap points in fully width x height independent of picture size. So if the need is setting more complex wrap points, a ellipse for example, only depicting this ellipse to a square 21600 x 21600 is needed independent of the picture size. This is much more simple if more complex wrap points shall be set. But it's a shame, that this feature not seems documented. So can we rely on it or not?");
document.write(new FileOutputStream("WordPicturesWrapTight.docx"));
document.close();
}
}
Result:
这篇关于Office Open XML `wrapPolygon` 中 `x` 和 `y` 的含义和单位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!