安装和配置
EXCEL的安装
npm i xlsx
npm i xlsx-style
在项目中使用的版本分别是
"xlsx": "^0.18.5",
"xlsx-style": "^0.8.13"
EXCEL的使用
为了方便使用,我们封装了一个工具类,方便使用
创建工具文件
在utils文件夹下新建一个excel.js文件
import * as XLSX from 'xlsx'
import XLSXStyle from 'xlsx-style'
export function createWs(data, fields, titles) {
const ws = XLSX.utils.json_to_sheet(data, {
header: fields
})
// 根据表头字段设置列宽
const wsWidth = []
// 全部默认宽度
for (let i = 0; i < fields.length; i++) {
wsWidth.push({
wpx: 20
})
}
// 设置表格的宽度
ws['!cols'] = wsWidth
const range = XLSX.utils.decode_range(ws['!ref'])
// 设置表格样式
for (let i = range.s.c; i < range.e.c + 1; i++) {
for (let j = range.s.r; j < range.e.r + 1; j++) {
// 单元格的地址, c是列,r是行, 如A1的地址是{c:0, r:0}
const cell_address = {
c: i,
r: j
}
const column = XLSX.utils.encode_cell(cell_address)
// 获取该单元格的值
const value = ws[column].v
ws[column].s = {
// 单元格字体样式
font: {
name: '宋体',
sz: 11,
},
// 单元格的边框线
border: {
color: {
auto: 1
},
top: {
style: 'thin'
},
bottom: {
style: 'thin'
},
left: {
style: 'thin'
},
right: {
style: 'thin'
}
},
// 单元格内容的排列方式
alignment: {
// 自动换行
wrapText: 1,
// 居中
horizontal: 'center',
vertical: 'center',
indent: 0
}
}
}
}
// 设置中文标题 因为后台返回的数据中属性只能以英文返回 所以需要转化为中文
for (let c = range.s.c; c <= range.e.c; c++) {
const header = XLSX.utils.encode_col(c) + '1'
ws[header].v = titles[ws[header].v]
}
return ws
}
// 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
export function sheet2blob(sheet, sheetName) {
sheetName = sheetName || 'sheet1'
const workbook = {
SheetNames: [sheetName],
Sheets: {}
}
workbook.Sheets[sheetName] = sheet // 生成excel的配置项
// 下载这里一定要用 xlsx-style 的write() 方法才可以使导出excel表格带样式
const wbout = XLSXStyle.write(workbook, {type: 'buffer'})
// 字符串转ArrayBuffer
return new Blob([wbout], {
type: 'application/octet-stream'
})
}
export function openDownloadDialog(url, saveName) {
if (typeof url === 'object' && url instanceof Blob) {
url = URL.createObjectURL(url) // 创建blob地址
}
const aLink = document.createElement('a')
aLink.href = url
aLink.download = saveName || '' // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
let event
if (window.MouseEvent) event = new MouseEvent('click')
else {
event = document.createEvent('MouseEvents')
event.initMouseEvent(
'click',
true,
false,
window,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null
)
}
aLink.dispatchEvent(event)
}
在项目中使用
// 引入Excel导出工具
import {createWs, openDownloadDialog, sheet2blob} from '@/utils/excel'
其中createWs方法是用来创建一个sheet表格,接收三个参数,第一个参数是数据,第二个参数是表头字段,第三个参数是表头中文名,示例代码如下
假设我们有一个数据,该数据是一个数组,数组中的每一项是一个对象,对象中的属性是表头字段,属性值是表头中文名
// 整理成表格数据
const data = this.scoreData.map((item, index) => {
return {
index: index + 1,
name: item.name,
chinese: item.chinese || 0,
mathematics: item.mathematics || 0,
english: item.english || 0,
physics: item.physics || 0,
chemistry: item.chemistry || 0,
biology: item.biology || 0,
politics: item.politics || 0,
history: item.history || 0,
geography: item.geography || 0,
total: item.total || 0,
average: item.average || 0
}
})
其中,数据对应的表头字段如下
const fields = [
'index',
'name',
'chinese',
'mathematics',
'english',
'physics',
'chemistry',
'biology',
'politics',
'history',
'geography',
'total',
'average'
]
表头中文名如下
const titles = {
index: '序号',
name: '姓名',
chinese: '语文',
mathematics: '数学',
english: '英语',
physics: '物理',
chemistry: '化学',
biology: '生物',
politics: '政治',
history: '历史',
geography: '地理',
total: '总分',
average: '平均分'
}
最后,我们调用createWs方法,将数据,表头字段,表头中文名传入,得到一个sheet表格,然后调用sheet2blob方法,将sheet表格转成blob对象,最后调用openDownloadDialog方法,将blob对象传入,即可实现导出excel表格的功能
const ws = createWs(data, fields, title)
openDownloadDialog(sheet2blob(ws), '某班-成绩表.xlsx')
进阶使用
- 在excel.js中,可以设置表头的宽度,如:
// 设置表头的宽度
// 成绩 设置列宽
fields.forEach((item) => {
if (item === 'index') {
wsWidth.push({wpx: 65})
} else if (item === 'name') {
wsWidth.push({wpx: 100})
} else {
wsWidth.push({wpx: 65})
}
})
这样的话成绩的序号(index)列宽度为65px,姓名(name)列宽度为100px,其他列宽度为65px 效果如下: 2. 也可以设置单元格字体的样式,如:
// 单元格字体样式
font: {
name: '宋体',
// 字体大小
sz: 11,
// 字体颜色
color: {
rgb: value === '红码' || value === '阳性!' ? 'FF0000' : value === '绿码' || value === '阴性' || value === '已采样' ? '008000' : value === '黄码' ? 'FFA500' : '000000'
},
// 健康码 行程码 检测结果 字体加粗
bold: value === '红码' || value === '绿码' || value === '黄码' || value === '阴性' || value === '阳性!' || value === '已采样' || value === '检测结果'
}
这样的话,在前面的表头宽度设置对应数值之后,健康码、行程码、检测结果这三列的字体颜色就会根据值的不同而不同,效果如下: