hutool文件导出

hutool文件导出

需求:管理员设置会议,参加会议会根据管理员设置的会议要求,用户参加会议填写相关数据,并且生成一个动态的excel数据并导出

示例:
每场都可以自定义报名字段
在这里插入图片描述
根据需求与前端约定
字段名称(name)
字段类型(type):select-下拉框;fill-填空。
是否必填(required)
字段属性(attribute)
下拉框:single-单选;multiple-多选。
填空:text-⽂本;number-数字。
额外字段
下拉框:options-选项
填空:length-字段长度
字段返回示例:

[
    {
        "name":"姓名",
        "type":"fill",
        "required":true,
        "attribute":"text",
        "length":"10"
    },
    {
        "name":"工作单位",
        "type":"fill",
        "required":true,
        "attribute":"text",
        "length":"20"
    },
    {
        "name":"电话",
        "type":"fill",
        "required":true,
        "attribute":"number",
        "length":"20"
    },
    {
        "name":"会议类型",
        "type":"select",
        "required":true,
        "attribute":"single",
        "options":[
            "考务会",
            "审稿会"
        ]
    },
    {
        "name":"科目",
        "type":"select",
        "required":false,
        "attribute":"single",
        "options":[
            "语文",
            "数学",
            "英语",
            "物理",
            "历史",
            "化学",
            "地理",
            "政治",
            "生物"
        ]
    },
    {
        "name":"是否住宿",
        "type":"select",
        "required":true,
        "attribute":"single",
        "options":[
            "是",
            "否"
        ]
    },
    {
        "name":"性别",
        "type":"select",
        "required":false,
        "attribute":"single",
        "options":[
            "男",
            "女"
        ]
    }
]


用户填写参数示例:

{
    "姓名":"小猪猪",
    "电话":"1734765xxxx",
    "工作单位":"xxx有限公司",
    "会议类型":"考务会",
    "是否住宿":"是",
    "性别":"男"
}

需要生成的报表示例:
序号、报名时间与签到时间是必须有的
在这里插入图片描述

使用hutool的工具ExcelUtil

  • 导包
	<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>5.5.6</version>
		</dependency>

  • 业务代码
   /**
     * 导出用户报名信息
     * conference.getApplyFields() 这个数据示例:
     * [{"name": "姓名","type": "fill","required": true,"attribute": "text","length": "10"},{"name": "工作单位","type": "fill","required": true,"attribute": "text","length": "20"},{"name": "电话","type": "fill","required": true,"attribute": "number","length": "20"},{"name": "会议类型","type": "select","required": true,"attribute": "single","options": ["考务会","审稿会"]},{"name": "科目","type": "select","required": false,"attribute": "single","options": ["语文", "数学", "英语","物理","历史","化学","地理","政治","生物"]},{"name": "是否住宿","type": "select","required": true,"attribute": "single","options": ["是", "否"]},{"name": "性别","type": "select","required": false,"attribute": "single","options": ["男", "女"]}]
     * 
     *conferenceApply.getInformation()这个数据示例:
     *{"姓名":"小猪猪","电话":"1734765xxxx","工作单位":"xxx有限公司","会议类型":"考务会","是否住宿":"是","性别":"男"}
     *
     * @param query 搜索信息
     * @return String
     */
    @Override
    public void conferenceApplyExport(ConferenceApplyListQuery query) throws IOException {
        // 查询会议信息
        Conference conference = conferenceMapper.selectOne(new LambdaQueryWrapper<Conference>()
                .eq(Conference::getConferenceId, query.getConferenceId()).select(Conference::getApplyFields));
        Assert.isTrue(ObjectUtil.isNull(conference), "未找到该会议信息!");
        List<ConferenceApply> conferenceApplyList = conferenceApplyMapper.listQuery(query);
        Assert.isTrue(CollectionUtil.isEmpty(conferenceApplyList), "未找到相关数据");
        ExcelWriter writer = ExcelUtil.getWriter();
        List<Map<String, String>> rows = new ArrayList<>();
        List<Object> list = JSONUtil.parseArray(conference.getApplyFields());
        List<String> names = new ArrayList<>();
        for (Object o : list) {
            Map<String, String> map = (Map<String, String>) JSONUtil.parse(o);
            names.add(map.get("name"));
        }
        int number = 1;
        DateTimeFormatter simpleDateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        for (ConferenceApply conferenceApply : conferenceApplyList) {
            Map<String, String> maps = new HashMap<>();
            maps.put("number", Integer.toString(number));
            Map<String, String> map = (Map<String, String>) JSONUtil.parse(conferenceApply.getInformation());
            // 填充空白数据
            names.forEach(x -> {
                if (!map.containsKey(x)) {
                    map.put(x, "/");
                }
            });
            maps.putAll(map);
            // 报名时间
            maps.put(ConferenceEnum.gmt_apply.getName(), simpleDateFormat.format(conferenceApply.getGmtApply()));
            // 签到时间
            maps.put(ConferenceEnum.gmt_sign.getName(), ObjectUtil.isNotEmpty(conferenceApply.getGmtSign())
                    ? simpleDateFormat.format(conferenceApply.getGmtSign()) : "");
            rows.add(maps);
            number++;
        }

        // 报名时间
        names.add(ConferenceEnum.gmt_apply.getName());
        // 签到时间
        names.add(ConferenceEnum.gmt_sign.getName());
        // Title
        writer.merge(names.size(), "会议报名表");
        // Header
        writer.addHeaderAlias("number", "序号");
        writer.setColumnWidth(0, 20);
        int num = 1;
        for (String key : names) {
             // 设置表头
            writer.addHeaderAlias(key, key);
            // 设置行间距
            writer.setColumnWidth(num, 20);
            num++;
        }
        writer.write(rows, true);
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode("conferenceApplyTable" + DateUtil.today() + ".xls", "utf-8"));

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);

    }

效果:
在这里插入图片描述

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

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

相关文章

Koa学习1:初始化项目

前言 作为前端开发者&#xff0c;最适合我们的后端就是node了&#xff0c;node的框架挺多的。选择Koa是因为国内用的挺多的、关于这方面的教程也很多、而且比较适合小项目。 学习教程是&#xff1a;【杰哥课堂】-项目实战-NodeKoa2从零搭建通用API服务 写这些文章&#xff0…

javascript基础九:说说Javascript中的继承?如何实现继承?

一、是什么 继承&#xff08;inheritance&#xff09;是面向对象软件技术当中的一个概念 如果一个类别B“继承自”另一个类别A&#xff0c;就把这个B称为“A的子类”&#xff0c;而把A称为“B的父类别”也可以称“A是B的超类” 继承的优点 继承可以使得子类具有父类别的各种属性…

Java 版 spring cloud 工程系统管理 工程项目管理系统源码 工程项目各模块及其功能点清单

工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#xff1a;实现对数据字典标签的增删改查操作 2、编码管理&#xff1a;实现对系统编码的增删改查操作 3、用户管理&#xff1a;管理和查看用户角色 4、菜单管理&#xff1a;实现对系统菜单的增删改查操…

【企业化架构部署】Apache网页优化

文章目录 一、Apache网页优化概述1.优化内容2.网页压缩2.1gzip概述2.2作用2.3Apache的压缩模块概述mod_gzip模块与mod_deflate模块 3.配置网页压缩功能3.1启用网页压缩功能步骤3.2具体操作步骤 4.配置网页缓存功能4.1启用网页压缩功能步骤4.2具体操作步骤 二、Apache安全优化1.…

设计模式之~工厂系列(简单工厂、工厂方法、抽象工厂)

目录 简单工厂模式 工厂方法模式 简单工厂 VS 工厂方法 抽象工厂模式&#xff1a; 拓展&#xff1a; 利用简单工厂模式优化抽象工厂 利用反射抽象工厂 进行优化 反射配置文件抽象工厂进行优化 简单工厂模式 优点&#xff1a;简单工厂模式的最大优点在于工厂类包含…

计算机专业主要学习什么

2020计算机专业主要学习什么 1计算机专业都学习哪些方面的知识 1、可视化编程 掌握编程方法和可视化技术&#xff0c;熟悉一个可视化平台及其软件开发技术。能够获取Delphi编程人员系列&#xff0c;Java Basic或VB开发专家认证。 就业方向&#xff1a;企业&#xff0c;政府&…

vue前端分页功能怎么实现

Vue前端分页功能可以通过以下几个步骤实现&#xff1a; 1. 安装分页组件库&#xff08;如vue-pagination-2&#xff09;&#xff1a; bash npm install vue-pagination-2 2. 在Vue项目中引入并注册分页组件&#xff1a; javascript import Vue from vue; import Pagination fr…

传地址给组件并让该组件用到地址在背景图片中的方法

问题 这是我在开发中遇到的问题。在网站的分页面中&#xff0c;背景图片的格式几乎一模一样。只是上面的文字和图片不一样而已。 所以我希望写一个组件&#xff0c;然后页面只需要传入背景图片地址和标题就可以显示出相关内容。 于是我动手写了&#xff0c;大致思路是一个盒…

判断点在多边形内算法的C++实现

本篇博客介绍了使用射线法判断点在多边形内部还是外部的算法&#xff0c;并通过C做了具体实现 1. 算法思路 判断平面内点是否在多边形内有多种算法&#xff0c;其中射线法是其中比较好理解的一种&#xff0c;而且能够支持凹多边形的情况。该算法的思路很简单&#xff0c;就是…

AMEYA360:纳芯微推出车规级耐高压、三线霍尔开关及锁存器NSM101x系列

纳芯微推出全新三线制车规霍尔效应开关/锁存器NSM101x系列&#xff0c;为数字位置检测提供高精度的解决方案&#xff0c;可被广泛应用于汽车执行器等的位置检测。 NSM101x产品系列包含了3个产品型号&#xff0c;即NSM1011(单极霍尔开关)、NSM1012(全极霍尔开关)、NSM1013(霍尔锁…

【Unity】Playable使用细则

【Unity】Playable使用细则 本文基于Unity 2021.3 API。 本文介绍官方文档中没提及的Playable使用限制、注意事项、Bug及规避方案&#xff0c;不是Playable的入门教程&#xff01; 如果你还不熟悉Playable的基础用法&#xff0c;请先学习以下官方文档和示例&#xff1a; Playa…

基于STM32的定时器--定时中断(HAL库)

基于STM32的定时器--定时中断&#xff08;HAL库&#xff09; 介绍引言定时器介绍 实例项目介绍准备设计流程 介绍 引言 本文旨在介绍如何使用STM32CubeMX配置KEIL 5开发一个每10us定时器中断触发一次的项目。帮助初学者入门STM32的定时器使用。 定时器介绍 定时器是STM32微…

chatgpt赋能python:Python升降序排列数字

Python升降序排列数字 在Python编程中&#xff0c;排序是一个非常常见并且重要的操作。Python提供了多种排序算法以满足不同的需求。 排序算法 Python中内置的排序算法有两种&#xff1a;Timsort和Quicksort。其中Timsort是一种混合排序算法&#xff0c;结合了插入排序和归并…

Linux系统中源码安装1.8.x版本Arduino IDE

本文内容参考&#xff1a; Ubuntu22.04安装Arduino IDE及Arduino UNO&#xff08;使用CH341驱动&#xff09;调试方法__KILLMILEDC_的博客-CSDN博客 在Linux上下载arduino_不说话的白帽子的博客-CSDN博客 https://guoqing.blog.csdn.net/article/details/88913063?spm1001.…

Linux NGINX服务 ReWrite^location

ReWrite^location 从功能看 rewrite 和 location 似乎有点像&#xff0c;都能实现跳转&#xff0c;主要区别在于 rewrite 是在同一域名内更改获取资源的路径&#xff0c;而 location 是对一类路径做控制访问或反向代理&#xff0c;还可以proxy_pass 到其他机器。 rewrite 对访问…

c++ new 源码学习一下

之前有一篇文章介绍了 new 的一些用法 c new 在指定内存上创建对象&#xff0c;今天结合源码来学习一下 new 更详细的用法。相关的源码&#xff1a;gcc git 1&#xff0c;void* operator new (std::size_t size); 我们可以在头文件<new>里看到它的原型&#xff1a; _G…

C++11 -- lambda表达式

文章目录 lamaba表达式的引入lambda表达式语法lamabda达式各部分说明捕获列表说明 lamaba表达式底层原理探索 lamaba表达式的引入 在C11之前,如果我们想对自定义类型Goods排序,可以根据姓名,价格,学号按照从大到小或者从小到大的方式排序,可是,这样我们要写额外写6个相关的仿函…

Quest 3初体验,或是苹果MR最大竞争对手

随着苹果MR临近&#xff0c;我们从彭博Mark Gurman了解到更多消息。昨日&#xff0c;Mark Gurman发布了Quest 3上手体验文章&#xff0c;并认为Quest 3可能是苹果MR头显最大的竞争对手。 1&#xff0c;Meta是XR头显领导者 尽管WWDC 23苹果MR将会成为最大的主角&#xff0c;但…

node.js与内置模块

一、目标 能够知道什么是Node.js能够知道Node.js可以做什么能够说出Node.js中的JavaScript的组成部分能够使用fs模块读写操作文件能够使用path模块处理路径能够使用http模块写一个基本的web服务器 二、目录 初始Node.jsfs文件系统模块path路径模块http模块 1.初始Node.js …

macos wireshark 抓取https包

1、启动浏览器 1.1 创建空文件 $ touch /Users/zhujl/Downloads/https/mysslkey.log 2、设置wireshark tls属性&#xff0c;指定tls密钥存储文件 2.1 进入Wireshark Preferfences > Protocols > TLS 属性配置 2.2 勾选上Reassemable TLS records spanning multiple …