1、导入依赖
<!--Excel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.1</version>
</dependency>
2、后端业务
1、Controller层
@PostMapping("/exportUser")
public void exportUser(@RequestBody Long[] ids, HttpServletResponse response){
sysUserService.downLoad(ids,response);
}
2、Service层
//接口
/**
* 导出Excel
* @param ids
* @param response
*/
void downLoad(Long[] ids, HttpServletResponse response);
//实现类
@Override
public void downLoad(Long[] ids, HttpServletResponse response) {
//获取数据源
List<SysUserRoleDto> sysUserList = sysUserMapper.getSysUserList(new ReqUserDto(), 0, 0);
//对返回的数据进行处理
sysUserList.forEach(userRoleDto -> {
userRoleDto.setStatus(userRoleDto.getStatus().equals("0")?"正常":"禁用");
userRoleDto.setSex(userRoleDto.getSex().equals("0")?"男":"女");
});
//调用ExcelUtil导出
ExcelUtil.download(response,sysUserList,SysUserRoleDto.class);
}
3、实体类
@Data
public class SysUserRoleDto extends SysUser implements Serializable {
/**
* 角色ID
*/
@ExcelIgnore
private Integer roleId;
/**
* 角色名称
*/
@ExcelProperty("角色名称")
private String roleName;
/**
* 角色标识符
*/
@ExcelProperty("角色标识符")
private String roleKey;
}
4、Excel导出工具类(重要)
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;
public class ExcelUtil {
/**
* 导出excel
*
* @param response
* @return
*/
// @SneakyThrows
public static<T> void download(HttpServletResponse response, List<T> list, Class<T> clazz) {
try {
// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("统计表", "UTF-8");
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName+".xlsx");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
// System.out.println(fileName);
EasyExcel.write(response.getOutputStream(), clazz)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())//自适应表格格式
.sheet()
.doWrite(list);
}catch (Exception e){
throw new RuntimeException(e.getMessage());
}
}
}
3、Vue前端
/** 导出按钮操作 */
handleExport() {
this.$confirm(`确定要导出吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 用户点击"确定"按钮,执行删除操作
this.$http.post('user/exportUser', this.ids, {
responseType: 'blob' // 指定响应类型为二进制流
}).then(res => {
// 获取响应数据并进行处理
const url = window.URL.createObjectURL(new Blob([res.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', '用户列表.xlsx'); // 设置下载文件名
document.body.appendChild(link);
link.click();
});
}).catch(() => {
// 用户点击"取消"按钮,什么也不做
})
},
4、分享一个我在开发中遇到的一个问题,真快把我气死的节奏!!!
excel响应导出时,一直报错
Uncaught (in promise)
接口测试工具测试没有问题!
原代码是这样
最终发现是我在全局处理bigint类型数据精度丢失问题时,将所有响应类型后转为json,但是Excel导出是blob类型,所以被拦截!
改过之后
//处理响应
axios.interceptors.response.use(response=>{
console.log(response)
if (response.status !== 200) {
Vue.prototype.$message.error(response.data.msg || '请求错误')
return Promise.reject("error")
}
return Promise.resolve(response)
},error => {
return Promise.reject(error);
})
//处理后台bigint精度丢失问题
axios.defaults.transformResponse = [
function (data) {
try {//try捕获
const json = JSONBIG({
storeAsString: true
})
return json.parse(data)
}catch (e) {
return data;
}
}
]