【第013篇】SpringBoot项目基于freemarker模板引擎生成word文件示例和工具类


一、项目中添加依赖

在pom.xml文件中增加如下坐标

<dependency>
	<groupId>org.freemarker</groupId>
	<artifactId>freemarker</artifactId>
	<version>2.3.28</version>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

二、配置文件中增加freemarker配置

在SpringBoot的yml配置文件中增加如下配置:

  freemarker:
    allow-request-override: false                             # 是否允许HttpServletRequest属性覆盖(隐藏)控制器生成的同名模型属性
    allow-session-override: false                             # 是否允许HttpSession属性覆盖(隐藏)控制器生成的同名模型属性
    cache: false                                              # 是否启用模板缓存
    charset: UTF-8                                            # 模板编码
    check-template-location: true                             # 是否检查模板位置是否存在
    content-type: text/html
    enabled: true                                             # 是否启用模板引擎
    expose-request-attributes: false                          # 设定所有request的属性在merge到模板的时候,是否要都添加到model中
    expose-session-attributes: false                          # 是否在merge模板的时候,将HttpSession属性都添加到model中
    expose-spring-macro-helpers: true                         # 设定是否以springMacroRequestContext的形式暴露RequestContextSpring’s macro library使用
    prefer-file-system-access: true                           # 是否优先从文件系统加载template,以支持热加载,默认为true
    request-context-attribute: request
    suffix: .ftl                                              # 设定模板的后缀
    template-loader-path: classpath:/public/template/         # 设定模板的加载路径,多个以逗号分隔
    settings:
      default_encoding: UTF-8
      classic_compatible: true
      template_update_delay: 0

效果图如下:
在这里插入图片描述

三、增加生成word文档的工具类

package io.renren.common.utils;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * word工具类
 */
public class WordUtils {
    /**
     * 根据模板引擎生成Word文件
     *
     * @param dataMap      待填充数据
     * @param templateName 模板文件名称
     * @param filePath     模板文件路径
     * @param fileName     生成的Word文件名称
     * @param response     响应流
     */
    public static void createWord(Map dataMap, String templateName, String filePath, String fileName, HttpServletResponse response) {
        try {
            response.setHeader("content-Type", "application/msword");

            // 创建配置实例
            Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
            // Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
            // 设置编码
            configuration.setDefaultEncoding(StandardCharsets.UTF_8.name());
            // ftl模板文件
            configuration.setClassForTemplateLoading(WordUtils.class, filePath);
            //设置对象包装器
            configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_28));
            //configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS));
            //设置异常处理器
            configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
            // 获取模板
            Template template = configuration.getTemplate(templateName);

            try {
                // 定义输出类型
                response.setContentType("application/octet-stream");
                // 下载文件的默认名称
                response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".doc", StandardCharsets.UTF_8.name()));
                //处理乱码问题
                response.setCharacterEncoding("utf-8");
                //生成Word文档
                template.process(dataMap, response.getWriter());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                response.flushBuffer();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

四、Word文档模板制作

1.word 2003 新建.doc 模板

在这里插入图片描述

2.另存为.xml 文件,格式化代码,并检查是否存在变量分离问题,如图

在这里插入图片描述
如果出现上述类似情况,则需要将其写在一起,${pwd},例如:
在这里插入图片描述

3.重命名为.ftl模板freemarker文件

在这里插入图片描述

五、将.ftl文件放在项目中

在这里插入图片描述

六、编写下载word文档接口

该接口是我公司实际业务,最后会在补充中写一个简单的生成word文档的代码。

@GetMapping("downloadZcsqs")
    @ApiOperation("下载仲裁申请书")
    public void downloadZcsqs(@ApiIgnore @RequestParam("arbitrationId") String arbitrationId, HttpServletResponse response) throws Exception {
        Sq101Zcsqs obj = new Sq101Zcsqs();

        // 性别字典
        List<SysDictDataDTO> gender = sysDictDataService.findListByDictType("gender");
        Map<String, String> genderMap = gender.stream().collect(Collectors.toMap(SysDictDataDTO::getDictValue, SysDictDataDTO::getDictLabel));

        DisputeArbitrationSqfileDTO data = disputeArbitrationSQService.getByArbitrationId(Long.parseLong(arbitrationId));
        if (StringUtils.isNotEmpty(data) && StringUtils.isNotEmpty(data.getDisputeEventEntity())) {
            DisputeEventEntity entity = data.getDisputeEventEntity();
            obj.setApplyName(StringUtils.checkObj2Str(entity.getApplyName(), DV));//申请人-姓名
            obj.setApplyGenderStr(StringUtils.checkObj2Str(genderMap.get(String.valueOf(entity.getApplyGender())), DV));//申请人-性别
            obj.setApplyAge(StringUtils.checkObj2Str(entity.getApplyAge(), DV));//申请人-年龄
            obj.setApplyAddress(StringUtils.checkObj2Str(entity.getApplyAddress(), DV));//申请人-住所
            obj.setZcsqSqryb(StringUtils.checkObj2Str(data.getZcsqSqryb(), DV));//申请人-邮编
            obj.setApplyPhone(StringUtils.checkObj2Str(entity.getApplyPhone(), DV));//申请人-电话
            obj.setZcsqDlrXm(StringUtils.checkObj2Str(data.getZcsqDlrXm(), DV));//申请人-代理人-姓名
            obj.setZcsqDlrXbStr(StringUtils.checkObj2Str(genderMap.get(String.valueOf(data.getZcsqDlrXb())), DV));//申请人-代理人-性别
            obj.setZcsqDlrDw(StringUtils.checkObj2Str(data.getZcsqDlrDw(), DV));//申请人-代理人-单位
            obj.setZcsqDlrZs(StringUtils.checkObj2Str(data.getZcsqDlrZs(), DV));//申请人-代理人-住所
            obj.setZcsqDlrYb(StringUtils.checkObj2Str(data.getZcsqDlrYb(), DV));//申请人-代理人-邮编
            obj.setZcsqDlrDh(StringUtils.checkObj2Str(data.getZcsqDlrDh(), DV));//申请人-代理人-电话
            obj.setApplyCompanyName(DV);//申请人-法人或者其他组织-名称
            obj.setApplyCompanyAddress(DV);//申请人-法人或者其他组织-地址
            obj.setApplyCompanyLegal(DV);//申请人-法定代表人(主要负责人)-姓名
            obj.setApplyCompanyJob(DV);//申请人-法定代表人(主要负责人)-职务
            obj.setApplyCompanyPhone(DV);//申请人-法定代表人(主要负责人)-电话

            obj.setDefendantName(StringUtils.checkObj2Str(entity.getDefendantName(), DV));//被申请人-姓名
            obj.setDefendantGenderStr(StringUtils.checkObj2Str(genderMap.get(String.valueOf(entity.getDefendantGender())), DV));//被申请人-性别
            obj.setDefendantAge(StringUtils.checkObj2Str(entity.getDefendantAge(), DV));//被申请人-年龄
            obj.setDefendantAddress(StringUtils.checkObj2Str(entity.getDefendantAddress(), DV));//被申请人-住所
            obj.setZcsqBsqryb(StringUtils.checkObj2Str(data.getZcsqBsqryb(), DV));//被申请人-邮编
            obj.setDefendantPhone(StringUtils.checkObj2Str(entity.getDefendantPhone(), DV));//被申请人-电话
            obj.setDefendantCompanyName(StringUtils.checkObj2Str(entity.getDefendantCompanyName(), DV));//被申请人-法人或者其他组织-名称
            obj.setDefendantCompanyAddress(StringUtils.checkObj2Str(entity.getDefendantCompanyAddress(), DV));//被申请人-法人或者其他组织-地址
            obj.setDefendantCompanyLegal(StringUtils.checkObj2Str(entity.getDefendantCompanyLegal(), DV));//被申请人-法定代表人(主要负责人)-姓名
            obj.setDefendantCompanyJob(StringUtils.checkObj2Str(entity.getDefendantCompanyJob(), DV));//被申请人-法定代表人(主要负责人)-职务
            obj.setDefendantCompanyPhone(StringUtils.checkObj2Str(entity.getDefendantCompanyPhone(), DV));//被申请人-法定代表人(主要负责人)-电话

            obj.setEventTitle(StringUtils.checkObj2Str(entity.getEventTitle(), DV) + "\t\t\t\t\t\t\t\t\t\t\t");//仲裁请求
            obj.setEventContent(StringUtils.checkObj2Str(entity.getEventContent(), DV) + "\t\t\t\t\t\t\t\t\t\t\t");//事实和理由

            obj.setProofName(StringUtils.checkObj2Str(entity.getProofName(), DV));//证据名称
            obj.setProofSource(StringUtils.checkObj2Str(entity.getProofSource(), DV));//证据来源
            obj.setWitnessName(StringUtils.checkObj2Str(entity.getWitnessName(), DV));//证人姓名
            obj.setWitnessPhone(StringUtils.checkObj2Str(entity.getWitnessPhone(), DV));//联系方式

            obj.setCountFj1(DV + "\t\t");//申请书副本份数
            obj.setCountFj2(DV + "\t\t");//其他有关材料份数
        }
        Map map = new HashMap();
        WordUtils.createWord(map, "101zcsqs.ftl", "/public/template/", "仲裁申请书", response);
    }

相关工具类:

/**
     * 检查对象转换成字符
     *
     * @param value
     * @param defaultValue 如果为null或者空字符串须返回的默认值
     * @return
     */
    public static String checkObj2Str(Object value, Object defaultValue) {
        if (value == null || value.toString().trim().equals("")) {
            value = defaultValue;
        }
        return value.toString().trim();
    }

    /**
     * 将对象转换为集合
     *
     * @param obj
     * @return
     */
    public static Map<String, Object> objectToMap(Object obj) {
        Map<String, Object> map = new HashMap<>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true);
            try {
                if (fields[i].get(obj) != null) {
                    map.put(fields[i].getName(), fields[i].get(obj));
                }
            } catch (Exception e) {

            }
            fields[i].setAccessible(false);
        }
        return map;
    }

实体类:

package io.renren.modules.dispute.word;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

@Data
@ApiModel(value = "仲裁申请书")
public class Sq101Zcsqs implements Serializable {
    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "申请人-姓名")
    private String applyName;

    @ApiModelProperty(value = "申请人-性别")
    private String applyGenderStr;

    @ApiModelProperty(value = "申请人-年龄")
    private String applyAge;

    @ApiModelProperty(value = "申请人-住所")
    private String applyAddress;

    @ApiModelProperty(value = "申请人-邮编")
    private String zcsqSqryb;

    @ApiModelProperty(value = "申请人-电话")
    private String applyPhone;

    @ApiModelProperty(value = "申请人-代理人-姓名")
    private String zcsqDlrXm;

    @ApiModelProperty(value = "申请人-代理人-性别")
    private String zcsqDlrXbStr;

    @ApiModelProperty(value = "申请人-代理人-单位")
    private String zcsqDlrDw;

    @ApiModelProperty(value = "申请人-代理人-住所")
    private String zcsqDlrZs;

    @ApiModelProperty(value = "申请人-代理人-邮编")
    private String zcsqDlrYb;

    @ApiModelProperty(value = "申请人-代理人-电话")
    private String zcsqDlrDh;

    @ApiModelProperty(value = "申请人-法人或者其他组织-名称")
    private String applyCompanyName;

    @ApiModelProperty(value = "申请人-法人或者其他组织-地址")
    private String applyCompanyAddress;

    @ApiModelProperty(value = "申请人-法定代表人(主要负责人)-姓名")
    private String applyCompanyLegal;

    @ApiModelProperty(value = "申请人-法定代表人(主要负责人)-职务")
    private String applyCompanyJob;

    @ApiModelProperty(value = "申请人-法定代表人(主要负责人)-电话")
    private String applyCompanyPhone;

    @ApiModelProperty(value = "被申请人-姓名")
    private String defendantName;

    @ApiModelProperty(value = "被申请人-性别")
    private String defendantGenderStr;

    @ApiModelProperty(value = "被申请人-年龄")
    private String defendantAge;

    @ApiModelProperty(value = "被申请人-住所")
    private String defendantAddress;

    @ApiModelProperty(value = "被申请人-邮编")
    private String zcsqBsqryb;

    @ApiModelProperty(value = "被申请人-电话")
    private String defendantPhone;

    @ApiModelProperty(value = "被申请人-法人或者其他组织-名称")
    private String defendantCompanyName;

    @ApiModelProperty(value = "被申请人-法人或者其他组织-地址")
    private String defendantCompanyAddress;

    @ApiModelProperty(value = "被申请人-法定代表人(主要负责人)-姓名")
    private String defendantCompanyLegal;

    @ApiModelProperty(value = "被申请人-法定代表人(主要负责人)-职务")
    private String defendantCompanyJob;

    @ApiModelProperty(value = "被申请人-法定代表人(主要负责人)-电话")
    private String defendantCompanyPhone;

    @ApiModelProperty(value = "仲裁请求")
    private String eventTitle;

    @ApiModelProperty(value = "事实和理由")
    private String eventContent;

    @ApiModelProperty(value = "证据名称")
    private String proofName;

    @ApiModelProperty(value = "证据来源")
    private String proofSource;

    @ApiModelProperty(value = "证人姓名")
    private String witnessName;

    @ApiModelProperty(value = "联系方式")
    private String witnessPhone;

    @ApiModelProperty(value = "申请书副本份数")
    private String countFj1;

    @ApiModelProperty(value = "其他有关材料份数")
    private String countFj2;
}

效果图:
在这里插入图片描述


补充

在这里插入图片描述

上述中模板文件链接:

链接:https://pan.baidu.com/s/1Ios7tRo2M9evsrBdM4t1JA
提取码:2022

链接:https://pan.baidu.com/s/1RPm6DCxT-JBIEO4koELPHw
提取码:2022

链接:https://pan.baidu.com/s/1BLdLJIJcGN2Gyrs3M_nFOQ
提取码:2022

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘉&年华

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值