这篇文章主要为大家详细介绍了Vue导出excel的两个常用方式,分别为前端vue+XLSX导出excel和vue+后端POI 导出excel,感兴趣的小伙伴可以了解下
目录
一、需求分析1. 两个方式2. 对比分析二、方式1:vue+XLSX1. 安装 XLSX2. XLSX 两个方法比较3. XLSX 方法一4. XLSX 方法二二、方式2:vue+POI1. 前端代码2. 后端代码(IMPORTANT)一、需求分析
1. 两个方式
导出excel有两个方式,前端导出 和 后端导出
前端导出excel:就用 vue+XLSX(npm 包)
后端导出excel:就用 vue+POI(maven 包)
2. 对比分析
前端导出excel 相对来说简单一点,XLSX是前端 npm 包,但是如果数据量大的话,会卡顿,处理时间慢;当数据量多的时候 使用后端导出会好一点
后端导出excel 相对来说麻烦一点,但是时间短、速度快;具体操作都放在后端,也节省了前端的操作。用户效果好。
二、方式1:vue+XLSX
1. 安装 XLSX
npm install xlsx file-saver --save
2. XLSX 两个方法比较
这个XLSX 方法一 和下面的XLSX 方法二 都是使用的 XLSX 模块的 方法,只是获取数据的方式和 导出excel的方式有点不一样。
相比之下,还是 XLSX 方法一 会好一点,可以自定义导出的字段。
3. XLSX 方法一
a. 按钮事件
<el-button size="small" type="primary" @click="exportSelect()">导出选中</el-button><el-button size="small" type="primary" @click="exportAllExcel">导出全部</el-button>
其实 上面的 二方法 可以做成一个方法,但是为了明确好分析,我写成了二个方法。
b. js 方法:导出选中 exportSelect()
exportSelect() { // 导出选中 this.$confirm("是否确认导出当前所有参赛人员数据?", "警告", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }).then((response) => { // this.selectdata 是复选框的 数据列表 if (this.selectdata.length <= 0) { this.$message.info('请选择数据!'); return false; } let tableData = [ ['序号', '赛区名称', '参赛人', '手机号', '收件地址', "邮箱", "录入时间", "状态"]//导出表头 ] // 表格表头 this.selectdata.forEach((item, index) => { let rowData = [] //导出内容的字段 rowData = [ index + 1, item.matchAreaName, item.userName, item.userPhone, item.receiveAddress, item.createTime, item.dataFlag === 0 ? '待审核': '审核通过', ] tableData.push(rowData) }) let workSheet = XLSX.utils.aoa_to_sheet(tableData); let bookNew = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(bookNew, workSheet, '作品名称') // 工作簿名称 let name = '参赛人员选中' + this.timeFormat() + '.xlsx' XLSX.writeFile(bookNew, name) // 保存的文件名 }) }, timeFormat() { let time = new Date(); let year = time.getFullYear(); let month = time.getMonth() + 1; let date = time.getDate(); let hours = time.getHours(); let minutes = time.getMinutes(); let seconds = time.getSeconds(); return year + '-' + this.addZero(month) + '-' + this.addZero(date) + ' ' + this.addZero(hours) + ':' + this.addZero(minutes) + ':' + this.addZero(seconds); }, addZero(num) { return num < 10 ? '0' + num : num },
c. js 方法:导出全部 exportAllExcel
// 导出 所有 exportAllExcel() { this.$confirm("是否确认导出全部参赛人员数据?", "警告", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }).then(response => { // 获取用户列表 let arr = []; let parameter = { pageNo: 1, pageSize: 1000 } getMatchUserInfoList(parameter).then(res => { this.loading = false; if (res.data.code != "1") { this.$message({ type: 'info', message: res.data.message }) } else { arr = res.data.data; console.log('----------:', JSON.stringify(arr)) this.exportList(arr); } }).catch(err => { this.$message.warning("系统问题,请稍后重试!") }) }, exportList(arr){ let tableData = [ ['序号', '赛区名称', '参赛人', '手机号', '收件地址', "邮箱", "录入时间", "审核状态", "是否发送豆子"]//导出表头 ] // 表格表头 arr.forEach((item, index) => { let rowData = [] //导出内容的字段 rowData = [ index + 1, item.matchAreaName, item.userName, item.userPhone, item.receiveAddress, item.email, item.createTime, item.dataFlag === 0 ? '待审核': '审核通过', item.sendFlag === 1 ? '否': '是', ] tableData.push(rowData) }) let workSheet = XLSX.utils.aoa_to_sheet(tableData); let bookNew = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(bookNew, workSheet, '作品名称') // 工作簿名称 let name = '全部参赛人员' + this.timeFormat() + '.xlsx' XLSX.writeFile(bookNew, name) // 保存的文件名 },
4. XLSX 方法二
a. 按钮事件
<el-button size="small" type="primary" @click="exportExcel">导出当前页</el-button>
b. js 方法:导出当前页 exportExcel
这里是
// 导出当前页 exportExcel() { this.$confirm("是否确认导出当前所有参赛人员数据?", "警告", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }).then((response) => { const wb = XLSX.utils.table_to_book( document.querySelector("#el-table") ); const wbout = XLSX.write(wb, { bookType: "xlsx", bookSST: true, type: "array", }); try { FileSaver.saveAs( new Blob([wbout], {type: "application/octet-stream"}), "参赛人员数据.xlsx" ); } catch (e) { if (typeof console !== "undefined") console.log(e, wbout); } }); },
二、方式2:vue+POI
这个方式也就是后端生成excel,与前端没有多大的关系,后端写好的 excel就直接write到 response里面了。
先直接放上前端代码。
1. 前端代码
a、按钮事件
<el-button size="small" type="primary" @click="exportAllExcel">导出全部</el-button>
b、网络请求封装
// 导出全部export function exportExcelForMatchUser(data) { return fetch({ url: '/xfx/matchUser/web/exportExcelForMatchUser', method: 'post', timeout: '120000', responseType: 'blob', data });}
c、js方法:导出全部 exportAllExcel
// 导出 所有 exportAllExcel() { this.$confirm("是否确认导出全部参赛人员数据?", "警告", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }).then(response => { exportExcelForMatchUser().then(response => { const data = "参赛人员web.xlsx"; console.log('1111111111111111111111111', JSON.stringify(response)) let blob = new Blob([response.data], {type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document;charset=utf-8"}); console.log('333333333333333333333333', JSON.stringify(blob)) // for IE if (window.navigator && window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, data); } else { console.log('chrome go here ') let downloadElement = document.createElement('a'); let href = window.URL.createObjectURL(blob); // 创建下载的链接 downloadElement.href = href; downloadElement.download = data; // 下载后文件名 document.body.appendChild(downloadElement); downloadElement.click(); // 点击下载 document.body.removeChild(downloadElement); // 下载完成移除元素 window.URL.revokeObjectURL(href); // 释放掉blob对象 } }).catch(err => { console.log(err) this.loading = false; this.$message.warning("对不起,下载失败"); }); }) },
2. 后端代码(IMPORTANT)
a、maven 依赖
<!-- poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-scratchpad --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>3.14</version> </dependency> <!--这个不属于 poi ,就是一个工具类--> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.3.2</version> </dependency>
a、controller 控制器层
/** * @return com.zheng.ucenter.common.constant.UcenterResult * @Author fengfanli * @Description //TODO 导出全部 * @Date 17:40 2021/5/17 * @Param [param, request] **/ @RequestMapping(value = "/web/exportExcelForMatchUser", method = RequestMethod.POST) public UcenterResult exportExcelForMatchUser(HttpServletResponse response) { try { MatchUserModel model = new MatchUserModel(); model.setStart(0); model.setPageSize(10000); List<MatchUserModel> allMatchUserModels = matchUserService.getAllMatchUserModels(model); // 导出 代码 List<MatchUserResp> result = new ArrayList<>(allMatchUserModels.size()); for (MatchUserModel matchUserModel : allMatchUserModels) { MatchUserResp resp = new MatchUserResp(); BeanUtils.copyProperties(matchUserModel, resp); resp.setCreateTime(DateHander.dateToStr1(matchUserModel.getCreateTime())); result.add(resp); } if (result.size()!=0){ ExportExcel exportExcel = new ExportExcel("参赛人员", MatchUserResp.class, 1); exportExcel.setDataList(result); String fileName = "MATCH_USER_" + DateHander.dateToStrD(new Date()) + (new Random().nextInt(100 - 10) + 10) + ".xlsx"; exportExcel.write(response, fileName); } return new UcenterResult(UcenterResultConstant.SUCCESS); } catch (Exception e) { logger.error("MatchUserController exportExcelForMatchUser error:", e); } return new UcenterResult(UcenterResultConstant.FAILED); }
重点就是其中的五行:
b、POJO类MatchUserResp类
这里使用到了自定义的 注解类
import java.io.Serializable;import java.util.Date;/** * @ClassName MatchUserResp * @Description TODO * @Author admin * @Date 2021/5/14 15:36 * @Version 1.0 */public class MatchUserResp implements Serializable { @ExcelField(title = "序号", align = 1, sort = 1) private Integer id; private Long matchMainId; private Long userId; @ExcelField(title = "是否发送豆子(2:发送,1:未发送)", align = 1, sort = 2) private Long sendFlag; @ExcelField(title = "比赛名称", align = 1, sort = 3) private String matchName; @ExcelField(title = "用户名", align = 1, sort = 4) private String userName; @ExcelField(title = "手机号", align = 1, sort = 5) private String userPhone; private String userWxHead; @ExcelField(title = "收件地址", align = 1, sort = 6) private String receiveAddress; @ExcelField(title = "邮箱", align = 1, sort = 7) private String email; private Long matchAreaCodeId; @ExcelField(title = "赛区名称", align = 1, sort = 8) private String matchAreaName; @ExcelField(title = "备注", align = 1, sort = 9) private String remark; private Integer createUserId; private String createUserName; @ExcelField(title = "创建时间", align = 1, sort = 10) private String createTime; private Integer dataFlag; private Integer useFlag; private String timeStamp; public Long getSendFlag() { return sendFlag; } public void setSendFlag(Long sendFlag) { this.sendFlag = sendFlag; } public Long getUserId() { return userId; } public void setUserId(Long userId) { this.userId = userId; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Long getMatchMainId() { return matchMainId; } public void setMatchMainId(Long matchMainId) { this.matchMainId = matchMainId; } public String getMatchName() { return matchName; } public void setMatchName(String matchName) { this.matchName = matchName; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPhone() { return userPhone; } public void setUserPhone(String userPhone) { this.userPhone = userPhone; } public String getUserWxHead() { return userWxHead; } public void setUserWxHead(String userWxHead) { this.userWxHead = userWxHead; } public String getReceiveAddress() { return receiveAddress; } public void setReceiveAddress(String receiveAddress) { this.receiveAddress = receiveAddress; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Long getMatchAreaCodeId() { return matchAreaCodeId; } public void setMatchAreaCodeId(Long matchAreaCodeId) { this.matchAreaCodeId = matchAreaCodeId; } public String getMatchAreaName() { return matchAreaName; } public void setMatchAreaName(String matchAreaName) { this.matchAreaName = matchAreaName; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public Integer getCreateUserId() { return createUserId; } public void setCreateUserId(Integer createUserId) { this.createUserId = createUserId; } public String getCreateUserName() { return createUserName; } public void setCreateUserName(String createUserName) { this.createUserName = createUserName; } public String getCreateTime() { return createTime; } public void setCreateTime(String createTime) { this.createTime = createTime; } public Integer getDataFlag() { return dataFlag; } public void setDataFlag(Integer dataFlag) { this.dataFlag = dataFlag; } public Integer getUseFlag() { return useFlag; } public void setUseFlag(Integer useFlag) { this.useFlag = useFlag; } public String getTimeStamp() { return timeStamp; } public void setTimeStamp(String timeStamp) { this.timeStamp = timeStamp; }}
c、其余的工具类
我都上传至GitHub了,可以直接拿过来用。
总结