poi处理多选框进行勾选操作下载word以及多word文件压缩

一、场景

将数据导出word后且实现动态勾选复选框操作
eg: word模板
在这里插入图片描述
导出后效果(根据数据动态勾选复选框)
在这里插入图片描述

二、解决方案及涉及技术

① 使用poi提供的库进行处理(poi官方文档)
② 涉及依赖

 <!-- excel工具 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
  <!-- pio处理word文件操作复选框-->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
            <version>1.9.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>4.1.2</version>
        </dependency>

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

三、代码实现

word单个/批量下载工具类
在操作模板时,我们需先将写入word模板的数据构建为Map
① 数据封装处理(TrafficBlock 对象)

public Map buildTrafficDataForm(TrafficBlock trafficBlock){
    BlockDownLoadDataForm dataForm = new BlockDownLoadDataForm();
    BeanUtils.copyProperties(trafficBlock, dataForm);
    dataForm.setDirection(EventInfoDirection.getDirection(trafficBlock.getDirection()).getMessage());
    // 涉桥/涉隧
    dataForm.setInvolveNo(String.valueOf(trafficBlock.getInvolveNumber()));
    // 模板数据处理
    dataForm.setStartToEndPile("K"+trafficBlock.getStartKilometersPile()+"+"+trafficBlock.getStartHectometerPile()+"至"+trafficBlock.getEndKilometersPile()+"+"+trafficBlock.getEndHectometerPile());
    dataForm.setAffectedStartToEndPile("K"+trafficBlock.getAffectedStartKilometersPile()+"+"+trafficBlock.getAffectedStartHectometerPile()+"至"+trafficBlock.getAffectedEndKilometersPile()+"+"+trafficBlock.getAffectedEndHectometerPile());
    // 阻断类别(突发类才会有)
    String blockCategory = String.valueOf(trafficBlock.getBlockCategory());
    // checkBox处理
    if("1".equals(trafficBlock.getBlockNature())){
        // 计划类
        dataForm.setPlanCheckBox(String.valueOf(trafficBlock.getBlockType()));
    }else{ //突发类
        if("1".equals(blockCategory)){
            // 地质灾害
            dataForm.setGeologyCheckBox(String.valueOf(trafficBlock.getBlockType()));
        }else if("2".equals(blockCategory)){
            // 重大灾害
            dataForm.setGreatCheckBox(String.valueOf(trafficBlock.getBlockType()));
        }else if("3".equals(blockCategory)){
            // 气象灾害
            dataForm.setWeatherCheckBox(String.valueOf(trafficBlock.getBlockType()));
        }else if("4".equals(blockCategory)){
            // 事故灾害
            dataForm.setAccidentCheckBox(String.valueOf(trafficBlock.getBlockType()));
        }else if("5".equals(blockCategory)){
            // 其他
            dataForm.setOtherCheckBox(String.valueOf(trafficBlock.getBlockType()));
        }
    }
    return convertTrafficBlockToMap(dataForm);
}

② dataMap构建工具

public static Map<String, String> convertTrafficBlockToMap(BlockDownLoadDataForm downLoadDataForm) {
        Map<String, String> valueMap = new HashMap<>();
        Class<?> clazz = downLoadDataForm.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            try {
                Object fieldValue = field.get(downLoadDataForm);
                if (fieldValue == null) {
                    valueMap.put(field.getName(), "");
                } else {
                    valueMap.put(field.getName(), String.valueOf(fieldValue));
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return valueMap;
    }

此处需要注意在多个文件下载时,每次向ZipOutputStream 写入字节流时,需要为每个生成的 Word 文件提供一个唯一的名称(写入的文件名必须不一致)否则会导致每次写入的流覆盖之前的,导致浏览器不能正确解析,进而下载失败!!!

// *****(Word单个/批量下载)
    public void generateTrafficWordForm(HttpServletResponse response, List<Long> ids) throws IOException {
        List<TrafficBlock> trafficBlocks = trafficBlockMapper.selectList(new LambdaQueryWrapper<TrafficBlock>().in(TrafficBlock::getId, ids));
        if (ids.size() == 1){
            // 单个下载
            Map dataMap = buildTrafficDataForm(trafficBlocks.get(0));
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+ URLEncoder.encode("交通阻断记录表.docx","UTF-8"));
            response.setContentType(String.valueOf(MediaType.APPLICATION_OCTET_STREAM));
            try (OutputStream out = response.getOutputStream()) {
                writeTrafficWordForm(dataMap, out);
            }
        }else if (ids.size()  > 1) {
            // 多个文件压缩下载
            response.setContentType("application/zip");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("交通阻断.zip", "UTF-8"));
            try (ZipOutputStream zipOut = new ZipOutputStream(response.getOutputStream())) {
                for (TrafficBlock trafficBlock : trafficBlocks) {
                    Map dataMap = buildTrafficDataForm(trafficBlock);
                    ByteArrayOutputStream wordStream = new ByteArrayOutputStream();
                    writeTrafficWordForm(dataMap, wordStream);
                    // 为每个文件生成唯一的名称
                    String uniqueFileName = "*****_" + trafficBlock.getId() + ".docx";
                    zipOut.putNextEntry(new ZipEntry(uniqueFileName));
                    zipOut.write(wordStream.toByteArray());
                    zipOut.closeEntry();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

poi工具类读取模板处理数据工具:

public void writeTrafficWordForm(Map<String, String> dataMap,OutputStream outputStream) {
        /**
         *  复选框
         * */
        //需要循环的表单数据
        dataMap.put("dataTable", String.valueOf(new ArrayList<>()));

        ConfigureBuilder configureBuilder = Configure.builder().useSpringEL().bind("dataTable", new HackLoopTableRenderPolicy());
        Configure config = configureBuilder.build();
        InputStream is = null;
        try {
            // 读取Word模板文件,获取输入流
            is = new ClassPathResource("template/profile/交通阻断记录表.docx").getInputStream();
            XWPFTemplate template = XWPFTemplate.compile(is, config).render(dataMap);
            template.write(outputStream);
            outputStream.flush();
            PoitlIOUtils.closeQuietlyMulti(template, outputStream);
        } catch (IOException e) {
            log.error("失败!!!!!!", e);
        } finally {
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    log.error("关闭流失败!", e);
                }
            }
        }
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入浅出负载均衡:理解其原理并选择最适合你的实现方式

负载均衡是一种在多个计算资源&#xff08;如服务器、CPU核心、网络链接等&#xff09;之间分配工作负载的技术&#xff0c;旨在优化资源利用率、提高系统吞吐量和降低响应时间。负载均衡的实现方式多种多样&#xff0c;以下是几种常见的实现方式&#xff1a; 1. 硬件负载均衡&…

基于Python机器学习、深度学习技术提升气象、海洋、水文领域实践应用-以ENSO预测为例讲解

1. 背景与目标 ENSO&#xff08;El Nio-Southern Oscillation&#xff09;是全球气候系统中最显著的年际变率现象之一&#xff0c;对全球气候、农业、渔业等有着深远的影响。准确预测ENSO事件的发生和发展对于减灾防灾具有重要意义。近年来&#xff0c;深度学习技术在气象领域…

MySQL表格练习(单表查询,多表查询)

一,单表查询 素材&#xff1a; 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NUL…

postgresql分区表相关问题处理

1.使用pg_cron按日创建分区表&#xff0c;会出现所在数据库对应用户权限不足的问题。 原因是pg_cron运行在postgres数据库中&#xff0c;是用superuser进行执行的&#xff0c;对应的分区表的owner为postgres&#xff0c;所以需要单独授权对表的所有操作权限。不知道直接改变ow…

【数据结构】基础知识

目录 1.1 什么是数据结构 1.2数据 1.3 逻辑结构 1.4 存储结构 1.4.1 顺序存储 1.4.2 链式存储 1.4.3 索引存储 1.4.4 散列存储 1.5 操作 1.1 什么是数据结构 数据的逻辑结构以及存储操作 数据结构没有那么复杂&#xff0c;它就教会你一件事&#xff1a;如何更有效的…

空指针:HttpSession异常,SpringBoot集成WebSocket

异常可能性&#xff1a; 404 &#xff1a; 请检查拦截器是否将请求拦截WebSocket握手期间HttpSession为空 HttpSession为空 方法一 &#xff1a; 网上参考大量的文档&#xff0c;有说跟前端请求域名有关系的。 反正对我来说&#xff0c;没啥用无法连接。 需使用 localhost&a…

相机SD卡照片数据不小心全部删除了怎么办?有什么方法恢复吗?

前几天&#xff0c;小编在后台友收到网友反馈说他在整理相机里的SD卡&#xff0c;原本是想把那些记录着美好瞬间的照片导出来慢慢欣赏。结果手一抖&#xff0c;不小心点了“删除所有照片”&#xff0c;等他反应过来&#xff0c;屏幕上已经显示“删除成功”。那一刻&#xff0c;…

Observability:利用 GCP Vertex AI 集成提升 LLM 可观察性

作者&#xff1a;来自 Elastic Ishleen Kaur•Muthukumar Paramasivam 随着组织越来越多地将 LLM 用于内容创建、检索增强生成 (Retrieval-Augmented Generation - RAG) 和数据分析等 AI 应用&#xff0c;SRE 和开发人员面临着新的挑战。监控工作流、分析输入和输出、管理查询延…

WEB攻防-通用漏洞_XSS跨站_权限维持_捆绑钓鱼_浏览器漏洞

目录 XSS的分类 XSS跨站-后台植入Cookie&表单劫持 【例1】&#xff1a;利用beef或xss平台实时监控Cookie等凭据实现权限维持 【例2】&#xff1a;XSS-Flash钓鱼配合MSF捆绑上线 【例3】&#xff1a;XSS-浏览器网马配合MSF访问上线 XSS的分类 反射型&#xff08;非持久…

21、Transformer Masked loss原理精讲及其PyTorch逐行实现

1. Transformer结构图 2. python import torch import torch.nn as nn import torch.nn.functional as Ftorch.set_printoptions(precision3, sci_modeFalse)if __name__ "__main__":run_code 0batch_size 2seq_length 3vocab_size 4logits torch.randn(batch…

上传自己的镜像到docker hub详细教程

上传自己的镜像到docker hub详细教程 本博客通B站视频一致&#xff1a; 上传自己的镜像到docker hub详细教程 1. 登录自己的hub.docker.com的账号 docker hub仓库 2. 点击Repositories&#xff0c;跳转到创建仓库页面 3. 点击Create a repository 创建repository&#xff0c…

高级软件工程-复习

高级软件工程复习 坐标国科大&#xff0c;下面是老师说的考试重点。 Ruby编程语言的一些特征需要了解要能读得懂Ruby程序Git的基本命令操作知道Rails的MVC工作机理需要清楚&#xff0c;Model, Controller, View各司什么职责明白BDD的User Story需要会写&#xff0c;SMART要求能…

初学stm32 --- SPI驱动25Q128 NOR Flash

目录 SPI介绍 SPI结构框图介绍 SPI外设对应的引脚 SPI数据发送与接收 SPI工作原理 SPI 全双工模式的通信机制 从机返回主机之前保存的数据 SPI工作模式介绍 SPI相关寄存器介绍&#xff08;F1 / F4 / F7&#xff09; SPI控制寄存器1&#xff08;SPI_CR1&#xff09; SPI状…

yum系统报错:SyntaxError: multiple exception types must be parenthesized

执行yum相关步骤报错如下&#xff1a; File "/usr/bin/yum", line 30except KeyboardInterrupt, e:^^^^^^^^^^^^^^^^^^^^ SyntaxError: multiple exception types must be parenthesized原因&#xff1a;python解释器版本错误&#xff0c;yum运行版本为python 2.7&am…

STM32第5章、IWDG

一、简介 IWDG&#xff1a;全称是Independent watchdog&#xff0c;即独立看门狗。本质上是一个能产生系统复位信号的计数器。 特性&#xff1a; 是一个递减计数器。 时钟信号由独立的RC振荡器提供&#xff0c;可在待机和停止模式下运行。 看门狗被激活后&#xff0c;当递减计…

快速上手 HarmonyOS 应用开发

一、DevEco Studio 安装与配置 1. DevEco Studio 简介 DevEco Studio 是 HarmonyOS 的一站式集成开发环境&#xff08;IDE&#xff09;&#xff0c;提供了丰富的工具和功能&#xff0c;支持 HarmonyOS 应用开发的全流程。 2. DevEco Studio 下载与安装 下载地址&#xff1a…

ThinkPHP 8的一对一关联

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…

像JSONDecodeError: Extra data: line 2 column 1 (char 134)这样的问题怎么解决

问题介绍 今天处理返回的 JSON 的时候&#xff0c;出现了下面这样的问题&#xff1a; 处理这种问题的时候&#xff0c;首先你要看一下当前的字符串格式是啥样的&#xff0c;比如我查看后发现是下面这样的&#xff1a; 会发现这个字符串中间没有逗号&#xff0c;也就是此时的J…

国产编辑器EverEdit - 扩展脚本:新建同类型文件(避免编程学习者反复新建保存练习文件)

1 扩展脚本&#xff1a;在当前文件目录下新建同类型文件 1.1 应用场景 用户在进行编程语言学习时&#xff0c;比如&#xff1a;Python&#xff0c;经常做完一个小练习后&#xff0c;又需要新建一个文件&#xff0c;在新建文件的时候&#xff0c;不但要选择文件类型&#xff0c…

Java+Maven+GDAL

下载已经编译好的压缩包&#xff0c;下载地址 解压 jar 包 release-1930-x64-dev.zip\release-1930-x64\bin\gdal\java 目录下 打成Maven依赖 mvn install:install-file -Dfilegdal-3.10.1.jar -DgroupIdorg.gdal -DartifactIdgdal -Dversion3.10.1 -Dpackagingjar -Dgener…