Apache POI:如何将图像放在 MS Word 文档的特定位置?

问题描述 投票:0回答:1

这是我的代码:

XWPFParagraph paragraph = document.createParagraph();
XWPFRun run=paragraph.createRun();

var img = new FileInputStream(new File("/Users/mahdi/Downloads/unnamed.jpg"));
var pic = run.addPicture(img, PictureType.JPEG, "unnamed.jpg", Units.pixelToEMU(400), Units.pixelToEMU(200));

工作正常并将图像添加到输出 .docx 文件中。但是,我希望能够指定该图像的位置(例如距左侧 5 厘米,距顶部 15 厘米)。我怎样才能做到这一点?

apache-poi openxml
1个回答
0
投票

XWPFRun.addPicture
添加与文本内嵌的图片。也就是说,图片的行为就像文本字符一样。例如,如果需要在页面的特殊位置添加图片,则需要将图片锚定在页面上。到目前为止
Apache POI
还不支持这一点。

如果知道

/word/document.xml
中的 XML 应如何满足此要求,则可以在
/word/document.xml
中创建 XML。 怎么知道?每个
*.docx
文件只是一个包含 XML 文件和其他文件的 ZIP 存档。因此,人们可以使用 Word GUI 创建所需的内容,将其另存为
*.docx
文件,然后解压缩该
*.docx
文件并查看它。

这样做时,我使用以下代码在页面上的特殊位置创建图片:

import java.io.*;

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 CreateWordImageAtPosition {

 private static CTAnchor getAnchorWithGraphic(CTDrawing drawing /*inline drawing*/ , 
  String drawingDescr, boolean behind, String relFromH, int posH, String relFromV, int posV) throws Exception {

  CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
  long width = drawing.getInlineArray(0).getExtent().getCx();
  long height = drawing.getInlineArray(0).getExtent().getCy();

  String anchorXML = 
   "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
  +"simplePos=\"0\" relativeHeight=\"0\" behindDoc=\""+((behind)?1:0)+"\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
  +"<wp:simplePos x=\"0\" y=\"0\"/>"
  +"<wp:positionH relativeFrom=\""+relFromH+"\"><wp:posOffset>"+posH+"</wp:posOffset></wp:positionH>"
  +"<wp:positionV relativeFrom=\""+relFromV+"\"><wp:posOffset>"+posV+"</wp:posOffset></wp:positionV>"
  //+"<wp:positionH relativeFrom=\""+relFromH+"\"><wp:align>"+"center"+"</wp:align></wp:positionH>"
  //+"<wp:positionV relativeFrom=\""+relFromV+"\"><wp:align>"+"center"+"</wp:align></wp:positionV>"
  +"<wp:extent cx=\""+width+"\" cy=\""+height+"\"/>"
  +"<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/><wp:wrapNone/>"
  +"<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\""+drawingDescr+"\"/><wp:cNvGraphicFramePr/>"
  +"</wp:anchor>";

  drawing = CTDrawing.Factory.parse(anchorXML);
  CTAnchor anchor = drawing.getAnchorArray(0);
  anchor.setGraphic(graphicalobject);
  return anchor;  
 }

 public static void main(String[] args) throws Exception {

  XWPFDocument doc = new XWPFDocument();
  XWPFParagraph paragraph;
  XWPFRun run; 
  InputStream in;
  CTDrawing drawing;
  CTAnchor anchor;

  paragraph = doc.createParagraph();
  run = paragraph.createRun();
  run.setText("Picture at position center of page:");

  run = paragraph.createRun();
  in = new FileInputStream("samplePict.jpeg");
  int width = Units.toEMU(100);
  int height = Units.toEMU(100);
  run.addPicture(in, Document.PICTURE_TYPE_JPEG, "samplePict.jpeg", width, height);
  in.close();  
  drawing = run.getCTR().getDrawingArray(0);

  int posH = Units.toEMU(72*4); // 4 inch
  posH -= width / 2;
  int posV = Units.toEMU(72*5); // 5 inch
  posV -= height / 2;
  anchor = getAnchorWithGraphic(drawing, "samplePict.jpeg", false /*behind text*/, "page", posH, "page", posV);

  drawing.setAnchorArray(new CTAnchor[]{anchor});
  drawing.removeInline(0);

  paragraph = doc.createParagraph();

  FileOutputStream out = new FileOutputStream("./CreateWordImageAtPosition.docx");
  doc.write(out);
  out.close();
  doc.close();

 }
}
© www.soinside.com 2019 - 2024. All rights reserved.