Java通过FreeMarker模板生成Word文件

1、引用依赖

compile('org.freemarker:freemarker:2.3.20')

2、制作Word文件

新建word文件,调整内容和格式,需要动态传参的地方使用占位符,如图:

Java通过FreeMarker模板生成Word文件_第1张图片

3、Word文件转换为模板
打开Word文件,另存为,XML格式文件,如图:

Java通过FreeMarker模板生成Word文件_第2张图片

4、编写工具类

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

/**
 * 导出word
 * 
 * @className ExportWordUtils
 * @author yangzhipeng
 * @version V1.0 2019年3月7日 上午11:04:03 TODO(如果是修改版本,描述修改内容)
 */
public class ExportWordUtils {
    private Configuration configuration = null;

    public ExportWordUtils() {
        configuration = new Configuration();
        configuration.setDefaultEncoding("UTF-8");
    }

    /**
     * 下载起租通知书
     * 
     * @param noticeInfo
     * @param response
     * @param request
     */
    public void createWord(NoticeInfo noticeInfo, HttpServletResponse response,
        HttpServletRequest request) {
        configuration.setClassForTemplateLoading(this.getClass(), "/templates");// 模板文件所在路径
        Template t = null;
        try {
            t = configuration.getTemplate("起租通知书.ftl"); // 获取模板文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        File outFile = new File(noticeInfo.getContAddendumNum() + ".doc"); // 导出文件
        Writer out = null;
        try {
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }

        try {
            t.process(getData(noticeInfo), out); // 将填充数据填入模板文件并输出到目标文件
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        response.setContentType("text/html;charset=utf-8");
        try {
            request.setCharacterEncoding("UTF-8");
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        java.io.BufferedInputStream bis = null;
        java.io.BufferedOutputStream bos = null;

        try {
            long fileLength = outFile.length();
            response.setContentType("application/msword");
            response.setHeader("Content-disposition", "attachment; filename="
                + URLEncoder.encode("起租通知书_" + noticeInfo.getContAddendumNum() + ".doc", "utf-8"));
            response.setHeader("Content-Length", String.valueOf(fileLength));
            bis = new BufferedInputStream(new FileInputStream(outFile));
            bos = new BufferedOutputStream(response.getOutputStream());
            byte[] buff = new byte[2048];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bis != null) try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (bos != null) try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                outFile.delete();
            } catch (Exception e2) {
            }
        }

    }

    /**
     * 传入yyyy-mm-dd返回yyyy年mm月dd日
     * 
     * @param date
     * @return
     */
    private String formatDate(String date) {
        if (StringUtils.isBlank(date)) {
            return date;
        }
        if (date.contains("-")) {
            String[] ymd = date.split("-");
            if (ymd == null || ymd.length != 3) {
                return date;
            } else {
                return ymd[0] + "年" + ymd[1] + "月" + ymd[2] + "日";
            }
        }
        return date;
    }

    /**
     * 文档千分位
     * 
     * @param str
     * @return
     */
    private static String formatXxx(String str) {
        NumberFormat nf = new DecimalFormat("#,###.##");
        if (StringUtils.isNotBlank(str)) {
            Double valueOf = 0D;
            try {
                valueOf = Double.valueOf(str.replaceAll(",", ""));
            } catch (Exception e) {
                return str;
            }
            String format = nf.format(valueOf);
            if (format.contains(".")) {
                String[] split = format.split("\\.");
                if (split[1].length() < 2) {
                    format += "0";
                }
            } else {
                format += ".00";
            }
            return format;
        } else {
            return str;
        }
    }

    /**
     * 处理起租通知书数据
     * 
     * @param noticeInfo
     * @return
     */
    private Map getData(NoticeInfo noticeInfo) {
        Map dataMap = new HashMap<>();
        dataMap.put("lease_way", noticeInfo.getLeaseWay());
        dataMap.put("lease_inception", noticeInfo.getLeaseInception());
        dataMap.put("dept_name", noticeInfo.getDeptName());
        dataMap.put("cont_atta_num", noticeInfo.getContAddendumNum());
        dataMap.put("project_name", noticeInfo.getProjectName());
        dataMap.put("business_class", noticeInfo.getBusinessClass());
        dataMap.put("lease_type", noticeInfo.getLeaseType());
        dataMap.put("lessee", noticeInfo.getLessee());
        dataMap.put("cont_amount", formatXxx(noticeInfo.getContAmount()));
        dataMap.put("rent_0", formatXxx(noticeInfo.getRent0()));
        dataMap.put("principal", formatXxx(noticeInfo.getPrincipal()));
        dataMap.put("interest", formatXxx(noticeInfo.getInterest()));
        dataMap.put("poundage", formatXxx(noticeInfo.getPoundage()));
        dataMap.put("management_cost", formatXxx(noticeInfo.getManagementCost()));
        dataMap.put("nominal_cost", formatXxx(noticeInfo.getNominalCost()));
        dataMap.put("salvage", formatXxx(noticeInfo.getSalvage()));
        dataMap.put("notarial_fees", formatXxx(noticeInfo.getNotarialFees()));
        dataMap.put("premium", formatXxx(noticeInfo.getPremium()));
        dataMap.put("rent", formatXxx(noticeInfo.getRent()));
        dataMap.put("margin_money", formatXxx(noticeInfo.getMarginMoney()));
        dataMap.put("cont_date", formatDate(noticeInfo.getContDate()));
        dataMap.put("lease_inception", noticeInfo.getLeaseInception());
        dataMap.put("currency", noticeInfo.getCurrency());
        dataMap.put("proj_manager", noticeInfo.getProjManager());
        dataMap.put("is_group", noticeInfo.getIsGroup());
        dataMap.put("periods", noticeInfo.getPeriods());
        dataMap.put("end_date", formatDate(noticeInfo.getEndDate()));
        dataMap.put("date", formatDate(DateUtil.formatYMD(new Date())));
        return dataMap;
    }

    /**
     * 生成ems打印单
     * 
     * @param eWTM
     * @param str
     * @return
     */
    public boolean replaceModelToWord(EmsWaybillTemplateModel eWTM, String attachmentUrl) {
        boolean flag = false;
        configuration.setClassForTemplateLoading(this.getClass(), "/templates");// 模板文件所在路径
        Template t = null;
        try {
            t = configuration.getTemplate("EMS.ftl"); // 获取模板文件
        } catch (IOException e) {
            e.printStackTrace();
        }
        File outFile = new File(attachmentUrl); // 导出文件
        Writer out = null;
        try {
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }

        try {
            t.process(getData(eWTM), out); // 将填充数据填入模板文件并输出到目标文件
            flag = true;
        } catch (TemplateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * @param eWTM
     * @return
     */
    private Object getData(EmsWaybillTemplateModel eWTM) {
        Map dataMap = new HashMap<>();
        dataMap.put("customerReceiptPeople",
            eWTM.getCustomerReceiptPeople() == null ? "" : eWTM.getCustomerReceiptPeople());
        dataMap.put("customerContactNo",
            eWTM.getCustomerContactNo() == null ? "" : eWTM.getCustomerContactNo());
        dataMap.put("customerName", eWTM.getCustomerName() == null ? "" : eWTM.getCustomerName());
        dataMap.put("customerAddress",
            eWTM.getCustomerAddress() == null ? "" : eWTM.getCustomerAddress());
        dataMap.put("customerCode", eWTM.getCustomerCode() == null ? "" : eWTM.getCustomerCode());
        dataMap.put("customerZipCode",
            eWTM.getCustomerZipCode() == null ? "" : eWTM.getCustomerZipCode());
        return dataMap;
    }


}
 

总结:

调用工具类的时,动态传参;
工具类中包含直接下载、生成word文件到服务器指定路径,两种方式。

模板参数Map中可传入list,进入模板中循环展示,可进行 list循环、if判断、获取长度下标等:

<#list details as d>
  <#if (details?size != d_index+1)>、<#else>。

你可能感兴趣的:(日常笔记)