SpringBoot+easypol前后端分离实现excel导出(保姆级教程)
本篇博文目录
- 1.后端
- 2.前端(采用axios)
- 3.运行效果
1.后端
- 导入easypoi的依赖
<dependency><groupId>cn.afterturngroupId><artifactId>easypoi-baseartifactId><version>4.2.0version>dependency><dependency><groupId>cn.afterturngroupId><artifactId>easypoi-webartifactId><version>4.2.0version>dependency><dependency><groupId>cn.afterturngroupId><artifactId>easypoi-annotationartifactId><version>4.2.0version>dependency>
- ExcelUtil.java(导入导出工具类)
package com.dudu.smartagriculture.utils;import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;/*** Excel导入导出工具类* @author pangu*/
public class ExcelUtil {/*** 导出工具类* @param list* @param title* @param sheetName* @param pojoClass* @param fileName* @param isCreateHeader* @param response*/public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass,String fileName, boolean isCreateHeader, HttpServletResponse response){ExportParams exportParams = new ExportParams(title, sheetName);exportParams.setCreateHeadRows(isCreateHeader);defaultExport(list, pojoClass, fileName, response, exportParams);}/*** 导出工具类* @param list* @param title* @param sheetName* @param pojoClass* @param fileName* @param response*/public static void exportExcel(List<?> list, String title, String sheetName, Class<?> pojoClass,String fileName,HttpServletResponse response){defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));}public static void exportExcel(List<Map<String, Object>> list, String fileName, HttpServletResponse response){defaultExport(list, fileName, response);}private static void defaultExport(List<?> list, Class<?> pojoClass, String fileName,HttpServletResponse response, ExportParams exportParams) {Workbook workbook = ExcelExportUtil.exportExcel(exportParams,pojoClass,list);if (workbook != null); downLoadExcel(fileName, response, workbook);}private static void downLoadExcel(String fileName, HttpServletResponse response, Workbook workbook) {try {response.setCharacterEncoding("UTF-8");response.setHeader("content-Type", "application/vnd.ms-excel");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));workbook.write(response.getOutputStream());} catch (IOException e) {//throw new NormalException(e.getMessage());}}private static void defaultExport(List<Map<String, Object>> list, String fileName, HttpServletResponse response) {Workbook workbook = ExcelExportUtil.exportExcel(list, ExcelType.HSSF);if (workbook != null);downLoadExcel(fileName, response, workbook);}public static <T> List<T> importExcel(String filePath,Integer titleRows,Integer headerRows, Class<T> pojoClass){if (StringUtils.isBlank(filePath)){return null;}ImportParams params = new ImportParams();params.setTitleRows(titleRows);params.setHeadRows(headerRows);List<T> list = null;try {list = ExcelImportUtil.importExcel(new File(filePath), pojoClass, params);}catch (NoSuchElementException e){//throw new NormalException("模板不能为空");} catch (Exception e) {e.printStackTrace();//throw new NormalException(e.getMessage());} return list;}public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass){if (file == null){ return null;}ImportParams params = new ImportParams();params.setTitleRows(titleRows);params.setHeadRows(headerRows);List<T> list = null;try {list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);}catch (NoSuchElementException e){// throw new NormalException("excel文件不能为空");} catch (Exception e) {//throw new NormalException(e.getMessage());System.out.println(e.getMessage());}return list;}}
- 后端excel导出接口(通过get请求,/devicepolicies/exportMemberList)
@ApiOperation(value = "导出策略列表Excel")@RequestMapping(value = "/exportMemberList", method = RequestMethod.GET)public void exportMemberList(@ApiIgnore HttpServletResponse response) {try {// 设置下载弹窗的文件名和格式(文件名要包括名字和文件格式)List<RulesListDto> allList = rulesService.getAllListByKeyword(null);// 获取数据//导出操作ExcelUtil.exportExcel(allList,"智慧农业监测系统策略记录","策略管理", RulesListDto.class,"智慧农业监测系统策略记录表.xlsx",response);} catch (Exception e) {LOGGER.error(e.getMessage());}}
备注:allList 为excel的数据源;"智慧农业监测系统策略记录"为title;策略管理为sheel的名字;智慧农业监测系统策略记录表.xlsx为文件名;RulesListDto.class为数据源对应的实体映射对象。
- 之所以有/devicepolicies,是因为在该接口类上有RequestMapping

- 映射实体对象,重点放在 @Excel标签上;name为列名;width为列宽;needMerge = true是否合并单元格;format为时间格式

- 关于@Excel注解常用的几个参数解释:
/*** 购物会员* Created by macro on 2021/10/12.*/
@Data
@EqualsAndHashCode(callSuper = false)
public class Member {@Excel(name = "ID", width = 10)private Long id;@Excel(name = "用户名", width = 20, needMerge = true)private String username;private String password;@Excel(name = "昵称", width = 20, needMerge = true)private String nickname;@Excel(name = "出生日期", width = 20, format = "yyyy-MM-dd")private Date birthday;@Excel(name = "手机号", width = 20, needMerge = true, desensitizationRule = "3_4")private String phone;private String icon;@Excel(name = "性别", width = 10, replace = {"男_0", "女_1"})private Integer gender;
}
在此我们就可以看到EasyPoi的核心注解@Excel,通过在对象上添加@Excel注解,可以将对象信息直接导出到Excel中去,下面对注解中的属性做个介绍;
- name:Excel中的列名;
- width:指定列的宽度;
- needMerge:是否需要纵向合并单元格;
- format:当属性为时间类型时,设置时间的导出导出格式;
- desensitizationRule:数据脱敏处理,3_4表示只显示字符串的前3位和后4位,其他为*号;
- replace:对属性进行替换;
- suffix:对数据添加后缀。
备注:来源于https://cloud.tencent.com/developer/article/1895554
2.前端(采用axios)
- 在request.js 工具类中(请求封装类)
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '../store'
import { getToken } from '@/utils/auth'// 创建axios实例
const service = axios.create({// baseURL: process.env.BASE_API, // api的base_urlbaseURL:'/api',timeout: 15000 // 请求超时时间
})// request拦截器
service.interceptors.request.use(config => {if (store.getters.token) {config.headers['Authorization'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改}return config
}, error => {// Do something with request errorconsole.log(error) // for debugPromise.reject(error)
})// respone拦截器
service.interceptors.response.use(response => {/*** code为非200是抛错 可结合自己业务进行修改*/const res = response.dataconsole.log(res);console.log(response);if(res.type === "application/vnd.ms-excel" && response.status === 200){// 说明是excelreturn response;}if (res.code !== 200) {Message({message: res.message,type: 'error',duration: 3 * 1000})// 401:未登录;if (res.code === 401) {MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {confirmButtonText: '重新登录',cancelButtonText: '取消',type: 'warning'}).then(() => {store.dispatch('FedLogOut').then(() => {location.reload()// 为了重新实例化vue-router对象 避免bug})})}return Promise.reject('error')} else {return response.data}},error => {console.log('err' + error)// for debugMessage({message: error.message,type: 'error',duration: 3 * 1000})return Promise.reject(error)}
)export default service
- 重点代码在这里:
if(res.type === "application/vnd.ms-excel" && response.status === 200){// 说明是excelreturn response;}
之所以做该判断是因为后端接口没有像其他接口那样返回统一结果对象(接口返回结果封装对象)

为什么是res.type和response.status来决定是否为导出excel接口

- 在api中编写再一次封装的请求函数


导出excel的request函数
export function exportMemberList(){return request({url: '/devicepolicies/exportMemberList',method: 'get',responseType: 'blob',header: {headers: {'Content-Type': 'application/x-download'}},})
}
组件代码中导入api

给导出按钮绑定点击事件

在methods中加入事件函数
, /** 导出按钮操作 */handleExport() {exportMemberList().then((response) => {this.downloadFile(response, "智慧农业监测系统策略记录表.xlsx");this.$message({showClose: true,message: "导出成功",type: "success",});})},// 下载文件downloadFile(res, fileName) {const content = res.data;const blob = new Blob([content]);if ("download" in document.createElement("a")) {// 非IE下载const elink = document.createElement("a");elink.download = fileName;elink.style.display = "none";elink.href = URL.createObjectURL(blob);document.body.appendChild(elink);elink.click();URL.revokeObjectURL(elink.href); // 释放URL 对象document.body.removeChild(elink);} else {// IE10+下载navigator.msSaveBlob(blob, fileName);}},
3.运行效果
- 用户点击导出

- 打开下载的excel文件

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
