Java使用模板导出word、pdf

使用deepoove根据模板导出word文档,包括文本、表格、图表、图片,使用WordConvertPdf可将word文档转换为pdf导出

模板样例:
导出结果:
一、引入相关依赖
XML 复制代码
        <!--        工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.16</version>
        </dependency>
        <!--        poi-->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.11.1</version>
        </dependency>
        <!--        word转pdf-->
        <dependency>
            <groupId>WordConvertPdf</groupId>
            <artifactId>WordConvertPdf</artifactId>
            <version>1.0</version>
        </dependency>
二、创建导出数据实体类
java 复制代码
@AllArgsConstructor
@NoArgsConstructor
@Data
@ApiModel(value = "ExportVO", description = "导出VO")
public class ExportVO {

    @ApiModelProperty(value = "标题")
    private String title;

    @ApiModelProperty(value = "名称")
    private String name;

    @ApiModelProperty(value = "数量")
    private Integer num;

    @ApiModelProperty(value = "集合数据")
    private List<ExportListVO> list;

    @ApiModelProperty(value = "表格")
    private List<ExportListVO> table;

    @ApiModelProperty(value = "柱状图")
    private ChartMultiSeriesRenderData barChart;

    @ApiModelProperty(value = "饼图")
    private ChartSingleSeriesRenderData pieChart;

    @ApiModelProperty(value = "折线图")
    private ChartMultiSeriesRenderData lineChart;

    @ApiModelProperty(value = "图片")
    private PictureRenderData img;
    
}
java 复制代码
@AllArgsConstructor
@NoArgsConstructor
@Data
@ApiModel(value = "ExportListVO", description = "导出集合VO")
public class ExportListVO {


    @ApiModelProperty(value = "类型")
    private String type;


    @ApiModelProperty(value = "数量")
    private Integer num;

}
三、业务代码
java 复制代码
 /**
     * 文档导出
     *
     * @param fileType 导出文件类型:1-docx,2-pdf
     * @param response 响应流
     */
    @Override
    public void exportFile(Integer fileType, HttpServletResponse response) throws IOException {
        //模板地址,存放在resources目录下
        String filePath = "templates/word/test.docx";
        //使用poi-tl进行模板处理
        ConfigureBuilder builder = Configure.builder();
        builder.useSpringEL(true);
        //执行循环策略
        LoopRowTableRenderPolicy strategy = new LoopRowTableRenderPolicy();
        //绑定集合对象
        builder.bind("list", strategy);
        builder.bind("table", strategy);
        //获取模板文件流
        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
        assert inputStream != null;
        //组装数据
        ExportVO data = this.createData();
        XWPFTemplate render = XWPFTemplate.compile(inputStream, builder.build()).render(data);
        // 设置强制下载不打开
        response.setContentType("application/force-download");
        response.addHeader("Access-Control-Expose-Headers", " Content-Disposition");
        if (fileType.equals(1)) {
            //如果需要导出为word
            response.addHeader("Content-Disposition", "attachment; fileName=" + new String(("导出模板.docx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            render.write(response.getOutputStream());
        } else if (fileType.equals(2)) {
            //如果需要导出为pdf
            response.addHeader("Content-Disposition", "attachment; fileName=" + new String(("导出模板.pdf").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
            BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            //设置临时文件的地址
            String tempPath = UUID.randomUUID() + ".docx";
            //根据模板生成临时文件
            render.writeToFile(tempPath);
            //将docx流转换为pdf流
            FileInputStream fileInputStream = new FileInputStream(tempPath);
            WordConvertPdf.getPdfStreamByWordStream(fileInputStream, outputStream);
            outputStream.flush();
            outputStream.close();
            fileInputStream.close();
            //删除临时文件
            File tempFile = new File(tempPath);
            Files.delete(tempFile.toPath());
            log.debug("删除临时word文件:{}", tempPath);
        }
    }

需要注意的时,文档中需要循环的数必须绑定biulder

四、组装数据,createData方法
java 复制代码
  private ExportVO createData() {
        ExportVO data = new ExportVO();
        //普通文本
        data.setTitle("食品统计");
        data.setName("蔬菜统计");
        data.setNum(60);
        //集合数据
        List<ExportListVO> list = new ArrayList<>();
        list.add(new ExportListVO("黄瓜", 10));
        list.add(new ExportListVO("茄子", 20));
        list.add(new ExportListVO("番茄", 30));
        //添加循环文本数据
        data.setList(list);
        //添加表格数据
        data.setTable(list);
        //添加柱状图数据
        ChartMultiSeriesRenderData barChart = new ChartMultiSeriesRenderData();
        barChart.setChartTitle("蔬菜统计柱状图");
        barChart.setCategories(list.stream().map(ExportListVO::getType).toArray(String[]::new));
        List<SeriesRenderData> barChartSeriesData = new ArrayList<>();
        barChartSeriesData.add(new SeriesRenderData("箱", list.stream().map(ExportListVO::getNum).toArray(Integer[]::new)));
        barChart.setSeriesDatas(barChartSeriesData);
        data.setBarChart(barChart);
        //添加饼图数据
        ChartSingleSeriesRenderData pieChart = new ChartSingleSeriesRenderData();
        pieChart.setChartTitle("蔬菜统计饼图");
        pieChart.setCategories(list.stream().map(ExportListVO::getType).toArray(String[]::new));
        pieChart.setSeriesData(new SeriesRenderData("箱", list.stream().map(ExportListVO::getNum).toArray(Integer[]::new)));
        data.setPieChart(pieChart);
        //添加折现图
        ChartMultiSeriesRenderData lineChart = new ChartMultiSeriesRenderData();
        lineChart.setChartTitle("蔬菜统计折线图");
        lineChart.setCategories(list.stream().map(ExportListVO::getType).toArray(String[]::new));
        List<SeriesRenderData> lineChartSeriesData = new ArrayList<>();
        lineChartSeriesData.add(new SeriesRenderData("箱", list.stream().map(ExportListVO::getNum).toArray(Integer[]::new)));
        lineChart.setSeriesDatas(lineChartSeriesData);
        data.setLineChart(lineChart);
        //添加图片
        PictureRenderData img = new PictureRenderData(800, 200, "D:\\files\\img\\test.jpg");
        data.setImg(img);
        return data;
    }
五、模板说明
1.这里面由{{}}包裹的内容对应ExportVO 实体中的属性名称
2.这里的list对应ExportVO实体中的list属性,循环list写入文本,并判断是否是最后一条数据,最后一条数据由.句号结尾
3.table对应ExportVO实体中table属性,type和num对应集合实体类ExportListVO中的type和num
4.模板中右键柱状图,查看可选文字,修改替换文字为ExportVO实体中柱状图属性名称{{barChart}}
5.模板中右键饼图,查看可选文字,修改替换文字为ExportVO实体中饼图属性名称{{pieChart}}
6.模板中右键折线图,查看可选文字,修改替换文字为ExportVO实体中折线图属性名称{{lineChart}}
7.模板中右键图片,查看可选文字,修改替换文字为ExportVO实体中图片属性名称{{img}}
相关推荐
captain3761 分钟前
网络编程(1)
java·网络·ide·java-ee
李少兄5 分钟前
JavaScript 运算符完全指南
java·开发语言·javascript
极客互动API10 分钟前
企业微信 AI 智能客服实战:Spring Boot+Vue 接入豆包、扣子、DeepSeek
java·人工智能·微信·企业微信
今天AI了吗10 分钟前
Codex使用技巧:深度解析 Plan Mode 与 Goal Mode
java·网络·人工智能·架构·java-ee
Huangxy__11 分钟前
java+ai 全栈项目
java·开发语言
阿维的博客日记16 分钟前
Example API指南2
java·mybatis
拖孩17 分钟前
一个人 + AI 做的小程序,一个月赚了 36 块
前端·后端·微信小程序
神仙别闹21 分钟前
基于C#实现(WinForm)文件管理系统
java·开发语言·c#
砚底藏山河27 分钟前
存储选型实战:CSV-SQLite-MySQL同机基准(魔码量化实战 #02)
java·数据库·python·金融·maven
huaweichenai27 分钟前
spring boot 打包并部署到线上服务
java·数据库·spring boot