项目需求:前端自定义表头并输出表格
引用xlsx.core.min.js 但会有警告:[警告⚠] `utils\xlsx.core.min.js` 文件体积超过 500KB,已跳过压缩以及 ES6 转 ES5 的处理,手机端使用过大的js库影响性能。
应用:筛选订单条件如时间范围,订单类型,然后请求后端接口获取数据,获取后自定义表头及表单内数据
<template>
<view class="body">
<view style="margin-top: 10px;">
<button @click="exportClick()">导出</button>
</view>
</view>
</template>
<script>
import * as XLSX from '@/utils/xlsx.core.min.js' //xlsxjs文件路径
export default {
data() {
return {
e_list: [],
headerName: {} //导出表头
}
},
onLoad() {
},
methods: {
//获取订单列表,不分页
async getList() {
uni.showLoading({
mask: true,
title: '加载中'
})
const params = {}
const res = await this.$u.api.获取订单列表(params)
if (res.data.code == 10000) {
this.e_list = res.data.data
// console.log('llll', this.e_list)
this.head_list = ['id']//不管导出哪个自定义表格都必须有序号
//遍历选中的表头信息加入到表格头列表中
for (var i in this.ordered_list) {
this.head_list.push(this.ordered_list[i])
}
for (var j in this.received_list) {
this.head_list.push(this.received_list[j])
}
console.log('导出表格头', this.head_list)
//数据列表
const excel_list = []
for (var i = 0; i < this.e_list.length; i++) {
//自定义序号
this.e_list[i].id = i + 1
// console.log(this.e_list[i].goods_list)
//取e_list[i]即表单数据的键值对循环,判断e_list[i]的key==key,则value = e_list[key]
const keys = Object.keys(this.e_list[i])
// const values = Object.values(this.e_list[i])
console.log('keys', keys)
//定义所有的表头信息,用户自定义选中的组成新表头对象header
const allHeaderName = {
id: '序号',
order_id: '订单号',
send_type: '订单类型',
nickname: '下单人',
create_at: '下单时间',
order_goods: '商品',
mobile: '联系电话',
pay_name: '支付状态',
status_name: '订单状态',
address: '地址'
}
const h_keys = Object.keys(allHeaderName)
// const h_values = Object.values(allHeaderName)
const excel_info = {}
//用户自定义选中的组成新表头对象header
for (var q = 0; q < this.head_list.length; q++) {
const key = this.head_list[q]
for (var p = 0; p < keys.length; p++) {
if (key == keys[p]) {
// console.log('key', key)
excel_info[key] = this.e_list[i][key]
}
if (key == h_keys[p]) {
// console.log('h_key', key)
this.headerName[key] = allHeaderName[key]
}
}
}
excel_list.push(excel_info)
console.log(excel_list)
}
uni.hideLoading()
// const header = this.head_list
const ExcelData = excel_list
this.json2Excel(ExcelData, this.head_list, this.headerName, '订单列表')
}
},
//导出数据
exportClick() {
if (this.time_range == '请选择时间' || this.order_type_id == 0 || !this.ordered_list || !this.received_list) {
uni.showToast({
icon: 'error',
title: '请完善信息'
})
} else {
this.getList()
}
},
/**
* json转化xlsx
* @param {Object} data 数据
* @param {Object} header header为数据源属性名
* @param {Object} headerName 表头文案
* @param {Object} fileName 文件名 ps:这里我写死了 可自行修改
*/
json2Excel(data, header, headerName, fileName) {
let wopts = {
bookType: 'xlsx',
bookSST: false,
type: 'binary',
}
let workBook = {
SheetNames: ['Sheet1'],
Sheets: {},
Props: {},
}
const newData = [headerName, ...data]
// 1.XLSX.utils.json_to_sheet(data)接受一个对象数组并返回一个基于对象关键字自动生成的“标题”的工作表
//默认的列顺序由使用Object.keys的字段的第一次出现确定
// 2.将数据放入对象workBook的Sheets中等待输出
//加了一句skipHeader:true,这样就会忽略原来的表头
workBook.Sheets['Sheet1'] = XLSX.utils.json_to_sheet(newData, {
header: header,
skipHeader: true
})
// 3.XLSX.write()开始编写ExceL表格
// 4.changeData()将数据处理成需要的输出的格式
// console.log(this.changeData(XLSX.write(workBook, wopts)))
let time = new Date().getTime()
const StrData = this.changeData(XLSX.write(workBook, wopts))
const fs = wx.getFileSystemManager() //获取全局唯一的文件管理器
fs.writeFile({
filePath: wx.env.USER_DATA_PATH +
`/订单列表${time}.xlsx`, // wx.env.USER_DATA_PATH 指定临时文件存入的路径,后面字符串自定义
data: StrData,
encoding: 'binary', //二进制流文件必须是 binary
success(res) {
uni.hideLoading()
wx.openDocument({
// 打开文档
filePath: wx.env.USER_DATA_PATH + `/订单列表${time}.xlsx`, //拿上面存入的文件路径
showMenu: true, // 显示右上角菜单
success: function(res) {},
fail: function() {
uni.showToast({
title: `打开失败`,
icon: 'error',
duration: 2000,
})
},
})
},
})
},
/**
* 将数据处理成需要的输出的格式
* @param {Object} s XLSX输入
*/
changeData(s) {
//如果存在ArrayBuffer对象(es6)最好采用该对象
if (typeof ArrayBuffer !== 'undefined') {
//1.创建一个字节长度为s.length的内存区域
let buf = new ArrayBuffer(s.length)
//2.创建一个指向buf的Unit8视图,开始于字节0,直到缓冲区的末尾
let view = new Uint8Array(buf)
//3.返回指定位置的字符的Unicode编码
for (let i = 0; i != s.length; ++i) {
view[i] = s.charCodeAt(i) & 0xff
}
return buf
} else {
let buf = new Array(s.length)
for (let i = 0; i != s.length; ++i) {
buf[i] = s.charCodeAt(i) & 0xff
}
return buf
}
},
}
}
</script>
测试数据e_list
const e_list = [
{
address: null,
create_at: "2022-09-28 16:25:40",
order_id: 95,
nickname: "春困",
mobile: "15076128602",
pay_name: "已付款"
pay_status: 1,
send_type: 2,
status_name: "待自提",
order_goods:['白菜一斤','西红柿一盒']
}
]