一、添加依赖

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.15</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.15</version>
        </dependency>
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.0.0</version>
        </dependency>

  

二、工具类

import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.PictureRenderData;
import com.hdvon.nmp.vcase.config.AppConfig;
import com.hdvon.nmp.vcase.helper.SpringHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.util.FileCopyUtils;

import javax.imageio.ImageIO;

/**
 * 适用于word 2007
 * poi 版本 3.7
 */
@Slf4j
public class WordHelper {

    /***
     * 写入书签内容、图片t
     * @param oldFileName 旧的文件名
     * @param filePath 模板文件路径
     * @param map 指定写入书签参数
     */
    public String export(String oldFileName,String filePath, Map<String, Object> oldmap){
        AppConfig appConfig = SpringHelper.getBean(AppConfig.class);
        String folder=appConfig.getBasePath()+appConfig.getWordPath();
        try {
            Map<String, Object> map=new HashMap<>();
            for (String key:oldmap.keySet()){
                map.put("${"+key+"}",oldmap.get(key));
            }
            if(StringUtils.isBlank(folder))return "";
            String newFileFolder=folder+new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            File newFile=new File(newFileFolder);
            if(!newFile.exists()){
                newFile.mkdir();
            }
            String fileName=new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"\\"+oldFileName;
            File outFile=new File(folder+fileName);
            //复制一份模板
            String copyPath=folder+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"\\"+"template.docx";
            File copyFile=new File(copyPath);
            FileCopyUtils.copy(new File(filePath),copyFile);
            //写入文字到doc
            OutputStream outputStream = null;
            outputStream = new FileOutputStream(outFile);
            XWPFDocument doc=WordUtil.generateWord(map,copyPath);
            doc.write(outputStream);
            outputStream.flush();
            outputStream.close();
            doc.close();
            //写入图片到doc
            String picUrl = (String)map.get("${picUrl}");
            String[] urls = picUrl.split(";");
            int size=urls.length;
            FileInputStream inputStream=new FileInputStream(outFile);
            XWPFDocument doc1=new XWPFDocument(inputStream);
            outputStream = new FileOutputStream(outFile);
            XWPFParagraph lastParagraph = doc1.getLastParagraph();
            for(int i=1;i<=size;i++){
                XWPFRun run = lastParagraph.createRun();
                run.setText("{{@localhostPicture"+i+"}}");
                lastParagraph.addRun(run);

            }
            doc1.write(outputStream);
            inputStream.close();
            outputStream.close();
            doc1.close();


           Map<String,Object> datas=new HashMap<String,Object>();
           File imgFile=null;
           FileInputStream imgInputStream=null;
           BufferedImage image=null;
            for(int i=0;i< urls.length;i++){
                String url=urls[i];
                url=appConfig.getBasePath()+url;
                imgFile=new File(url);
                if(!imgFile.exists()) continue;
                imgInputStream=new FileInputStream(imgFile);
                image= ImageIO.read(imgInputStream);
                if(StringUtils.isNotBlank(url)) {
                    datas.put("localhostPicture" + (i + 1), new PictureRenderData(image.getWidth(), image.getHeight(), url));
                }
            }

            XWPFTemplate template=XWPFTemplate.compile(outFile).render(datas);
            FileOutputStream out1=new FileOutputStream(outFile);
            template.write(out1);
            out1.flush();
            out1.close();
            template.close();
            imgInputStream.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return appConfig.getWordPath()+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+"/"+oldFileName;
    }
}

  

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
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;

/**
 * 适用于word 2007
 * poi 版本 3.7
 */
public class WordUtil {

    /**
     * 根据指定的参数值、模板,生成 word 文档
     *
     * @param param    需要替换的变量
     * @param template 模板
     */
    public static XWPFDocument generateWord(Map<String, Object> param, String template) {
        XWPFDocument doc = null;
        try {
            OPCPackage pack = POIXMLDocument.openPackage(template);
            doc = new CustomXWPFDocument(pack);
            if (param != null && param.size() > 0) {

                //处理段落
                List<XWPFParagraph> paragraphList = doc.getParagraphs();
                processParagraphs(paragraphList, param, doc);

                //处理表格
                Iterator<XWPFTable> it = doc.getTablesIterator();
                while (it.hasNext()) {
                    XWPFTable table = it.next();
                    List<XWPFTableRow> rows = table.getRows();
                    for (XWPFTableRow row : rows) {
                        List<XWPFTableCell> cells = row.getTableCells();
                        for (XWPFTableCell cell : cells) {
                            List<XWPFParagraph> paragraphListTable = cell.getParagraphs();
                            processParagraphs(paragraphListTable, param, doc);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return doc;
    }

    /**
     * 处理段落
     *
     * @param paragraphList
     * @throws FileNotFoundException
     * @throws InvalidFormatException
     */
    public static void processParagraphs(List<XWPFParagraph> paragraphList, Map<String, Object> param, XWPFDocument doc) throws InvalidFormatException, FileNotFoundException {
        if (paragraphList != null && paragraphList.size() > 0) {
            for (XWPFParagraph paragraph : paragraphList) {
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
                    String text = run.getText(0);
                    if (text != null) {
                        boolean isSetText = false;
                        for (Entry<String, Object> entry : param.entrySet()) {
                            String key = entry.getKey();
                            if (text.indexOf(key) != -1) {
                                isSetText = true;
                                Object value = entry.getValue();
                                if (value instanceof Object) {//文本替换
                                    text = text.replace(key, value.toString());
                                } else if (value instanceof Map) {    //图片替换
                                    text = text.replace(key, "");
                                    Map pic = (Map) value;
                                    int width = Integer.parseInt(pic.get("width").toString());
                                    int height = Integer.parseInt(pic.get("height").toString());
                                    int picType = getPictureType(pic.get("type").toString());
                                    String byteArray = (String) pic.get("content");


                                    //ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);

                                    //int ind = doc.getAllPictures().size() - 1;
                                    //doc.createPicture(ind, width , height,paragraph);
                                    CTInline inline = run.getCTR().addNewDrawing().addNewInline();
                                    insertPicture(doc, byteArray, inline, width, height);

                                }
                            }
                        }
                        if (isSetText) {
                            run.setText(text, 0);
                        }
                    }
                }
            }
        }
    }

    /**
     * 根据图片类型,取得对应的图片类型代码
     *
     * @param picType
     * @return int
     */
    private static int getPictureType(String picType) {
        int res = CustomXWPFDocument.PICTURE_TYPE_PICT;
        if (picType != null) {
            if (picType.equalsIgnoreCase("png")) {
                res = CustomXWPFDocument.PICTURE_TYPE_PNG;
            } else if (picType.equalsIgnoreCase("dib")) {
                res = CustomXWPFDocument.PICTURE_TYPE_DIB;
            } else if (picType.equalsIgnoreCase("emf")) {
                res = CustomXWPFDocument.PICTURE_TYPE_EMF;
            } else if (picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")) {
                res = CustomXWPFDocument.PICTURE_TYPE_JPEG;
            } else if (picType.equalsIgnoreCase("wmf")) {
                res = CustomXWPFDocument.PICTURE_TYPE_WMF;
            }
        }
        return res;
    }

    /**
     * 将输入流中的数据写入字节数组
     *
     * @param in
     * @return
     */
    public static byte[] inputStream2ByteArray(InputStream in, boolean isClose) {
        byte[] byteArray = null;
        try {
            int total = in.available();
            byteArray = new byte[total];
            in.read(byteArray);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (isClose) {
                try {
                    in.close();
                } catch (Exception e2) {
                    System.out.println("关闭流失败");
                }
            }
        }
        return byteArray;
    }

    /**
     * insert Picture
     *
     * @param document
     * @param filePath
     * @param inline
     * @param width
     * @param height
     * @throws InvalidFormatException
     * @throws FileNotFoundException
     */
    private static void insertPicture(XWPFDocument document, String filePath,
                                      CTInline inline, int width,
                                      int height) throws InvalidFormatException,
            FileNotFoundException {
        document.addPictureData(new FileInputStream(filePath), XWPFDocument.PICTURE_TYPE_PNG);
        int id = document.getAllPictures().size() - 1;
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;
        String blipId =
                document.getAllPictures().get(id).getPackageRelationship().getId();
        String picXml = getPicXml(blipId, width, height);
        XmlToken xmlToken = null;
        try {
            xmlToken = XmlToken.Factory.parse(picXml);
        } catch (XmlException xe) {
            xe.printStackTrace();
        }
        inline.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("IMG_" + id);
        docPr.setDescr("IMG_" + id);
    }

    /**
     * get the xml of the picture
     *
     * @param blipId
     * @param width
     * @param height
     * @return
     */
    private static String getPicXml(String blipId, int width, int height) {
        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=\"" + 0 +
                        "\" 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>";
        return picXml;
    }
}

  

版权声明:本文为tinyj原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/tinyj/p/9802535.html