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}}
相关推荐
敲代码的小王!2 小时前
MD5加密算法和BCrypt密码加密算法
java·算法·安全
魔尔助理顾问3 小时前
一个简洁高效的Flask用户管理示例
后端·python·flask
李长渊哦6 小时前
使用Druid连接池优化Spring Boot应用中的数据库连接
数据库·spring boot·后端
web135085886356 小时前
【Spring Boot】Spring AOP动态代理,以及静态代理
spring boot·后端·spring
罗政7 小时前
冒险岛079 V8 整合版源码搭建教程+IDEA启动
java·ide·intellij-idea
nbsaas-boot7 小时前
Go 自动升级依赖版本
开发语言·后端·golang
架构默片7 小时前
【JAVA工程师从0开始学AI】,第五步:Python类的“七十二变“——当Java的铠甲遇见Python的液态金属
java·开发语言·python
zzyh1234568 小时前
springcloud的组件及作用
后端·spring·spring cloud
不只会拍照的程序猿8 小时前
从插入排序到希尔排序
java·开发语言·数据结构·算法·排序算法
尚学教辅学习资料8 小时前
基于SpringBoot的图书借阅小程序+LW参考示例
spring boot·后端·小程序·java毕设·图书借阅