SpringBoot+Vue实现Excel文档导入和导出

1.准备工作

1.1.前端程序

在前端首先加上批量导出的按钮,如下

<el-button size="small" type="warning" plain @click="exportData">
批量导出
</el-button>

 在添加了点击事件之后,在methods中要与之对应的添加上exportData的方法,其中multipleSelection是复选框中勾选后用户的id,下面的代码逻辑为,当我没有勾选复选框的时候(也就是multipleSelection的长度为0时)就执行导出功能

//批量导出exportData(){//没有选择行的时候全部导出,或者根据搜索条件导出if(!this.multipleSelection.length){}},

 1.2.后端程序

前端基本架构写好了,接下来我们开始写后端的接口,如下 

  • 接口的参数有两个,一个是用户的名字,一个是response对象(为了获取输出流,将Excel写回浏览器)
  • 借助hutool工具包提供的ExcelUtil类获取一个ExcelWrite对象(别忘了导入hutool的jar包)
<!--hutool工具包-->
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.16</version>
</dependency>
  • 执行查询所有用户,将结果添加到write对象中
  • 在获取了输出流之后,将write对象写到流里
     /*** 批量导出* @param name*/@GetMapping("/export")public void exportData(@RequestParam(required = false) String name, HttpServletResponse response) throws IOException {ExcelWriter writer = ExcelUtil.getWriter(true);List<User> list = new ArrayList<>();//第一种:全部导出(当name为空的时候执行,也就是说前端没有勾选复选框时,全部导出)if(StringUtils.isBlank(name)){//查询所有用户list = userService.list();}writer.write(list,true);//获取输出流ServletOutputStream outputStream = response.getOutputStream();//将excel写入到输出流里,并设置用完流之后就关闭writer.flush(outputStream,true);}

2.完善工作

这个时候,后端的程序也基本写好了,现在返回前端来写请求,我的请求之中添加了token,因为之前添加过jwt验证,如果没有token的话,就不能访问,但是之前在axios的请求头中都添加了token,而这个请求是js中的,所以要自己手动在请求路径中添加一个token(而之前后端程序中写了,如果请求头里没有token,那么后台会自己在请求路径中寻找token)

  //批量导出exportData(){//没有选择行的时候全部导出,或者根据搜索条件导出if(!this.multipleSelection.length){window.open('http://localhost:8082/user/export?token='+this.user.token)}},

3.测试

前后端框架基本写好了,接下来进行测试,启动前后端工程后,点击批量导出

可以看到,报了500的错误,那就表明是后台代码写的有问题,返回后端查看,发现控制台报了以下错误

这个错误比较经典,在对Excel进行处理的时候我们必须引入一个叫POI-OOXML的依赖,如下:

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

接下来,进行测试,发现下载的文件是zip类型的,这与Excel表格格式后缀xlsx不符,所以我们还要在后台添加导出的文件格式

response.setContentType("application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet;charset=utf-8");
response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("用户信息表","UTF-8")+".xlsx");
  • setContentType设置了HTTP响应的Content-Typeapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet,这表示响应的内容是一个Excel文件,即OpenXML格式的电子表格。charset=utf-8指定了字符编码为UTF-8。
  • setHeader设置了HTTP响应的Content-Disposition头,其值为attachment,表示响应的内容是附件,浏览器会提示用户下载该文件。filename=后面跟的是附件的默认文件名,这里通过URLEncoder.encode方法对"用户信息表"进行了URL编码,以确保文件名中的非ASCII字符在HTTP头中正确传输。编码后的字符串加上.xlsx后缀,构成了完整的文件名。

4.第二次测试

加上了响应格式之后,我们再来一次测试,如下:

可以看到,该文件名字已经被修改成“用户信息表”,并且格式也不是之前的.zip,而是Excel的格式,打开文件,如下:

可以看到表头对应的是实体类的字段名,那么如何将表头换成中文呢?

只需要在实体类的字段上加上@Alias注解并设置别名即可(注意:这个@Alias注解是hutool包下的,不是mybatis包下的),如下: 

 加上注解之后,再进行测试,Excel表头就会被修改成指定的名称

到目前为止,Excel导出的功能就完成了,但是还要修改一下业务逻辑

  • 当我不进行模糊查询的时候,点击批量导出,则要导出全部的数据
  • 当我进行模糊查询的时候,点击批量导出,则要导出查询出来的全部数据

所以我要给代码修改一下逻辑,如下:

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(StringUtils.isNotBlank(name),User::getName,name);list = userService.list(wrapper);

添加一个模糊查询,并设置一个条件,只有当name的值不为空,才会进行模糊查询,否则就不会添加模糊查询的条件,这样就完成了上面提出的业务要求

 5.完善后的前后端代码

@GetMapping("/export")public void exportData(@RequestParam(required = false) String name, HttpServletResponse response) throws IOException {ExcelWriter writer = ExcelUtil.getWriter(true);List<User> list = new ArrayList<>();//第一种:全部导出(当name为空的时候执行,也就是说前端没有勾选复选框时,全部导出)LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.like(StringUtils.isNotBlank(name),User::getName,name);//if(StringUtils.isBlank(name)){//查询所有用户list = userService.list(wrapper);//}writer.write(list,true);response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("用户信息表","UTF-8")+".xlsx");//获取输出流ServletOutputStream outputStream = response.getOutputStream();//将excel写入到输出流里,并设置用完流之后就关闭writer.flush(outputStream,true);//关闭writewriter.close();}

前端添加的代码是要给请求添加一个name属性,这样后台才能接收到name,如下:

 //批量导出exportData(){//没有选择行的时候全部导出,或者根据搜索条件导出if(!this.multipleSelection.length){window.open('http://localhost:8082/user/export?token='+this.user.token+'&name='+this.name)}},

 测试如下:

首先查询姓王的用户,查询结果如下:

 然后再导出,结果如下:

自此,初步功能已经完善

6.勾选复选框之后进行导出

之前完成的是,不勾选复选框,然后进行全部数据的导出,和进行模糊搜索之后,将搜索出的数据进行全部导出 

整体思路

  • 要想勾选复选框之后对指定的数据进行导出,那么在勾选复选框之后就要把该用户的id传给后端,由于可以选择多个用户,那么前端传的数据应该是一个数组类型,但是GET方法传不了数组,所以我们可以将其转换成字符串类型,然后后端用String类型接收,然后再将字符串转换成List集合进行查询(为什么要转换成集合,因为mybatis-plus中的条件构造器in需要一个list类型的参数) 

在前端添加id的请求参数,如下,第一行程序意思是,将前端复选框勾选的用户的id数组转换成字符串,并且以逗号分隔,类似于"1","2","3"

let idStr = this.multipleSelection.join(',');
window.open('http://localhost:8082/user/export?token='+this.user.token+'&ids=' + idStr)

 后端用String类型的参数即可接收,如下:

  @RequestParam(required = false) String ids

 接下来的工作就是将字符串类型的参数转换成list集合,并将其添加到条件查询器里,如下:

//将字符串按逗号分割成数组
String[] id = ids.split(",");
//使用Stream API 将字符串数组转换为整数集合
List<Integer> userId = Arrays.stream(id).map(Integer::valueOf).collect(Collectors.toList());
wrapper.in(StringUtils.isNotBlank(ids),User::getId,userId);

全部代码

后端:

    /*** 批量导出* @param name*/@GetMapping("/export")public void exportData(@RequestParam(required = false) String name,@RequestParam(required = false) String ids,HttpServletResponse response) throws IOException {ExcelWriter writer = ExcelUtil.getWriter(true);List<User> list = new ArrayList<>();//第一种:全部导出(当name为空的时候执行,也就是说前端没有勾选复选框时,全部导出)LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();//如果ids不为空(也就是我勾选了复选框),就执行将传进来的ids字符串转换成数组类型的操作然后导出勾选的用户数据,否则就执行全部导出if(StringUtils.isNotBlank(ids)){//将字符串按逗号分割成数组String[] id = ids.split(",");// 使用 Stream API 将字符串数组转换为整数集合List<Integer> userId = Arrays.stream(id).map(Integer::valueOf).collect(Collectors.toList());wrapper.in(StringUtils.isNotBlank(ids),User::getId,userId);}else {wrapper.like(StringUtils.isNotBlank(name),User::getName,name);}list = userService.list(wrapper);writer.write(list,true);response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");response.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode("用户信息表","UTF-8")+".xlsx");//获取输出流ServletOutputStream outputStream = response.getOutputStream();//将excel写入到输出流里,并设置用完流之后就关闭writer.flush(outputStream,true);//关闭writewriter.close();}

前端: 

//批量导出exportData(){//没有选择行的时候全部导出,或者根据搜索条件导出if(!this.multipleSelection.length){window.open('http://localhost:8082/user/export?token='+this.user.token+'&name=' + this.name)}else {//不加","也可以,join默认会加上let idStr = this.multipleSelection.join(',');window.open('http://localhost:8082/user/export?token='+this.user.token+'&ids=' + idStr)}},

7.批量导入功能实现

  • 由于Excel文件导入和文件上传本质一样,所以后端接口的参数也要一个MultipartFile
  • 同样的,Excel文件导入也要借助ExcelUtil,其中的getReader方法需要一个Input流作为参数,而MultipartFile类型能获取InputStream
  • 获取到reader之后,readAll方法将Excel文件中的数据读取为一个User对象的列表。User.class是Java反射中用来指定类的。
  • 获取到Excel表中的User类型的数据集合,再调用mybatisplus中的方法,将数据写入数据库
  • 其中这个ServiceException是自定义的异常

后端: 

    @PostMapping("/import")public Result importData(MultipartFile file) throws IOException {try {//获取inputStream流InputStream inputStream  = file.getInputStream();ExcelReader reader = ExcelUtil.getReader(inputStream);List<User> userList = reader.readAll(User.class);userService.saveBatch(userList);} catch (Exception e) {throw new ServiceException("文件上传失败");}return Result.success();}

前端: 

 来看看上传文件的前端代码,如下:

  • 文件上传是一个特定的代码,其中Element-UI规定了以下格式,其中有几个属性需要了解
  • action 后面跟请求路径
  • :headers  后面跟要在这个请求的请求头里添加的东西
  • :show-file-list  表示文件上传成功后要不要显示上传成功的文件的列表,false表示关闭,true表示开启
  • :on-success  后面跟文件上传成功之后的事件,handleImport事件如下:
    //批量导入handleImport(res,file,fileList){console.log(res)this.load(1)if (res.code === '200'){this.$message.success("上传成功")}else {this.$message.error(res.msg)}},
<el-uploadstyle="display: inline-block;margin-left: 10px"action="http://localhost:8082/user/import":headers="{token:user.token}":show-file-list="false":on-success="handleImport"><el-button size="small" plain type="primary">文件导入</el-button>
</el-upload>

 到此为止,该模块的功能全部实现>_<

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

汽车IVI中控开发入门及进阶(二十七):车载摄像头vehicle camera

前言: 在车载IVI、智能座舱系统中,有一个重要的应用场景就是视频。视频应用又可分为三种,一种是直接解码U盘、SD卡里面的视频文件进行播放,一种是手机投屏,就是把手机投屏软件已视频方式投屏到显示屏上显示,另外一种就是对视频采集设备(主要就是摄像头Camera)的视频源…

3ds Max软件下载安装:3D建模软件 轻松开启你的建模之旅!

3ds Max&#xff0c;在建模过程中&#xff0c;网格建模和NURBS建模两大技术发挥着不可或缺的作用。网格建模允许用户通过顶点、边和面等元素的调整&#xff0c;精确地塑造出模型的形态&#xff1b;而NURBS建模则以其优秀的曲线和曲面处理能力&#xff0c;为设计师们提供了更为平…

二分+ST表+递推,Cf 1237D - Balanced Playlist

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 1237D - Codeforces 二、解题报告 1、思路分析 case3提示我们一件事情&#xff1a;如果存在某个位置永远不停止&#xff0c;那么所有位置都满足永远不停止 很容易证明 随着下标右移&#xff0c…

【Ruby基础01】windows和termux中搭建Ruby开发环境

windows下环境搭建 railsinstaller官方git地址 按照文档安装git、nodejs、yarn&#xff0c;安装教程百度一下。railsinstall可以从release页面下载最新版本4.1.0。 安装完成如下 安装RubyMine 下载RubyMine RubyMine下载地址 安装激活 下载文件&#xff0c;按照里面的流程…

Houdini到UE地形流程

目录 Houidni地形制作 UE地形设置 Houdini engine插件安装 B站参考视频 Houidni地形制作 使用Terrain的HeightField相关节点制作地形&#xff1b;设置地形相关的材质层&#xff08;如rock、soil、grass等&#xff09;&#xff0c;注意材质的重叠&#xff1b; //detail层级&…

Python网络爬虫4-实战爬取pdf

1.需求背景 爬取松产品中心网站下的家电说明书。这里以冰箱为例&#xff1a;松下电器-冰箱网址 网站分析&#xff1a; 第一步&#xff1a; 点击一个具体的冰箱型号&#xff0c;点击了解更多&#xff0c;会打开此型号电器的详情页面。 第二步&#xff1a;在新打开的详情页面中…

Linux top 命令使用教程

转载请标明出处&#xff1a;https://blog.csdn.net/donkor_/article/details/139775547 文章目录 一、top 是什么二、top的基础语法三、top输出信息解读 一、top 是什么 Linux top 是一个在Linux和其他类 Unix 系统上常用的实时系统监控工具。它提供了一个动态的、交互式的实时…

关于Mysql 中 Row size too large (> 8126) 错误的解决和理解

提示&#xff1a;啰嗦一嘴 &#xff0c;数据库的任何操作和验证前&#xff0c;一定要记得先备份&#xff01;&#xff01;&#xff01;不会有错&#xff1b; 文章目录 问题发现一、问题导致的可能原因1、页大小2、行格式2.1 compact格式2.2 Redundant格式2.3 Dynamic格式2.4 Co…

Redis的安装及详解

1.Redis介绍&#xff1f; 1.1 Redis是什么&#xff1f; Redis&#xff08;Remote Dictionary Server,远程字典服务器&#xff09;是一个开源免费的&#xff0c;用C语言编写的一个高性能的分布式内存数据库&#xff0c;基于内存运行并支持持久化的NoSQL数据库。是当前最热门的…

Apache Doris 基础 -- 部分数据类型及操作

您还可以使用SHOW DATA TYPES;查看Doris支持的所有数据类型。 部分类型如下&#xff1a; Type nameNumber of bytesDescriptionSTRING/可变长度字符串&#xff0c;默认支持1048576字节(1Mb)&#xff0c;最大精度限制为2147483643字节(2gb)。大小可以通过BE配置string_type_le…

【Perl】与【Excel】

引言 perl脚本语言对于文本的处理、转换很强大。对于一些信息量庞大的文本文件&#xff0c;看起来不直观&#xff0c;可以将信息提取至excel表格中&#xff0c;增加数据分析的可视化。perl语言的cpan提供了大量模块。对于excel文件的操作主要用到模块&#xff1a; Spreadshee…

Elasticsearch过滤器(Filter):原理及使用

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

【数据库编程-SQLite3(一)】sqlite3数据库在Windows下的配置及测试

学习分析 1、资源准备2、环境配置2.1、将资源包下载解压缩保存。2.2、在QT中创建工程,配置环境 3、测试配置3.1、 sqlite3_open函数3.2、sqlite3_close函数3.3、代码测试 1、资源准备 资源包 2、环境配置 2.1、将资源包下载解压缩保存。 解压缩得到以下文件 2.2、在QT中创建…

第十五章 观察者模式

目录 1 观察者模式介绍 2 观察者模式原理 3 观察者模式实现 4 观察者模式应用实例 5 观察者模式总结 1 观察者模式介绍 观察者模式的应用场景非常广泛&#xff0c;小到代码层面的解耦&#xff0c;大到架构层面的系统解耦&#xff0c;再或者 一些产品的设计思路&#xff0c…

图卷积网络(Graph Convolutional Network, GCN)

图卷积网络&#xff08;Graph Convolutional Network, GCN&#xff09;是一种用于处理图结构数据的深度学习模型。GCN编码器的核心思想是通过邻接节点的信息聚合来更新节点表示。 图的表示 一个图 G通常表示为 G(V,E)&#xff0c;其中&#xff1a; V 是节点集合&#xff0c;…

【perl】环境搭建

1、Vscode Strawberry Perl 此过程与tcl环境搭建很类似&#xff0c;请参考我的这篇文章&#xff1a; 【vscode】 与 【tclsh】 联合搭建tcl开发环境_tclsh软件-CSDN博客 perl语言的解释器可以选择&#xff0c;strawberry perl。Strawberry Perl for Windows - Releases。 …

对于补码的个人理解

1. 十进制的取模计算 现在我想要使另一个数加上2后用8取模后也等于1&#xff0c;这个数可以是哪些&#xff1f; 这个问题比较简单&#xff0c;只需要-1加上8的倍数即可 例如&#xff1a; 如果我们想要得到距离-1这个负数最近的一个正数7&#xff0c;直接使用-18即可。反过来想…

C# WinForm —— 36 布局控件 GroupBox 和 Panel

1. 简介 两个可以盛放其他控件的容器&#xff0c;可以用于把不同的控件分组&#xff0c;一般不会注册事件 GroupBox&#xff1a;为其他控件提供可识别的分组。可通过Text属性设置标题&#xff1b;有边框&#xff1b;没有滚动条&#xff0c;一般用于按功能分组 Panel&#xff…

白酒:中国的酒文化的传承与发扬

中国&#xff0c;一个拥有五千年文明史的国度&#xff0c;其深厚的文化底蕴孕育出了丰富多彩的酒文化。在这片广袤的土地上&#xff0c;酒不仅仅是一种产品&#xff0c;更是一种情感的寄托&#xff0c;一种文化的传承。云仓酒庄的豪迈白酒&#xff0c;正是这一文化脉络中的一颗…

CentOS系统自带Python2无法使用pip命令

Linux运维工具-ywtool 目录 一. 系统环境二.解决三.验证四.备注(1)输入"yum install -y python-pip",提示没有可用 python-pip包(2)安装完pip后进行升级 一. 系统环境 centos7系统自带的python2.7无法使用pip命令 二.解决 yum install python-pip -y三.验证 pip…