《SpringBoot2.0 实战》系列-整合thymeleaf 实现模板文件转word打印

前言

最近,有小伙伴看了我的《模板文件转pdf打印》文章后,私信问我,有没有转word的demo。当时只能遗憾的说没有。所以就有了这篇文章。

如何开始

thymeleaf 依赖包

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

thymeleaf配置

spring:
  # thymeleaf
  thymeleaf:
    prefix: classpath:/templates/
    check-template-location: true
    suffix: .html
    encoding: UTF-8
    mode: HTML
    cache: false
    servlet:
      content-type: text/html

模板准备,此处模板和导出pdf的模板一样

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.w3.org/1999/xhtml" layout:decorator="layout">
<head lang="en">
    <title>Spring Boot Demo - PDF</title>
    <style>
        @page {
            size: 210mm 297mm; /*设置纸张大小:A4(210mm 297mm)、A3(297mm 420mm) 横向则反过来*/
            margin: 0.25in;
            padding: 1em;
            @bottom-center{
                content:"葫芦科技 © 版权所有";
                font-family: SimSun;
                font-size: 12px;
                color:red;
            };
            @top-center { content: element(header) };
            @bottom-right{
                content:"第" counter(page) "页  共 " counter(pages) "页";
                font-family: SimSun;
                font-size: 12px;
                color:#000;
            };
        }
        body{font-family: 'SimSun'}
        h2{color: crimson}
        #myheader{
            width: 500px;
            height: 22px;
            border: 1px solid #000000;
        }
        table, th , td  {
            border: 1px solid grey;
            border-collapse: collapse;
            padding: 5px;
        }
        table tr:nth-child(odd) {
            background-color: #f1f1f1;
        }
        table tr:nth-child(even) {
            background-color: #ffffff;
        }
        #input1{
            border-bottom: 1px solid #000000;
        }
    </style>
</head>
<!--这样配置不中文不会显示-->
<!--<body style="font-family: 宋体">-->
<body style="font-family: 'SimSun'">
<div>1.标题-中文</div>
<h2 th:text="${title}"></h2>

<div>2.按钮:按钮的边框需要写css渲染</div>
<button class="a" style="border: 1px solid #000000"> click me t-p</button>
<div id="divsub"></div>

<div>3.普通div</div>
<div id="myheader">Alice's Adventures in Wonderland</div>

<div>4.图片 绝对定位到左上角(注意:图片必须用全路径或者http://开头的路径,否则无法显示)</div>
<img th:src="${imageUrl}"/>

<div>5.普通table表格</div>
<div>
    <table style="width: 700px">
        <tr>
            <th>姓名</th>
            <th>昵称</th>
            <th>年龄</th>
        </tr>
        <tr th:each="info : ${demoList}">
            <td th:text="${info.name}"></td>
            <td th:text="${info.nick}"></td>
            <td th:text="${info.age}"></td>
        </tr>
    </table>

</div>

<div>6.input控件,边框需要写css渲染 (在模板中一般不用input,因为不存在输入操作)</div>
<div>
    <label>姓名:</label>
    <input id="input1" aria-label="葫芦胡" type="text" value="葫芦胡"/>
</div>
</body>
</html>

核心处理类

工具类

/**
 * @Description word处理工具类
 * @Author gourd.hu
 * @Date 2020/5/25 9:42
 * @Version 1.0
 */
@Slf4j
public class WordUtil {


    public static void generateDoc(TemplateEngine templateEngine, String templateName,PrintWriter responseWriter, Map<String,Object> variables) throws UnsupportedEncodingException {
        // 声明一个上下文对象,里面放入要存到模板里面的数据
        final Context context = new Context();
        context.setVariables(variables);
        try(BufferedWriter writer = new BufferedWriter(responseWriter)) {
            templateEngine.process(templateName,context, writer);
        }catch (Exception e){
            ResponseEnum.TEMPLATE_PARSE_ERROR.assertFail(e);
        }

    }
    /**
     * word下载
     *
     * @param templateEngine   配置
     * @param templateName 模板名称
     * @param variables     模板参数集
     * @param response     HttpServletResponse
     * @param fileName     下载文件名称
     */
    public static void download(TemplateEngine templateEngine, String templateName, Map<String, Object> variables, HttpServletResponse response, String fileName) {
        // 断言参数不为空
        ResponseEnum.TEMPLATE_DATA_NULL.assertNotEmpty(variables);
        // 设置编码、文件ContentType类型、文件头、下载文件名
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/msword");
        try {
            response.setHeader("Content-Disposition", "attachment;fileName=" +
                    new String(fileName.getBytes("gb2312"), "ISO8859-1"));
        } catch (UnsupportedEncodingException e) {
            log.error(e.getMessage(), e);
        }
        try (PrintWriter responseWriter = response.getWriter()) {
            generateDoc(templateEngine, templateName, responseWriter, variables);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
    /**
     * word预览
     *
     * @param templateEngine   配置
     * @param templateName 模板名称
     * @param variables     模板参数集
     * @param response     HttpServletResponse
     */
    public static void preview(TemplateEngine templateEngine, String templateName, Map<String, Object> variables, HttpServletResponse response) {
        // 断言参数不为空
        ResponseEnum.TEMPLATE_DATA_NULL.assertNotEmpty(variables);
        // 设置编码、文件ContentType类型、文件头、下载文件名
        response.setCharacterEncoding("gb2312");
        try (PrintWriter responseWriter = response.getWriter()) {
            generateDoc(templateEngine, templateName, responseWriter, variables);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}

controller入口



/**
 * 文档预览、下载
 *
 * @author gourd.hu
 * @version 1.0
 */
@RestController
@RequestMapping(value = "/document")
@Api(tags = "文档预览、下载API")
public class DocumentController {

    @Autowired
    private TemplateEngine templateEngine;

    /**
     * word下载
     *
     * @param response HttpServletResponse
     */
    @GetMapping(value = "/word/download")
    @ApiOperation(value="word下载")
    public void downloadWord(HttpServletResponse response) {
        Map<String,Object> variables = new HashMap<>(4);
        variables.put("title","测试预览Word!");
        variables.put("imageUrl","http://localhost:10001/imgs/sg.jpg");
        List<Map<String,String>> demoList = new ArrayList<>();
        Map<String,String> demoMap = new HashMap<>(8);
        demoMap.put("name","哈哈");
        demoMap.put("nick","娃娃");
        demoMap.put("age","19");
        Map<String,String> demoMap2 = new HashMap<>(8);
        demoMap2.put("name","天天");
        demoMap2.put("nick","饭饭");
        demoMap2.put("age","14");
        demoList.add(demoMap);
        demoList.add(demoMap2);
        variables.put("demoList",demoList);
        WordUtil.download(templateEngine,"pdfPage",variables,response,"测试打印.docx");
    }

    /**
     * word预览
     *
     * @param response HttpServletResponse
     */
    @GetMapping(value = "/word/preview")
    @ApiOperation(value="word预览")
    public void previewWord(HttpServletResponse response) {
        // 构造freemarker模板引擎参数,listVars.size()个数对应pdf页数
        Map<String,Object> variables = new HashMap<>(4);
        variables.put("title","测试预览Word!");
        variables.put("imageUrl","http://localhost:10001/imgs/sg.jpg");
        List<Map<String,String>> demoList = new ArrayList<>();
        Map<String,String> demoMap = new HashMap<>(8);
        demoMap.put("name","哈哈");
        demoMap.put("nick","娃娃");
        demoMap.put("age","19");
        Map<String,String> demoMap2 = new HashMap<>(8);
        demoMap2.put("name","天天");
        demoMap2.put("nick","饭饭");
        demoMap2.put("age","14");
        demoList.add(demoMap);
        demoList.add(demoMap2);
        variables.put("demoList",demoList);
        WordUtil.preview(templateEngine,"pdfPage",variables,response);
    }
}

测试效果

在这里插入图片描述

结语

至此,word打印功能就完成了,如果本文有错误的地方,欢迎评论指正。

===============================================

代码均已上传至本人的开源项目
cloud-plus:https://blog.csdn.net/HXNLYW/article/details/104635673

猜你喜欢

转载自blog.csdn.net/HXNLYW/article/details/106330927