Spring Boot2 集成 poi-tl 实现模板引擎导出 Word

前言

poi-tl(poi template language)是基于Apache POI的Word模板引擎,纯Java组件,跨平台,代码短小精悍,通过插件机制使其具有高度扩展性。

1.Maven

		<!-- excel工具 -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.16</version>
		</dependency>

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>3.16</version>
		</dependency>

		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml-schemas</artifactId>
			<version>3.16</version>
		</dependency>

		<!-- poi-tl导出word -->
		<dependency>
			<groupId>com.deepoove</groupId>
			<artifactId>poi-tl</artifactId>
			<version>1.5.0</version>
		</dependency>

2.application.properties

# 模板路径
data.template.path=D:/workspace/gitlab101/sc-bianguan/target/classes/template/

3.快速开始

新建Word文档list.docx。

3.1.文本模板{{var}}

TextRenderData 或 String 数据模型。

    @ApiOperation(value = "文本模板")
    @PostMapping("/downloadWord1")
    public Result downloadWord1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Map<String,Object> tempMap = new HashMap<>();
        tempMap.put("name", "这是一个文本测试");
        tempMap.put("age", 134);
        //获取文件的相对路径  可在控制台打印查看输出结果
        File file = new File(path + "list.docx");
        /*1.根据模板生成文档*/
        XWPFTemplate template = XWPFTemplate.compile(file).render(tempMap);
        response.setContentType("application/octet-stream");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = "测试";
        URLEncoder.encode(fileName,"UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName="+ fileName +".docx");
        response.flushBuffer();
        template.write(response.getOutputStream());
        return success();
    }

3.2.图片模板{{@var}}

PictureRenderData 数据模型。

    @ApiOperation(value = "图片模板")
    @PostMapping("/downloadWord2")
    public Result downloadWord2(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Map<String,Object> tempMap = new HashMap<>();
        // 本地图片
        tempMap.put("local", new PictureRenderData(80, 100, "F:/图片.jpg"));

        //获取文件的相对路径  可在控制台打印查看输出结果
        File file = new File(path + "list.docx");
        /*1.根据模板生成文档*/
        XWPFTemplate template = XWPFTemplate.compile(file).render(tempMap);
        response.setContentType("application/octet-stream");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = "测试";
        URLEncoder.encode(fileName,"UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName="+ fileName +".docx");
        response.flushBuffer();
        template.write(response.getOutputStream());
        return success();
    }

3.3.表格模板{{#var}}

poi-tl默认实现了N行N列的样式(如下图),同时提供了当数据为空时,展示一行空数据的文案(如下图中的No Data Descs),数据模型是 MiniTableRenderData 。

    @ApiOperation(value = "表格模板")
    @PostMapping("/downloadWord3")
    public Result downloadWord3(HttpServletRequest request, HttpServletResponse response) throws IOException {

        RowRenderData header = RowRenderData.build(new TextRenderData("FFFFFF", "姓名"), new TextRenderData("FFFFFF", "学历"));

        RowRenderData row0 = RowRenderData.build("张三", "研究生");
        RowRenderData row1 = RowRenderData.build("李四", "博士");
        RowRenderData row2 = RowRenderData.build("王五", "博士后");

        Map<String,Object> tempMap = new HashMap<>();

        tempMap.put("table", new MiniTableRenderData(header, Arrays.asList(row0, row1, row2)));

        //获取文件的相对路径  可在控制台打印查看输出结果
        File file = new File(path + "list.docx");
        /*1.根据模板生成文档*/
        XWPFTemplate template = XWPFTemplate.compile(file).render(tempMap);
        response.setContentType("application/octet-stream");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = "测试";
        URLEncoder.encode(fileName,"UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName="+ fileName +".docx");
        response.flushBuffer();
        template.write(response.getOutputStream());
        return success();

3.4.列表模板{{*var}}

NumbericRenderData 数据模型。

    @ApiOperation(value = "列表模板")
    @PostMapping("/downloadWord4")
    public Result downloadWord4(HttpServletRequest request, HttpServletResponse response) throws IOException {

        List<TextRenderData> tempDataList = new ArrayList<>();

        Map<String,Object> tempMap = new HashMap<>();

        TextRenderData data0 = new TextRenderData("这是一个列表测试1");
        TextRenderData data2 = new TextRenderData("这是一个列表测试2");
        tempDataList.add(data0);
        tempDataList.add(data2);

        // 列表样式支持罗马字符、有序无序等
        // FMT_DECIMAL //1. 2. 3.
        // FMT_DECIMAL_PARENTHESES //1) 2) 3)
        // FMT_BULLET //● ● ●
        // FMT_LOWER_LETTER //a. b. c.
        // FMT_LOWER_ROMAN //i ⅱ ⅲ
        // FMT_UPPER_LETTER //A. B. C.
        Pair<Enum, String> numFmt = NumbericRenderData.FMT_LOWER_ROMAN;

        // 列表数据模型
        NumbericRenderData numbericRenderData = new NumbericRenderData(numFmt,tempDataList);
        tempMap.put("list", numbericRenderData);

        //获取文件的相对路径  可在控制台打印查看输出结果
        File file = new File(path + "list.docx");
        /*1.根据模板生成文档*/
        XWPFTemplate template = XWPFTemplate.compile(file).render(tempMap);
        response.setContentType("application/octet-stream");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = "测试";
        URLEncoder.encode(fileName,"UTF-8");
        response.setHeader("Content-Disposition", "attachment;fileName="+ fileName +".docx");
        response.flushBuffer();
        template.write(response.getOutputStream());
        return success();
    }

3.5.其他

还支持很多高级模板功能,详细见官方文档Github源码

注意:

  • poi-tl v1.5.x是构建在Apache poi3.16+和JDK1.6+上的版本。
  • 高版本的建议使用Apache poi4.0.0+和JDK1.8+,poi-tl 最新文档
  • 一定请注意版本问题,不然出现各种BUG会很麻烦。

版权声明:本文为lovelichao12原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。