Office Open XML`wrapPolygon`中`x`和`y`的含义和单位 [英] Meaning and unit of `x` and `y` in Office Open XML `wrapPolygon`

查看:91
本文介绍了Office Open XML`wrapPolygon`中`x`和`y`的含义和单位的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人知道Office Open XML wrapPolygonxy的含义和单位是什么吗?

Does someone knows what is the meaning and unit of x and y in Office Open XML wrapPolygon?

文档指出:

在x轴上指定一个坐标.此坐标的原点应由父XML元素指定....此属性的可能值由ST_Coordinate简单类型(第5.1.12.16节)定义. ."

"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)."

听起来好像应该描述图片左上角以x = 0和y = 0开头的多边形.单位为EMU.

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.

而不是描述21600 x 21600的正方形

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>"
...

导致换行点的宽度为图片的全宽x高度.

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.

因此,该坐标的原点应由父XML元素指定".并且多边形从图片左上角的x = 0和y = 0开始,宽度和高度的单位不能为EMU.而且,如果图片是矩形,则由于正方形多边形21600 x 21600会导致矩形换行点,所以即使多边形本身的含义也不清楚.

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.

此文件记录在某处吗?

推荐答案

好吧,似乎没人回答.因此,我至少将提供一个示例说明该规则的原因:一个正方形多边形21600 x 21600导致折点的全宽x高度与图片大小无关."可能会有用.

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.

如果需要设置更复杂的环绕点,例如一个椭圆,只需要将此椭圆描绘为21600 x 21600的正方形即可,而与图片大小无关.这比根据实际图片大小计算环绕点要简单得多.因此,我们可以强制Word在文本周围紧紧包裹文字.

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.

示例代码:

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

结果:

这篇关于Office Open XML`wrapPolygon`中`x`和`y`的含义和单位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆