【问题标题】:Meaning and unit of `x` and `y` in Office Open XML `wrapPolygon`Office Open XML`wrapPolygon`中`x`和`y`的含义和单位
【发布时间】:2017-12-08 15:32:19
【问题描述】:

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

documentation 声明:

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

听起来它应该描述一个多边形,从图片左上角的x=0 和y=0 开始。单位为EMU

但这不可能是真的,因为如果在代码Change image layout or wrap in DOCX with Apache POI中使用,那么,如果我这样做:

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

那么生成的换行点在图片之外很远。

而是描述一个正方形多边形 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 高度中的换行点。

这与图片大小本身无关。它可以是所有可能大小的正方形或矩形大小的图片。

因此,虽然“此坐标的原点应由父 XML 元素指定。”并且多边形从图片左上角的x=0 和y=0 开始,宽度和高度的单位不能是EMU。并且由于如果图片是矩形,21600 x 21600的正方形多边形会导致矩形环绕点,甚至多边形本身的含义也不清楚。

这是否记录在某处?

【问题讨论】:

    标签: ms-word apache-poi openxml


    【解决方案1】:

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

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

    示例代码:

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

    结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-07
      相关资源
      最近更新 更多