Post 和 Get 两种方式实现数据导出Excel文件并下载
Post 和 Get 两种方式实现数据导出Excel文件并下载
前端使用Vue,后端使用Springboot。
一般而言,使用post方式是比较方便的。但有时候,需要下载的数据在后端进行查询的时候很比较复杂的查询条件,而这个查询条件是前端进行下载请求的时候传递的参数,如果参数比较复杂或参数量比较大,超出了get方式的参数限制,就需要使用post方式进行下载请求。
Post方式:
后端将查询到的数据作一些处理之后,将数据写入到请求的响应体中,前端在请求接口之后,在回调函数中,将响应体中的二进制流转化为Blob对象,然后创建一个下载链接进行下载。
后端代码:
@PostMapping("/export") public void export(HttpServletResponse response, @RequestParam("className") String className) { try { // 根据班级名获取该班级的所有学生的信息 List list = StudentService.lists(className); // 为了导出的表格中有序号,在定义实体类的时候加了一个serialNo属性 for(int i = 0; i < list.size(); i++) { list.get(i).setSerialNo(i + 1); } // 设置excel文件的名字,这边可以不用,在前端重新设置了文件名 String name = "学生信息列表.xlsx"; String fileName = new String(name.getBytes("gb2312"), "ISO8859-1"); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition","attachment;filename=" + fileName); // 这里注册的 CustomCellWriteHandler工具类是用来在excel中适应内容自动调整表格宽度的 ExcelWriter writer = EasyExcel.write(response.getOutputStream()).registerWriteHandler(new CustomCellWriteHandler()).build(); WriteSheet sheet = EasyExcel.writerSheet(0,"sheet").head(BillList.class).build(); writer.write(list,sheet); writer.finish(); } catch (Exception e) { log.info("jjj", e); } }
Student 实体类:
@Datapublic class Student{ // ExcelIgnore 注册表示该属性不导出到excel @ExcelIgnore private Integer id; @ExcelProperty(value = "班级", index = 1) private String className; @ExcelProperty(value = "学号", index = 2) private String studentNumber; @ExcelProperty(value = "姓名", index = 3) private String name; @ExcelProperty(value = "性别", index = 4) private String gender; @ // 导出excel的序号列, index值表示在导出的excel中的第几列,从0开始 @ExcelProperty(value = "序号", index = 0) private Integer serialNo;}
CustomCellWriteHandler工具类:
import com.alibaba.excel.enums.CellDataTypeEnum;import com.alibaba.excel.metadata.CellData;import com.alibaba.excel.metadata.Head;import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;import org.apache.commons.collections4.CollectionUtils;import org.apache.poi.ss.usermodel.Cell;import java.util.HashMap;import java.util.List;import java.util.Map;public class CustomCellWriteHandler extends AbstractColumnWidthStyleStrategy { private Map> CACHE = new HashMap<>(); @Override protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List cellDataList, Cell cell, Head head, Integer integer, Boolean isHead) { boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList); if (needSetWidth) { Map maxColumnWidthMap = CACHE.get(writeSheetHolder.getSheetNo()); if (maxColumnWidthMap == null) { maxColumnWidthMap = new HashMap<>(); CACHE.put(writeSheetHolder.getSheetNo(), maxColumnWidthMap); } Integer columnWidth = this.dataLength(cellDataList, cell, isHead); if (columnWidth >= 0) { if (columnWidth > 255) { columnWidth = 255; } Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex()); if (maxColumnWidth == null || columnWidth > maxColumnWidth) { maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth); writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256); } } } } private Integer dataLength(List cellDataList, Cell cell, Boolean isHead) { if (isHead) { return cell.getStringCellValue().getBytes().length; } else { CellData cellData = cellDataList.get(0); CellDataTypeEnum type = cellData.getType(); if (type == null) { return -1; } else { switch (type) { case STRING: return cellData.getStringValue().getBytes().length; case BOOLEAN: return cellData.getBooleanValue().toString().getBytes().length; case NUMBER: return cellData.getNumberValue().toString().getBytes().length; default: return -1; } } } }}
前端代码:
// 导入接口文件,一个controller的接口都配置在一个js/ts文件中import studentApi from '@/api/studentAPI'// exportExcel 绑定了下载按钮的点击事件function exportExcel() { studentApi.exportExcelUrl(className).then(res=>{ const url = window.URL.createObjectURL(new Blob([res])) let link = document.createElement('a') link.style.display = 'none' link.href = url link.setAttribute('download', '学生信息列表.xlsx') document.body.appendChild(link) link.click() URL.revokeObjectURL(link.href) // 释放URL 对象 document.body.removeChild(link) link = null })}
studentAPI.ts:
import AxiosInstance from "@/plugins/axiosInstance";const exportExcelUrl = (className:string) => { return AxiosInstance.post('/rent/export', {responseType:'arraybuffer', params: {className: className}})}export default { exportExcelUrl}
axiosInstance.ts:
import axios from 'axios'// 配置后端接口地址前缀const ConfigBaseURL = 'http://localhost:8080/' // 本地环境const Axios = axios.create({ timeout: 5000, baseURL: ConfigBaseURL, headers: { 'Content-Type': 'application/json;charset=UTF-8' }})Axios.interceptors.request.use(config => { return config}, error => { return Promise.reject(error)})Axios.interceptors.response.use(response => { var data = response.data return response.data}, error => { return Promise.reject(error)})export default Axios ;
Get方式:
实现方式和post基本一致,后端只需要修改一下接口的请求方式和response的contentType;前端就只需要提供一个链接即可。
后端代码:
@GetMapping("/export") public void export(HttpServletResponse response, @Param("className") String className) { try { // 根据班级名获取该班级的所有学生的信息 List list = StudentService.lists(className); // 为了导出的表格中有序号,在定义实体类的时候加了一个serialNo属性 for(int i = 0; i < list.size(); i++) { list.get(i).setSerialNo(i + 1); } // 设置Excel文件名 String name = "学生信息列表.xlsx"; String fileName = new String(name.getBytes("gb2312"), "ISO8859-1"); response.setContentType("application/vnd.ms-excel;chartset=utf-8"); response.setHeader("Content-Disposition","attachment;filename=" + fileName); // 这里注册的 CustomCellWriteHandler工具类是用来在excel中适应内容自动调整表格宽度的 ExcelWriter writer = EasyExcel.write(response.getOutputStream()).registerWriteHandler(new CustomCellWriteHandler()).build(); WriteSheet sheet = EasyExcel.writerSheet(0,"sheet").head(BillList.class).build(); writer.write(list,sheet); writer.finish(); } catch (Exception e) { log.info("jjj", e); } }
除了请求方式从Post改为了Get,还有一个变化之处就是:
response.setContentType("application/vnd.ms-excel;chartset=utf-8");
前端代码:
// exportExcel 绑定了下载按钮的点击事件function exportExcel() { // 本来后面的接口地址也是配置在接口文件中的,这边为了方便阅读,直接放在了此处。 var className = 2205 window.location.href = "http://localhost:8080/student/export?className=" + className}
参考:
使用VUE+SpringBoot+EasyExcel 整合导入导出demo_娜乌西卡lxm的博客-CSDN博客
通过get或post请求下载excel表格的解决办法_get请求下载excel_一键写代码的博客-CSDN博客
Vue2 导出Excel + 解决乱码问题 —— axios (下载后台传过来的流文件(excel)后乱码问题)_Shimeng_1989的博客-CSDN博客
来源地址:https://blog.csdn.net/chen1030416518/article/details/129973905
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341