如何使用 Apache POI 锁定 docx 中图像的纵横比?

How to lock aspect ratio of an image in a docx with Apache POI?

有没有办法使用 Apache POI 为 docx 中的图像启用 "lock aspect ratio" 选项? 我正在将图像添加到 运行 并且我想锁定它的大小。 在文档中搜索但未找到任何内容。

为了更清楚,我指的是 word 中可用的选项,如图所示: https://support.content.office.net/en-us/media/a30a8baa-6775-4931-bca6-199fda6afc6e.png

谢谢

答案取决于图片如何应用于 Word 文档。如果这是通过 XWPFRun.addPicture 完成的,则它是文本 运行 中的内联图片。然后 运行 包含一个绘图层,其中包含一个包含图片的内联元素。然后,此内联元素可能包含非可视图形框架属性,这些属性可能具有图形框架锁,将无变化方面设置为真。

/word/document.xml 中的 XML 看起来像:

<w:r>
 <w:drawing>
  <wp:inline ...>
   <wp:cNvGraphicFramePr><a:graphicFrameLocks noChangeAspect="true"/></wp:cNvGraphicFramePr>
    <a:graphic>
   ...

那么对于XWPFRun run包含的图片可以设置

run.getCTR().getDrawingArray(0).getInlineArray(0).addNewCNvGraphicFramePr().addNewGraphicFrameLocks().setNoChangeAspect(true);

完整示例:

import java.io.*;

import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.util.Units;

import java.util.List;
import java.util.ArrayList;

import java.net.URL;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.Dimension;

public class CreateWordPicturesInTextRuns {

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

  List<String> pictureURLs = new ArrayList<String>();
  pictureURLs.add("https://www.eastcottvets.co.uk/uploads/Animals/gingerkitten.jpg");
  pictureURLs.add("https://www.catster.com/wp-content/uploads/2017/12/A-kitten-meowing.jpg");
  pictureURLs.add("https://www.animalfriends.co.uk/app/uploads/2014/08/06110347/Kitten-small.jpg");
  pictureURLs.add("https://d27ucmmhxk51xv.cloudfront.net/media/english/illustration/kitten.jpg");

  XWPFDocument document= new XWPFDocument();
  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run = paragraph.createRun();
  run.setText("The kitten pictures: ");

  URL url;
  BufferedImage image;
  Dimension dim;
  ByteArrayOutputStream bout;
  ByteArrayInputStream bin;
  for (String pictureURL : pictureURLs) {
   try {
       
    url = new URL(pictureURL);
    image = ImageIO.read(url);
    dim = new Dimension(image.getWidth(), image.getHeight());
    double width = dim.getWidth();
    double height = dim.getHeight();
    double scaling = 1.0;
    if (width > 72*3) scaling = (72*3)/width; //scale width not to be greater than 3 inches

    bout = new ByteArrayOutputStream();
    ImageIO.write(image, "jpeg", bout);
    bout.flush();
    bin = new ByteArrayInputStream(bout.toByteArray());
    run = paragraph.createRun();
    run.addPicture(bin, XWPFDocument.PICTURE_TYPE_JPEG, "kitten", 
     Units.toEMU(width*scaling), Units.toEMU(height*scaling));

    //lock aspect ratio
    run.getCTR().getDrawingArray(0).getInlineArray(0).addNewCNvGraphicFramePr().addNewGraphicFrameLocks().setNoChangeAspect(true);
    
   } catch (Exception ex) {
    ex.printStackTrace();
   }
  }

  FileOutputStream out = new FileOutputStream("CreateWordPicturesInTextRuns.docx");
  document.write(out);
  out.close();
  document.close();

 }
}