如何在poi word run.addPicture()中动态设置图像大小?

时间:2017-04-20 06:37:16

标签: apache-poi

 XWPFDocument doc= new XWPFDocument();
 InputStream a = someMethod(underConditions(inputimage));
 paragraph.createRun().addPicture(a, Document.PICTURE_TYPE_PNG, "", Units.toEMU(20), Units.toEMU(20));
 a.close();
 doc.write(new FileOutputStream("CreateWordHeaderFooter.docx"));
 doc.close();

这是在poi word中添加图像的简单代码。但是InputStream a在不同条件下是不同的。如果inputimage是小Unit.toEMU(20),Units.toEMU(20)是大的,如果inputimage是大Units.toEMU(20),Units.toEMU(20)太小。在这种情况下,图像会失真。所以我的问题是如何根据不同的图像设置动态图像大小。谢谢。

1 个答案:

答案 0 :(得分:3)

因此,我们需要从文件中确定图像的首选尺寸。关于如何做到这一点已经有很多讨论。搜索关键字:java get dimension from image file。最简单的可能是使用ImageIO从文件中读取BufferedImage,然后该文件具有widthheight属性。

示例:

import java.io.*;

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

import org.apache.poi.util.Units;

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

public class CreateWordImagesPreferredSize {

 static Dimension getImageDimension(File imgFile) throws IOException {
  BufferedImage img = ImageIO.read(imgFile);
  return new Dimension(img.getWidth(), img.getHeight());
 }

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

  XWPFDocument doc= new XWPFDocument();

  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run = paragraph.createRun();  
  run.setText("The Images:");

  String[] images = new String[]{"Koala.png", "Scannen.jpg", "Winter.bmp"};

  for (int i = 0 ; i < images.length; i++) {

   paragraph = doc.createParagraph();
   run = paragraph.createRun();

   File imgFile = new File(images[i]);
   Dimension dim = getImageDimension(imgFile);
   System.out.println(dim);

   double width = dim.getWidth();
   double height = dim.getHeight();

   double scaling = 1.0;
   if (width > 72*6) scaling = (72*6)/width; //scale width not to be greater than 6 inches

   InputStream in = new FileInputStream(imgFile);
   paragraph.createRun().addPicture(in, Document.PICTURE_TYPE_PNG, images[i], 
    Units.toEMU(width*scaling), Units.toEMU(height*scaling));
   in.close();

  }

  doc.write(new FileOutputStream("CreateWordImagesPreferredSize.docx"));
  doc.close();

 }
}

注意:如果原始尺寸较大,我会将图像缩放到不大于6英寸的宽度。所以它将适合一个页面宽度。较小的图像不会缩放。

编辑:

从评论中可以看出,如果您无法使用File但必须使用InputStream,那么您需要知道,BufferedImage img = ImageIO.read(imgStream);当然是从流中读取的。因此,流将在此之后结束。因此,.addPicture(imgStream,...)将需要新打开的流。

示例:

import java.io.*;

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

import org.apache.poi.util.Units;

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

public class CreateWordImagesPreferredSizeStream {

 static InputStream getInputStream(String filename) throws Exception {
  return new FileInputStream(filename);
 }

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

  XWPFDocument doc= new XWPFDocument();

  XWPFParagraph paragraph = doc.createParagraph();
  XWPFRun run = paragraph.createRun();  
  run.setText("The Images:");

  String[] images = new String[]{"Koala.png", "Scannen.jpg", "Winter.bmp"};

  for (int i = 0 ; i < images.length; i++) {

   paragraph = doc.createParagraph();
   run = paragraph.createRun();

   InputStream imgStream = getInputStream(images[i]);

   BufferedImage img = ImageIO.read(imgStream);
   double w = img.getWidth();
   double h = img.getHeight();
   imgStream.close();

   System.out.println(w);
   System.out.println(h);

   double scaling = 1.0;
   if (w > 72*6) scaling = (72*6)/w; //scale width not to be greater than 6 inches

   imgStream = getInputStream(images[i]);

   paragraph.createRun().addPicture(imgStream, Document.PICTURE_TYPE_PNG, images[i], 
    Units.toEMU(w*scaling), Units.toEMU(h*scaling));
   imgStream.close();

  }

  doc.write(new FileOutputStream("CreateWordImagesPreferredSize.docx"));
  doc.close();

 }
}