在前端开发中,处理 Excel 文件是特别常见的任务,尤其是在一些后台管理业务中会经常涉及到数据的导入和导出等。本文将介绍如何使用 xlsx 和 file-saver 这两个库来实现前端的 Excel 数据导入与导出。xlsx 允许我们读取和创建 Excel 文件,而 file-saver 使得将文件保存到本地变得简单。
1.使用xlsx和file-saver完成导出excel功能
// 导入第三方包
import xlsx from 'xlsx'
import fs from 'file-saver'
xlsx(json, fields, filename = '.xlsx') {
// 遍历json数据,并根据fields映射修改字段名
json.forEach(item => {
for (const i in item) {
if (fields.hasOwnProperty(i)) {
item[fields[i]] = item[i]; // 将旧字段名的值赋给新字段名
}
delete item[i]; // 删除旧字段名
}
});
const sheetName = filename; // 设置Excel文件的名称
const wb = xlsx.utils.book_new(); // 创建一个新的工作簿对象
const ws = xlsx.utils.json_to_sheet(json, { header: Object.values(fields) }); // 将处理后的JSON数据转换为工作表
wb.SheetNames.push(sheetName); // 将工作表名称添加到工作簿的SheetNames数组
wb.Sheets[sheetName] = ws; // 将工作表添加到工作簿
// 设置默认单元格样式
const defaultCellStyle = {
font: { name: 'Verdana', sz: 13, color: 'FF00FF88' },
fill: { fgColor: { rgb: 'FFFFAA00' }}
};
// 写入选项,包括样式配置
const wopts = {
bookType: 'xlsx',
bookSST: false,
type: 'binary',
cellStyles: true,
defaultCellStyle: defaultCellStyle,
showGridLines: false
};
// 生成Excel文件的二进制数据
const wbout = xlsx.write(wb, wopts);
// 将二进制数据转换为Blob对象
const blob = new Blob([this.s2ab(wbout)], { type: 'application/octet-stream' });
// 使用file-saver库保存文件
fs.saveAs(blob, filename + '.xlsx');
},
s2ab(s) {
let buf;
if (typeof ArrayBuffer !== 'undefined') {
// 如果支持ArrayBuffer,将字符串转换为ArrayBuffer
buf = new ArrayBuffer(s.length);
const view = new Uint8Array(buf);
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
return buf;
} else {
// 如果不支持ArrayBuffer,使用数组
buf = new Array(s.length);
for (let i = 0; i !== s.length; ++i) buf[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
}
2.在点击事件中触发导出事件
<button @click="ImportData">导出</button>
switchExportData (data) {
const exportData = JSON.parse(JSON.stringify(data))
// 这里可以对数据进行一次加工,转换为用户需要的最终形式
return exportData
},
ExportData (data = []) {
const columns={name:'姓名',age:'年龄',sex:'性别'} // json 数据 的 key => value 对应关系
const exportData = this.switchExportData(data) // 处理数据
this.xlsx(exportData, columns, 'excel表名' )
},
3.导入功能
/* 读取文件 将文件转换为二进制 */
readFile (file) {
return new Promise(resolve => {
const reader = new FileReader()
reader.readAsBinaryString(file)
reader.onload = ev => {
resolve(ev.target.result)
}
})
},
addHoursToDate(dateStr, hoursToAdd) {
// 解析日期字符串为 Date 对象
const date = new Date(dateStr);
// 添加小时
date.setHours(date.getHours() + hoursToAdd);
// 格式化为 'YYYY-MM-DD' 格式
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,+1
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
},
switchObj (data, originalObj) {
data.forEach(item => {
const obj = {}
for (const key in originalObj) {
// 对日期格式的数据做兼容处理
if (item[originalObj[key]] instanceof Date) {
obj[key] = this.addHoursToDate(item[originalObj[key]]),8) || '' // 加八小时是为了校准时差
} else {
obj[key] = String(item[originalObj[key]] || '') // 将其他比如数字类型的数据统一转换成字符串类型
}
}
result.push(obj)
})
return result
},
handleUploadChange (file) {
const dataBinary = await this.readFile(file.target.files[0]) // file.target.files[0]即为文件对象
file.target.value = null // 注意上传后要将input的值设为空
const workBook = xlsx.read(dataBinary, { type: 'binary', cellDates: true })
const workSheet = workBook.Sheets[workBook.SheetNames[0]]
const data = xlsx.utils.sheet_to_json(workSheet) // 拿到的数据原始值,key值为中文
const columns={name:'姓名',age:'年龄',sex:'性别'} // json 数据 的 key => value 对应关系
let importData = this.switchObj(data, columns) // 将key和value转换为接口所需要的形式
4.button和input触发上传事件
<button @click="ImportData">导入</button>
<input ref="file" type="file" name="file" accept=".xlsx,.xls" @change="handleUploadChange">
Importdata () {
this.$refs.file.click()
}






