根据Word模板生成Word文件 (JAVA POI)

  • 需求

     通过提前准备的word模板,渲染填充数据,生成新的加工好的word文件。(也试过使用Freemarker渲染数据,但是有个很大的弊端:使用Freemarker渲染的后文件会变大)

  • 用法

  •     POI的Maven依赖

    org.apache.poi
    poi
    3.8
  • 需要将模板参数设置成如下格式, 另存为word文档即可

根据Word模板生成Word文件 (JAVA POI)_第1张图片

  • 直接放代码,仅供参考

import com.cloudlead.common.worker.client.exception.RestClientException;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
*
* 文档处理类
*
* */
public class WordTemplateUtil {

    /*从word模板 渲染参数 获取word文档
    *   template 模板文件 params 参数 outputStream 输出流,
    */
    public static void wordRenderAndGetFromWordTemplate(File template, Map params, OutputStream outputStream)throws Exception{

        FileInputStream inputStream = new FileInputStream(template);

        XWPFDocument templateDoc = new XWPFDocument(inputStream);
        produce(templateDoc,params);
        templateDoc.write(outputStream);

    }
     /* 处理参数 生成doc */
    public static void produce(XWPFDocument templateDoc,Map params){

        Iterator iterator = templateDoc.getParagraphsIterator();

        while(iterator.hasNext()){

            XWPFParagraph next = iterator.next();

            if (next.isEmpty()||!match(next.getParagraphText())){
                continue;
            }
            next.getRuns().forEach(
                run -> setNewTextforRun(run,params)
            );

        }

    }

/*
    * 正则匹配 返回 matcher
    * */
    public static Matcher matcher(String text){
        Pattern pattern = Pattern.compile("\\$\\{(.+?)}", Pattern.CASE_INSENSITIVE);
        return pattern.matcher(text);
    }
    /*
    * 判定是否包匹配
    * */
    public static boolean match(String text){
        Matcher matcher = matcher(text);
        return matcher.find();
    }
    /*
    * 替换参数 设置新参数
    * */
    public static void setNewTextforRun(XWPFRun run,Map params){

        List ctTexts = run.getCTR().getTList();

        ctTexts.forEach(
            ctText->{
                String text = ctText.getStringValue();
                Matcher matcher = matcher(text);

                while(matcher.find()){

                    String group = matcher.group();
                    if (group.contains(" ")){
                        throw new RestClientException("${}表达式不能包含空格");
                    }

                    String name = group.substring(2, group.length()-1);
                    String value = params.get(name);
                    value = value==null?"":value;

                    if (text.equals(group)){
                        text=value;

                    }else{
                        //转义
                        String[] parts = text.split("\\$\\{"+name+"}");
                        //length=1 分前后 设置参数值
                        if (parts.length==1){
                            String part = parts[0];
                            text = text.indexOf(part)==0?(part+value):(value+part);
                        }else{
                            text = StringUtils.join(parts,value);
                        }

                    }

                }
                ctText.setStringValue(text);
            }
        );

    }
}
  • 调用代码示例


 @GetMapping("/templateExport")
 public void exportContractFromTemplate() throws Exception{
     /*设置参数*/
     Map params = new HashMap<>();
     params.put("partyA","华为");
     params.put("partyB","新浪");
     params.put("contractNo","NO2019100506")
     params.put("signTime","2019年10月05日");
     String templatePath = "C:\\Users\\Administrator\\Desktop\\template.docx";
     response.setHeader("Content-Disposition", "attachment;filename=out.doc");
     response.setContentType("'application/msword';charset=UTF-8");
     response.setCharacterEncoding("UTF-8");
     WordTemplateUtil.wordRenderAndGetFromWordTemplate(
       new File(templatePath ), params, response.getOutputStream()
     );
    
 }

 

你可能感兴趣的:(文件处理)