使用POI往word插入图片

在POI4之后的版本,想在word中插入图片是比较简单的。

直接在指定段落paragraph中创建一个run,然后用addPic方法即可

Document doc = new XWPFDocument(new FileInputStream(new File("new.doc")));
XWPFParagraph paragraph = doc.getParagraphs(doc.getParagraphs().size() - 1);
XWPFRun run = paragraph.createRun();
run.addPicture(new FileInputStream(imgPath), 
Document.PICTURE_TYPE_JPEG, 
name, 
Units.toEMU(400), Units.toEMU(400));


但在POI3.X中,没有addPic方法,有createPicture方法,但是有缺陷,不可用,原因是3.X的POI代码实现createPicture的xml格式有问题,最终找到一个大神写的,原理就是重构XWPFDocument的createPicture方法

CustomXWPFDocument,重写Document类

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFPictureData;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
/**
 * 
* @功能描述: POI缺陷,无法正确的往word中插入图片,原因是XML没有正确生成
* 重写document类的createPicture,重写XML
* @名称: CustomXWPFDocument.java 
* @路径 com.daimeng.util 
* @作者 daimeng.fun
* @E-Mail sephy9527@qq.com
* @创建时间 2019年12月7日 上午12:02:26 
* @version V1.0
 */
public class CustomXWPFDocument extends XWPFDocument{
public CustomXWPFDocument(InputStream in) throws IOException
    {
        super(in);
    }
//POI3.7-3.9可用,但也无需用
public int getId(String blipId){
/*List<XWPFPictureData> list = getAllPictures();
for(int i = 0; i < list.size(); i ++){
XWPFPictureData data = list.get(i);
if(blipId.equals(data.getPackageRelationship().getId())){
return i;
}
}*/
return 0;
}
    public void createPicture(String blipId,int id,XWPFRun run, int width, int height)
    {
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;
        //String blipId = getAllPictures().get(id).getPackageRelationship().getId();
        //int id = getId(blipId);
        CTInline inline = run.getCTR().addNewDrawing().addNewInline();
        String picXml = "" +
                "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" +
                "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" +
                "         <pic:nvPicPr>" +
                "            <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" +
                "            <pic:cNvPicPr/>" +
                "         </pic:nvPicPr>" +
                "         <pic:blipFill>" +
                "            <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" +
                "            <a:stretch>" +
                "               <a:fillRect/>" +
                "            </a:stretch>" +
                "         </pic:blipFill>" +
                "         <pic:spPr>" +
                "            <a:xfrm>" +
                "               <a:off x=\"0\" y=\"0\"/>" +
                "               <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" +
                "            </a:xfrm>" +
                "            <a:prstGeom prst=\"rect\">" +
                "               <a:avLst/>" +
                "            </a:prstGeom>" +
                "         </pic:spPr>" +
                "      </pic:pic>" +
                "   </a:graphicData>" +
                "</a:graphic>";
        //CTGraphicalObjectData graphicData = inline.addNewGraphic().addNewGraphicData();
        XmlToken xmlToken = null;
        try
        {
            xmlToken = XmlToken.Factory.parse(picXml);
        }
        catch(XmlException xe)
        {
            xe.printStackTrace();
        }
        inline.set(xmlToken);
        //graphicData.set(xmlToken);
        inline.setDistT(0);
        inline.setDistB(0);
        inline.setDistL(0);
        inline.setDistR(0);
        CTPositiveSize2D extent = inline.addNewExtent();
        extent.setCx(width);
        extent.setCy(height);
        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
        docPr.setId(id);
        docPr.setName("Picture " + id);
        docPr.setDescr("Generated");
    }
}


doc需要用CustomXWPFDocument实例化

CustomXWPFDocument doc = new CustomXWPFDocument(new FileInputStream(new File("new.doc")));
String pid = doc.addPictureData(new FileInputStream(imgPath), Document.PICTURE_TYPE_JPEG);
doc.createPicture(pid,doc.getNextPicNameNumber(XWPFDocument.PICTURE_TYPE_JPEG),run, 400, 400);

至此就可以往word中加入图片了

{context}