Project scenario:
I recently took over a project, and one of the requirements was to export the data in the queried table into an Excel file and download it locally.
The question is, shouldn’t it be better to implement this kind of thing on the backend? If you do it on the front end, you need to get all the data, then parse the data, and then perform a series of operations to convert it into an Excel file. If the amount of data is small, it is fine. If the amount of data is huge, give me the entire tens of thousands of items. , wouldn’t the browser be stuck? ? (Of course, this is just my personal opinion as a newbie. If any passing master has good suggestions or experience, please enlighten me~~)
When I reported these risks to the SB manager, people thought I was lazy and didn’t want to do it. Give various reasons to refute me. . .
Okay, I’ll do whatever you say! There is no way, people under the eaves have to bow their heads.
-------------------------------------------------- --Bullshit dividing line------------------------------------------------ ----------------
Back to the subject, when I checked some information, I found that the implementation is actually quite simple. The old rules, no more nonsense, just go straight to the code!
solution:
1. Package installation: npm install xlsx file-saver --save
2. Introduction: import XLSX from 'xlsx'
3. Write a button in the template, and doExport is the click event to trigger the export function.
<el-button
type="primary"
size="small"
:loading="exportLoading"
icon="el-icon-document"
@click="doExport"
>导出Excel</el-button>
The interface style is as follows:
4. The methods code is as follows:
doExport() {
// 开始生成文件时,添加一个loading让它一直转,待生成excel完毕之后再关掉
this.exportLoading = true
// 关键函数
function exportToExcel(fileName, tableData) {
const worksheet = XLSX.utils.json_to_sheet(tableData)
const workbook = {
Sheets: {
data: worksheet }, SheetNames: ['data'] }
const excelBuffer = XLSX.write(workbook, {
bookType: 'xlsx', type: 'array' })
const data = new Blob([excelBuffer], {
type: 'application/octet-stream' })
FileSaver.saveAs(data, `${
fileName}.xlsx`)
}
// fileName 为生成的 Excel 文件名称,为避免重复,这里使用时间戳作为前缀
const fileName = moment().format('YYYY-MM-DD hh:mm:ss') + ' xxx信息数据'
// perPageSize 为请求数据的数量,由于需求方想要全部的数据,而前端又要分页,所以只能把这个参数设置成很大喽,如果出问题我也没办法~
const params = {
page: this.currentPage - 1,
size: 100000,
queryCondition: {
area: this.searchForm.area,
deviceType: this.searchForm.deviceType,
hospitalName: this.searchForm.deviceCustomer,
erpMaterialDescription: this.searchForm.erpMaterialDescription,
deviceSerialNumber: this.searchForm.deviceSerialNumber,
materialNumber: this.searchForm.materialNumber,
workOrderCreatedTimeStart: this.searchForm.workOrderCreatedTime,
workOrderCreatedTimeEnd: this.searchForm.workOrderCreatedTime,
workOrderClosedTimeStart: this.searchForm.workOrderClosedTime,
workOrderClosedTimeEnd: this.searchForm.workOrderClosedTime,
workOrderNumber: this.searchForm.workOrderNumber,
engineerName: this.searchForm.engineerName,
warrantyStatus: this.searchForm.warrantyStatus,
materialReplaceTimesLow: this.searchForm.materialReplaceTimesLow,
materialReplaceTimesHigh: this.searchForm.materialReplaceTimesHigh
}
}
console.log(params)
const self = this
ibMaterialApi.getIBMaterialTableData(params).then(res => {
if (res.code === 200) {
// 解析excel文件
const excelData = []
for (let i = 0; i < res.data.length; i++) {
const excelObj = {
}
excelObj.序列号 = (i + 1).toString()
excelObj.创建时间 = res.data[i].createTime === '0' ? '暂无数据' : res.data[i].createTime
excelObj.物料号 = res.data[i].materialNumber
excelObj.物料描述 = res.data[i].erpMaterialDescription
excelObj.客户名称 = res.data[i].hospitalName
excelObj.省份 = res.data[i].area
excelObj.机型 = res.data[i].deviceType
excelObj.整机序列号 = res.data[i].deviceSerialNumber
excelObj.故障时间 = res.data[i].equipmentDowntime
excelObj.故障描述 = res.data[i].diagnose
excelObj.解决方案 = res.data[i].suggestionSolution ? res.data[i].suggestionSolution : '暂无数据'
excelObj.旧件序列号 = res.data[i].oldSerialNumber ? res.data[i].oldSerialNumber : 'N.A'
excelObj.保修状态 = res.data[i].warrantyStatus
excelObj.工单号 = res.data[i].caseId
excelData.push(excelObj)
}
console.log(excelData)
exportToExcel(fileName, excelData)
self.exportLoading = false
} else {
self.exportLoading = false
}
}).catch(() => {
self.exportLoading = false
})
}
When exporting a file, the loading style is as follows:
File downloaded successfully!
OK! That's it. The code is very simple. It can be used for personal testing and cv.
If you have any better opinions, please criticize and correct me!