使用htool工具导出和导入Excel表

embedded/2025/3/18 13:40:23/

htool官网
代码中用到的hool包里面的excel工具ExcelUtil

1. 引入依赖

    <!-- Java的工具类 --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.25</version></dependency><!-- 操作office文件 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.4.0</version></dependency></dependencies>

excel_20">2. 导出excel

// adminList就是从数据库查询到的数据
private void writeExcel(HttpServletResponse response,List<Admin> adminList) throws Exception {// 1. 构建writer对象ExcelWriter writer = ExcelUtil.getWriter(true);	// 参数true,是否为xlsx格式// 2. 设置表头,第一个参数是实体类的属性名,第二个参数是excel文件中要呈现的列名writer.addHeaderAlias("username", "用户名");writer.addHeaderAlias("name", "姓名");writer.addHeaderAlias("phone", "手机号");writer.addHeaderAlias("email", "邮箱");// 在写excel文件时只写上面设置了别名的属性,如果不设置就算设置了别名也会把数据库查询到的所有信息都写入excel文件writer.setOnlyAlias(true);// 3. 写标题,合并0-3合计4个单元格,标题内容,这个不是必须的writer.merge(3, "用户信息表"); // 写excel是按顺序写入的,先写标题// 4. 将数据库的文件写入,第二个参数:是否强制写标题writer.write(adminList, true);// 5. 固定写法,设置响应类型和响应头response.setContentType("application/vnd.ms-excel;charset=utf-8");String fileName = URLEncoder.encode("管理员信息", StandardCharsets.UTF_8);  // 对“管理员信息”汉字进行编码response.setHeader("Content-Disposition","attachment;filename=" + fileName + ".xlsx");// 6. 写出到流并关闭ServletOutputStream out = response.getOutputStream();writer.flush(out, true);writer.close();// 关闭writer,释放内存IoUtil.close(out);//此处记得关闭输出Servlet流}
  • 用于参考的接口
// 导出选择id的数据,参数ids是要导出数据id的数组@GetMapping("/exportExcel")public void exportExcel(Integer[] ids, HttpServletResponse response) throws Exception {List<Admin>  allData = adminService.selectByIds(ids);try{writeExcel(response, allData);}catch (Exception e){throw new CustomException("导出失败");	// 自定义的异常处理}}

3. 导入Excel表

1. 使用element上传组件

  • 注意name属性,这是传递给接口的名字,要与接口的参数名对应
      <el-upload:show-file-list="false"accept=".xls,.xlsx"name="a":on-success="handleImport"action="http://localhost:8080/admin/importExcel"style="display: inline-block;margin-left: 10px;position: relative;top:1px"><el-button type="info">批量导入</el-button></el-upload>

2. 接口代码

  @PostMapping("/importExcel")public Result<String> importExcel(MultipartFile a) throws Exception {	// 注意参数a要与前端<el-upload>组件的nama属性对应//  1. 拿到输入流 构建 readerInputStream inputStream = a.getInputStream();ExcelReader reader = ExcelUtil.getReader(inputStream);//  2. 通过Reader 读取 excel 里面的数据,第一个参数是Excel表中的标题行,第二个参数是实体类中对应的属性reader.addHeaderAlias("用户名", "username");reader.addHeaderAlias("姓名", "name");reader.addHeaderAlias("手机号", "phone");reader.addHeaderAlias("邮箱", "email");//    读取全部数据,默认第一行为标题行,从第二行开始读取数据
//    List<Admin> list = reader.readAll(Admin.class);// 我的excel设置了大标题的表头,第一个参数指定标题行的位置是1,第二个参数是数据开始行位置,第三个参数是实体类List<Admin> list = reader.read(1,2,Admin.class);// 3. 将数据写到数据库Integer i = adminService.addAdminBatch(list);return Result.ok("共导入了"+i+"条信息");}

3. 返回数据

// 批量导入按钮点击事件
const handleImport = (response) => {if (response.code === "1") {load()	// 重新加载页面的列表数据ElMessage.success(`导入成功,${response.data}`)} else {ElMessage.error(response.msg)}
}

4. 使用axios发送请求导出文件

  • 使用认证后,前端发送window.open请求不方便携带token
  • 后端发送文件的代码没有改变

1. 使用axios请求代替windows.open()

    request.get('/admin/exportExcel', {params: {ids: ids.join(',')},// Axios 会将服务器返回的响应数据封装成一个 Blob 对象responseType: 'blob',	})

2. 在拦截器中获取文件

// 响应拦截器
service.interceptors.response.use(response => {if (response.config.responseType === "blob") {// 从响应头中获取 Content-Dispositionconst contentDisposition = response.headers["content-disposition"];let extractedFileName = '';if (contentDisposition) {// 使用正则表达式匹配文件名const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);if (matches != null && matches[1]) {// 去除引号,decodeURIComponent:对文件名编码处理extractedFileName = decodeURIComponent(matches[1].replace(/['"]/g, ''));}// 如果没有从响应头中获取到文件名,则使用传入的 fileName 或默认值extractedFileName = extractedFileName || "下载文件";const blob = new Blob([response.data]);const a = document.createElement("a");const url = window.URL.createObjectURL(blob);a.href = url;a.download = extractedFileName;a.click();window.URL.revokeObjectURL(url);ElMessage.success('文件下载成功');return Promise.resolve();}......
}

3. 对跨域请求过滤器配置

  • 原因:在跨域请求中,浏览器默认只允许访问部分简单响应头,如 Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,若要访问其他自定义响应头,需要在后端明确设置 ExposedHeaders。
	@Configurationpublic class CorsConfig {	     // 配置跨域请求过滤器@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedOrigin("*");config.addAllowedHeader("*");config.addAllowedMethod("*");// 暴露 Content-Disposition 响应头,允许前端访问config.addExposedHeader("Content-Disposition");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}}

http://www.ppmy.cn/embedded/173603.html

相关文章

正则表达式的基本应用以及查询工具

首先&#xff0c;是对于基本的正则表达式的应用以及部分介绍(见代码注释部分): 以javaScript为例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-wi…

算法刷题整理合集(四)

本篇博客旨在记录自已的算法刷题练习成长&#xff0c;里面注有详细的代码注释以及和个人的思路想法&#xff0c;希望可以给同道之人些许帮助。本人也是算法小白&#xff0c;水平有限&#xff0c;如果文章中有什么错误或遗漏之处&#xff0c;望各位可以在评论区指正出来&#xf…

力扣hot100二刷——二叉树

第二次刷题不在idea写代码&#xff0c;而是直接在leetcode网站上写&#xff0c;“逼”自己掌握常用的函数。 标志掌握程度解释办法⭐Fully 完全掌握看到题目就有思路&#xff0c;编程也很流利⭐⭐Basically 基本掌握需要稍作思考&#xff0c;或者看到提示方法后能解答⭐⭐⭐Sl…

高级java每日一道面试题-2025年3月04日-微服务篇[Eureka篇]-Eureka是什么?

如果有遗漏,评论区告诉我进行补充 面试官: Eureka是什么&#xff1f; 我回答: 在Java高级面试中&#xff0c;关于Eureka的讨论通常会涵盖其基本概念、组件与架构、工作原理、高级特性以及与其他服务发现工具的比较等多个方面。以下是结合提供的内容对Eureka进行的详细解析和…

Python 鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

C++特性——智能指针

为什么需要智能指针 对于定义的局部变量&#xff0c;当作用域结束之后&#xff0c;就会自动回收&#xff0c;这没有什么问题。 当时用new delete的时候&#xff0c;就是动态分配对象的时候&#xff0c;如果new了一个变量&#xff0c;但却没有delete&#xff0c;这会造成内存泄…

每日学习Java之一万个为什么

场景启动器&#xff1a;starter 参考常见启动器 默认配置 官网默认值 依赖 见官网 / pom父依赖 注解 SpringBootApplication&#xff1a;启动自动装配&#xff0c;配合 main SpringApplication.run&#xff08;.class,args&#xff09; SpringBootTest&#xff1a;Spri…

MySQL数据库备份工具:binlog详细操作与实战指南

MySQL的binlog&#xff08;二进制日志&#xff09;是MySQL数据库中非常重要的日志文件&#xff0c;它记录了所有对数据库的修改操作&#xff08;如INSERT、UPDATE、DELETE等&#xff09;。通过 binlog&#xff0c;我们可以实现数据恢复、主从复制、数据审计等功能。因此&#x…