Java使用模板导出word、pdf

news2024/11/23 14:42:48

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

模板样例:

导出结果:

一、引入相关依赖
        <!--        工具类-->
        <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>
二、创建导出数据实体类
@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;
    
}
@AllArgsConstructor
@NoArgsConstructor
@Data
@ApiModel(value = "ExportListVO", description = "导出集合VO")
public class ExportListVO {


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


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

}

 

三、业务代码

 /**
     * 文档导出
     *
     * @param fileType 导出文件类型:1-docx,2-pdf
     * @param response 响应流
     */
    @Override
    public void exportFile(Integer fileType, HttpServletResponse response) throws IOException {
        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方法
  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}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1068728.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DiffusionDet:第一个用于物体检测的扩散模型(DiffusionDet: Diffusion Model for Object Detection)

提出了一种新的框架——DiffusionDet&#xff0c;它将目标检测定义为一个从有噪声的盒子到目标盒子的去噪扩散过程。在训练阶段&#xff0c;目标盒从真实值盒扩散到随机分布&#xff0c;模型学会了逆转这个噪声过程。 在推理中&#xff0c;该模型以渐进的方式将一组随机生成的框…

【Java每日一题】— —第二十四题:编程定义一个长方形类Rectangle(2023.10.08)

&#x1f578;️Hollow&#xff0c;各位小伙伴&#xff0c;今天我们要做的是第二十四题。 &#x1f3af;问题&#xff1a; &#xff08;1&#xff09;定义成员变量&#xff1a;长&#xff08;int height&#xff09;&#xff0c;宽&#xff08;int width&#xff09;&#xf…

springboot整合pi支付开发

pi支付流程图&#xff1a; 使用Pi SDK功能发起支付由 Pi SDK 自动调用的回调函数&#xff08;让您的应用服务器知道它需要发出批准 API 请求&#xff09;从您的应用程序服务器到 Pi 服务器的 API 请求以批准付款&#xff08;让 Pi 服务器知道您知道此付款&#xff09;Pi浏览器向…

如何系列 如何使用ff4j实现功能迭代

文章目录 功能开关是什么为什么需要功能开关&#xff1f;功能流程组件业务接入端常用Api 功能开关管理端 高级面向切面 AOP审计和监控缓存微服务中使用 概念功能 Feature功能存储 FeatureStore属性 Property属性存储 PropertyStoreFF4J架构FF4J使用开关策略 FlippingStrategy功…

【赠书活动】如何让AI在企业多快好省的落地

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

优化理论笔记

目录 一、前言 二、优化问题的基本要素 三、优化问题分类 四、最优值类型 五、最优化方法分类 六、非约束优化 1、问题定义 2、优化算法 1&#xff09;一般局部搜索过程 2&#xff09;集束搜索 3&#xff09;禁忌搜索 4&#xff09;模拟退火 5&#xff09;蛙跳算法…

使用Resnet进行图像分类训练

本文仅给出最基础的baseline进行图像分类训练&#xff0c;后续可在此代码基础上对模型结构进行修改。 一、图像分类数据集 现有一份图像类别数据集&#xff0c;类别为Y和N&#xff0c;数据目录如下&#xff1a; /datasets/data/ |-- train/ | |-- Y/ | |-- N/划分训练集…

超自动化加速落地,助力运营效率和用户体验显著提升|爱分析报告

RPA、iPaaS、AI、低代码、BPM、流程挖掘等在帮助企业实现自动化的同时&#xff0c;也在构建一座座“自动化烟囱”。自动化工具尚未融为一体&#xff0c;协同价值没有得到释放。Gartner于2019年提出超自动化&#xff08;Hyperautomation&#xff09;概念&#xff0c;主要从技术组…

法律战爆发:“币安退出俄罗斯引发冲击波“

币安是全球最大的加密货币交易所之一&#xff0c;经历了几个月的艰难时期&#xff0c;面临着各种法律挑战&#xff0c;最近将其俄罗斯分公司的所有资产出售给了一家几天前才成立的公司。 这家主要交易所的麻烦始于 6 月份&#xff0c;当时美国证券交易委员会 (SEC)起…

PyTorch Lightning - LightningModule 训练逻辑 (training_step) 异常处理 try-except

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/133673820 在使用 LightningModule 框架训练模型时&#xff0c;因数据导致的训练错误&#xff0c;严重影响训练稳定性&#xff0c;因此需要使用 t…

消费者的力量:跨境电商如何满足新一代的需求

当代跨境电商行业正处于高速发展的阶段&#xff0c;而新一代消费者正在塑造这一行业的未来。他们的需求和消费行为发生了巨大变化&#xff0c;对于跨境电商来说&#xff0c;满足这一新一代消费者的需求至关重要。本文将探讨新一代消费者的需求以及跨境电商如何满足这些需求的方…

【Bond随你温故Azure Architecture】之HADR篇

上次复盘数据保护策略还是在《数据需要找回怎么办&#xff1f;我们如何选择正确的恢复/退回方式&#xff1f;》探讨了在application&DB层面上&#xff0c;不同level的数据保护有不同策略。而它也恰好是今天HA&DR版图的一角&#xff08;RDBMS部分&#xff09;&#xff0…

【机器学习】svm

参考 sklearn中SVC中的参数说明与常用函数_sklearn svc参数-CSDN博客https://blog.csdn.net/transformed/article/details/90437821 参考PYthon 教你怎么选择SVM的核函数kernel及案例分析_clfsvm.svc(kernel)-CSDN博客https://blog.csdn.net/c1z2w3456789/article/details/10…

【Python_PySide2学习笔记(十六)】多行文本框QPlainTextEdit类的的基本用法

多行文本框QPlainTextEdit类的的基本用法 前言正文1、创建多行文本框2、多行文本框获取文本3、多行文本框获取选中文本4、多行文本框设置提示5、多行文本框设置文本6、多行文本框在末尾添加文本7、多行文本框在光标处插入文本8、多行文本框清空文本9、多行文本框拷贝文本到剪贴…

什么是EJB以及和Spring Framework的区别

&#x1f454; 前言 EJB&#xff0c;对于新生代程序员来说&#xff0c;是一个既熟悉又陌生的名词&#xff0c;EJB&#xff0c;大家都听说过&#xff0c;但是不一定都了解过&#xff0c;EJB是一种开发规范&#xff0c;而不是像Spring Framework一样是一个开源框架&#xff0c;E…

卫星/RedCap/高算力/解决方案/创新金奖……移远通信为IOTE 2023再添新活力

9月20日&#xff0c;IOTE 2023第二十届国际物联网展深圳场震撼来袭。 作为IOTE多年的“老朋友”&#xff0c;移远通信在参展当天&#xff0c;不仅有5G RedCap、卫星通信、高算力、车载等高性能产品及终端展出&#xff0c;还携智慧出行、智慧生活、智慧能源、工业互联网等多领域…

redis集群是符合cap中的ap还是cp

近期忽然间考虑到了这个问题。 cap 理论 cap是实现分布式系统的思想。 由3个元素组成。 Consistency&#xff08;一致性&#xff09; 在任何对等 server 上读取的数据都是最新版&#xff0c;不会读取出旧数据。比如 zookeeper 集群&#xff0c;从任何一台节点读取出来的数据…

SpringBoot 如何配置 OAuth2 认证

在Spring Boot中配置OAuth2认证 OAuth2是一种用于授权的开放标准&#xff0c;允许应用程序安全地访问用户的资源。Spring Boot提供了强大的支持&#xff0c;使得在应用程序中配置OAuth2认证变得非常容易。本文将介绍如何在Spring Boot中配置OAuth2认证&#xff0c;以便您可以在…

ThreeJS-3D教学六-物体位移旋转

之前文章其实也有涉及到这方面的内容&#xff0c;比如在ThreeJS-3D教学三&#xff1a;平移缩放物体沿轨迹运动这篇中&#xff0c;通过获取轨迹点物体动起来&#xff0c;其它几篇文章也有旋转的效果&#xff0c;本篇我们来详细看下&#xff0c;另外加了tween.js知识点&#xff0…

基于SpringBoot的靓车汽车销售网站

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 车辆展示管理 车辆品牌管理 用户交流管理 购物车 用户交流 我的订单管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的…