POI实现word文档导出

news2025/6/8 19:57:02

1 需求

在列表页面中点击合同按钮,跳转到合同页面
在这里插入图片描述
页面中有下载按钮,点击下载按钮,把页面展示的内容导出到word中。
在这里插入图片描述

2 分析

2.1 POI操作Word的API介绍

poi对低版本的doc本身支持的就不好所以我们直接说高版本的docx版本的api。

1、poi操作word正文

XWPFDocument代表一个docx文档,其可以用来读docx文档,也可以用来写docx文档

一个文档包含多个段落,一个段落包含多个Runs文本,一个Runs包含多个Run,Run是文档的最小单元

获取所有段落:List<XWPFParagraph> paragraphs = word.getParagraphs();

获取一个段落中的所有片段Runs:List<XWPFRun> xwpfRuns = xwpfParagraph.getRuns();

获取一个Runs中的一个Run:XWPFRun run = xwpfRuns.get(index);

2、poi操作word中的表格

一个文档包含多个表格,一个表格包含多行,一行包含多列单元格

获取所有表格:List<XWPFTable> xwpfTables = doc.getTables();

获取一个表格中的所有行:List<XWPFTableRow> xwpfTableRows = xwpfTable.getRows();

获取一行中的所有列:List<XWPFTableCell> xwpfTableCells = xwpfTableRow.getTableCells();

获取一格里的内容:List<XWPFParagraph> paragraphs = xwpfTableCell.getParagraphs();

之后和正文段落一样

2.2 思路分析

首先我们先制作一个word模板,把动态的内容先写特殊字符然后替换,表格的话需要我们自己创建然后向表格中放内容。
在这里插入图片描述

3 代码实现

第一步:制作模板(模板内容如上图所示),放入到项目中
在这里插入图片描述

第二步:提供根据id查询用户的方法,并且用户中带有办公资源数据

1、User类中添加一个集合属性
在这里插入图片描述

2、UserController代码

提供一个根据用户ID查询用户对象

@GetMapping("/{id}")
public User  findById(@PathVariable("id") Long id){
    return userService.findById(id);
}

3、UserService代码

查询用户信息,并且查询用户的办公用品数据,赋值到用户中

@Autowired
private ResourceMapper resourceMapper;
public User findById(Long id) {
    //查询用户
    User user = userMapper.selectByPrimaryKey(id);
    //根据用户id查询办公用品
    Resource resource = new Resource();
    resource.setUserId(id);
    List<Resource> resourceList = resourceMapper.select(resource);
    user.setResourceList(resourceList);
    return user;
}

第三步:完成导出word功能

Controller代码

@GetMapping(value = "/downloadContract",name = "导出用户合同")
public void downloadContract(Long id,HttpServletResponse response) throws Exception{
    userService.downloadContract(id,response);
}

UserService代码

先准备两个方法,一个是想指定的单元格中放入图片,另一个是 复制word中表格的行


//    向单元格中写入图片
private void setCellImage(XWPFTableCell cell, File imageFile) {

    XWPFRun run = cell.getParagraphs().get(0).createRun();
    //        InputStream pictureData, int pictureType, String filename, int width, int height
    try(FileInputStream inputStream = new FileInputStream(imageFile)) {
        run.addPicture(inputStream,XWPFDocument.PICTURE_TYPE_JPEG,imageFile.getName(), Units.toEMU(100),Units.toEMU(50));
    } catch (Exception e) {
        e.printStackTrace();
    }

}

//    用于深克隆行
private void copyRow(XWPFTable xwpfTable, XWPFTableRow sourceRow, int rowIndex) {
    XWPFTableRow targetRow = xwpfTable.insertNewTableRow(rowIndex);
    targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
    //        获取源行的单元格
    List<XWPFTableCell> cells = sourceRow.getTableCells();
    if(CollectionUtils.isEmpty(cells)){
        return;
    }
    XWPFTableCell targetCell = null;
    for (XWPFTableCell cell : cells) {
        targetCell = targetRow.addNewTableCell();
        //            附上单元格的样式
        //            单元格的属性
        targetCell.getCTTc().setTcPr(cell.getCTTc().getTcPr());
        targetCell.getParagraphs().get(0).getCTP().setPPr(cell.getParagraphs().get(0).getCTP().getPPr());
    }
}

完成导出主体方法

/**
     * 下载用户合同数据
     * @param id
     */
public void downloadContract(Long id,HttpServletResponse response) throws Exception {
    //        1、读取到模板
    File rootFile = new File(ResourceUtils.getURL("classpath:").getPath()); //获取项目的根目录
    File templateFile = new File(rootFile, "/word_template/contract_template.docx");
    XWPFDocument word = new XWPFDocument(new FileInputStream(templateFile));
    //        2、查询当前用户User--->map
    User user = this.findById(id);
    Map<String,String> params = new HashMap<>();
    params.put("userName",user.getUserName());
    params.put("hireDate",simpleDateFormat.format(user.getHireDate()));
    params.put("address",user.getAddress());
    //        3、替换数据
    //         处理正文开始
    List<XWPFParagraph> paragraphs = word.getParagraphs();
    for (XWPFParagraph paragraph : paragraphs) {
        List<XWPFRun> runs = paragraph.getRuns();
        for (XWPFRun run : runs) {
            String text = run.getText(0);
            for (String key : params.keySet()) {
                if(text.contains(key)){
                    run.setText(text.replaceAll(key,params.get(key)),0);
                }
            }
        }
    }
    //         处理正文结束

    //      处理表格开始     名称	价值	是否需要归还	照片
    List<Resource> resourceList = user.getResourceList(); //表格中需要的数据
    XWPFTable xwpfTable = word.getTables().get(0);

    XWPFTableRow row = xwpfTable.getRow(0);
    int rowIndex = 1;
    for (Resource resource : resourceList) {
        //        添加行
        //            xwpfTable.addRow(row);
        copyRow(xwpfTable,row,rowIndex);
        XWPFTableRow row1 = xwpfTable.getRow(rowIndex);
        row1.getCell(0).setText(resource.getName());
        row1.getCell(1).setText(resource.getPrice().toString());
        row1.getCell(2).setText(resource.getNeedReturn()?"需求":"不需要");

        File imageFile = new File(rootFile,"/static"+resource.getPhoto());
        setCellImage(row1.getCell(3),imageFile);
        rowIndex++;
    }
    //     处理表格开始结束
    //        4、导出word
    String filename = "员工(" + user.getUserName() + ")合同.docx";
    response.setHeader("content-disposition", "attachment;filename=" + new String(filename.getBytes(), "ISO8859-1"));
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    word.write(response.getOutputStream());
}

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

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

相关文章

朴素,word,任何参考文献导入endnote

朴素&#xff0c;word&#xff0c;任何参考文献导入endnote 注意&#xff1a;对于以下这几种不做阐述&#xff0c;看其他帖子都有讲述&#xff1a; 这里的参考文献指的是类似于&#xff1a; [1]. Li Y, Lu Y, Huo X, et al. Bandgap tuning strategy by cations and halide io…

【python零基础入门学习】python基础篇之文件对象open、模块以及函数的使用(三)

本站以分享各种运维经验和运维所需要的技能为主 《python》&#xff1a;python零基础入门学习 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8》暂未更新 《docker学习》暂未更新 《ceph学习》ceph日常问题解…

【人月神话】重新探索人月神话:软件工程的现实与挑战

人月神话是一篇由美国软件工程师弗雷德里克布鲁克斯所写的软件工程经典之作&#xff0c;最早发表于1975年。这篇文章的全名是《人月神话&#xff1a;软件工程的神话与现实》&#xff08;The Mythical Man-Month: Essays on Software Engineering&#xff09;&#xff0c;它涵盖…

智慧导览|智能导游系统|AR景区导览系统|景区电子导览

随着文旅市场的加快复苏&#xff0c;以及元宇宙、VR、AR、虚拟数字人等新兴技术的快速发展&#xff0c;文旅行业也正在加快数字化转型的步伐&#xff0c;向智慧景区建设迈进。为满足不同年龄段游客的游览需要&#xff0c;提升旅游服务体验&#xff0c;越来越多的旅游景区、博物…

BlueStore BlueFS rocksdb 关联性梳理

Tag: ceph 12.2.4 BlueStore空间初始化 BlueStore磁盘空间管理 总述 OSD挂载目录基于文件系统管理&#xff0c;Slow、WAL、DB空间区域基于裸盘管理&#xff1b;Slow区域&#xff1a;此类空间主要用于存储对象数据&#xff0c;由BlueStore管理&#xff0c;其中分配于BlueFS空…

如何将枯燥的大数据进行可视化处理?

在数字时代&#xff0c;大数据已经成为商业、科学、政府和日常生活中不可或缺的一部分。然而&#xff0c;大数据本身往往是枯燥的、难以理解的数字和文字&#xff0c;如果没有有效的方式将其可视化&#xff0c;就会错失其中的宝贵信息。以下是一些方法&#xff0c;可以将枯燥的…

Python入门 类class 基础篇

记住一句话&#xff1a;类是模板&#xff0c;而实例则是根据类创建的对象。 我初学时对类的理解是从类的字面上&#xff0c;可以片面的认为它是一个种类&#xff0c;它是相似特征的抽像&#xff0c;也就是相似的东西&#xff0c;可以把相似特征的事务抽象成一个类。&#xff0…

基于串口校时的数字钟设计

文章目录 设计目标硬件设计数码管串口 软件设计顶层模块串口接收模块数据处理模块时钟模块串口发送模块 总结 设计目标 环境&#xff1a;ACX720开发板 实现功能&#xff1a; 数码管能够显示时分秒能够接收串口数据修改时间能够将当前时间以1s一次速率发送到电脑 硬件设计 数…

java之SpringBoot基础篇、前后端项目、MyBatisPlus、MySQL、vue、elementUi

文章目录 前言JC-1.快速上手SpringBootJC-1-1.SpringBoot入门程序制作&#xff08;一&#xff09;JC-1-2.SpringBoot入门程序制作&#xff08;二&#xff09;JC-1-3.SpringBoot入门程序制作&#xff08;三&#xff09;JC-1-4.SpringBoot入门程序制作&#xff08;四&#xff09;…

virtualbox 扩展磁盘大小

此处设置完成后&#xff0c;还需要进入虚拟机&#xff0c;实际扩展磁盘大小 参考 https://zhuanlan.zhihu.com/p/319431032

搭一个shinyAPP就是一篇《Bioinformatics》?

写在前面 原本想引用一番shiny&#xff0c;结果并没有检索出shiny研发团队所发表的论文&#xff0c;倒是有诸多shiny爱好者搭建shinyApp所发表的文章。例如这篇题为“ShinyGO: a graphical gene-set enrichment tool for animals and plants”、于2020年发表于《Bioinformatic…

【AWS】如何用SSH连接aws上的EC2实例(虚拟机)?

目录 0.环境 1.连接结果示例 2.SSH连接思路 3.具体步骤 1&#xff09;安装并运行ssh服务 2&#xff09;启动ssh服务 3&#xff09;在AWS上找到正在运行的EC2实例&#xff0c;并且根据提供的ssh连接语句进行连接 0.环境 windows 11 64位 前提&#xff1a; 有aws账户&…

B. Swap and Reverse

Problem - B - Codeforces 思路&#xff1a;这个题想复杂了&#xff0c;对于第一个条件&#xff0c;我们发现其实就是可以对所有的奇数位置之间任意交换&#xff0c;所有的偶数位置之间任意交换&#xff0c;对于第二个条件来说&#xff0c;如果k为奇数是没有意义的&#xff0c;…

2022年12月 C/C++(七级)真题解析#中国电子学会#全国青少年软件编程等级考试

C/C编程&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;走迷宫 一个迷宫由R行C列格子组成&#xff0c;有的格子里有障碍物&#xff0c;不能走&#xff1b;有的格子是空地&#xff0c;可以走。 给定一个迷宫&#xff0c;求从左上角走到右下角最少需要走多少步…

跑得快的快递和跑得慢的快递差在哪些环节?

快递速度是现代物流的核心竞争力之一&#xff0c;对于电商行业和消费者而言&#xff0c;快捷、高效的快递服务意味着更好的购物体验和更高的客户满意度。大家都有过这样的经历&#xff1a;有时候我们选择了跑得快的快递公司&#xff0c;包裹几乎可以说是眨眼间就到达了目的地&a…

​SIGIR 2023 | 用于序列推荐的多兴趣预训练框架

©PaperWeekly 原创 作者 | 唐作立 单位 | 武汉大学硕士生 研究方向 | 推荐系统 引言 在推荐系统中&#xff0c;由于用户具备多种兴趣的特点&#xff0c;使用多兴趣学习&#xff08;Multi-interest Learning&#xff09;对用户进行建模能够带来显著的性能提升&#xff0c;…

【2023集创赛】加速科技杯二等奖作品:基于ATE的电源芯片测试设计与性能分析

本文为2023年第七届全国大学生集成电路创新创业大赛&#xff08;“集创赛”&#xff09;加速科技杯二等奖作品分享&#xff0c;参加极术社区的【有奖征集】分享你的2023集创赛作品&#xff0c;秀出作品风采&#xff0c;分享2023集创赛作品扩大影响力&#xff0c;更有丰富电子礼…

自然语言处理 微调大模型ChatGLM-6B

自然语言处理 微调大模型ChatGLM-6B 1、GLM设计原理2、大模型微调原理1、P-tuning v2方案2、LORA方案 1、GLM设计原理 bert的主要任务是随机的去除掉某个单词&#xff0c;使用上下文将其预测出来&#xff08;相当于完形填空任务&#xff09;&#xff1b; GPT的主要任务是根据前…

idea配置gitLab

前言&#xff1a;网上有很多类似的文章&#xff0c;但描述不够详细 步骤1&#xff1a;安装git 如果安装成功再次点击TEST按钮展示如下&#xff1a;git版本 步骤2&#xff1a;idea配置gitlab 查看当前项目管理的 远程仓库再git的地址&#xff0c;该地址可是gitLab的&#xff0…

基于sonar 的C#静态代码扫描使用总结

1.原理简介 C#语言接入Sonar代码静态扫描相较于Java、Python来说&#xff0c;相对麻烦一些。Sonar检测C#代码时需要预先编译&#xff0c;而且C#代码必须用MSbuid进行编译&#xff0c;如果需要使用SonarQube对C#进行代码质量分析&#xff0c;则需要Sonar-Scanner-MSBuild和MSBu…