使用export2excel导出数据,以及多级表头
最近公司做项目,需要导出数据到excel表格
使用到了 element ui ,export2excel
特此记录,毕竟好记性不如烂笔头
不包含修改样式(菜鸟一枚,希望大佬指教点名)
1.安装依赖,三个依赖包
npm install -s file-saver npm install -s xlsx npm install -d script-loader
2.创建文件
在项目src 下创建 vendor 文件夹
然后创建 export2excel.js 文件
- export2excel.js 文件内容
/* eslint-disable */ import { saveas } from 'file-saver' import xlsx from 'xlsx' function generatearray(table) { var out = []; var rows = table.queryselectorall('tr'); var ranges = []; for (var r = 0; r < rows.length; ++r) { var outrow = []; var row = rows[r]; var columns = row.queryselectorall('td'); for (var c = 0; c < columns.length; ++c) { var cell = columns[c]; var colspan = cell.getattribute('colspan'); var rowspan = cell.getattribute('rowspan'); var cellvalue = cell.innertext; if (cellvalue !== "" && cellvalue == +cellvalue) cellvalue = +cellvalue; //skip ranges ranges.foreach(function (range) { if (r >= range.s.r && r <= range.e.r && outrow.length >= range.s.c && outrow.length <= range.e.c) { for (var i = 0; i <= range.e.c - range.s.c; ++i) outrow.push(null); } }); //handle row span if (rowspan || colspan) { rowspan = rowspan || 1; colspan = colspan || 1; ranges.push({ s: { r: r, c: outrow.length }, e: { r: r + rowspan - 1, c: outrow.length + colspan - 1 } }); }; //handle value outrow.push(cellvalue !== "" ? cellvalue : null); //handle colspan if (colspan) for (var k = 0; k < colspan - 1; ++k) outrow.push(null); } out.push(outrow); } return [out, ranges]; }; function datenum(v, date1904) { if (date1904) v += 1462; var epoch = date.parse(v); return (epoch - new date(date.utc(1899, 11, 30))) / (24 * 60 * 60 * 1000); } function sheet_from_array_of_arrays(data, opts) { var ws = {}; var range = { s: { c: 10000000, r: 10000000 }, e: { c: 0, r: 0 } }; for (var r = 0; r != data.length; ++r) { for (var c = 0; c != data[r].length; ++c) { if (range.s.r > r) range.s.r = r; if (range.s.c > c) range.s.c = c; if (range.e.r < r) range.e.r = r; if (range.e.c < c) range.e.c = c; var cell = { v: data[r][c] }; if (cell.v == null) continue; var cell_ref = xlsx.utils.encode_cell({ c: c, r: r }); if (typeof cell.v === 'number') cell.t = 'n'; else if (typeof cell.v === 'boolean') cell.t = 'b'; else if (cell.v instanceof date) { cell.t = 'n'; cell.z = xlsx.ssf._table[14]; cell.v = datenum(cell.v); } else cell.t = 's'; ws[cell_ref] = cell; } } if (range.s.c < 10000000) ws['!ref'] = xlsx.utils.encode_range(range); return ws; } function workbook() { if (!(this instanceof workbook)) return new workbook(); this.sheetnames = []; this.sheets = {}; } function s2ab(s) { var buf = new arraybuffer(s.length); var view = new uint8array(buf); for (var i = 0; i != s.length; ++i) view[i] = s.charcodeat(i) & 0xff; return buf; } export function export_table_to_excel(id) { var thetable = document.getelementbyid(id); var oo = generatearray(thetable); var ranges = oo[1]; /* original data */ var data = oo[0]; var ws_name = "sheetjs"; var wb = new workbook(), ws = sheet_from_array_of_arrays(data); /* add ranges to worksheet */ // ws['!cols'] = ['apple', 'banan']; ws['!merges'] = ranges; /* add worksheet to workbook */ wb.sheetnames.push(ws_name); wb.sheets[ws_name] = ws; var wbout = xlsx.write(wb, { booktype: 'xlsx', booksst: false, type: 'binary' }); saveas(new blob([s2ab(wbout)], { type: "application/octet-stream" }), "test.xlsx") } export function export_json_to_excel({ multiheader = [], header, data, filename, merges = [], autowidth = true, booktype = 'xlsx', } = {}) { /* original data */ filename = filename || 'excel-list' data = [...data] data.unshift(header); for (let i = multiheader.length - 1; i > -1; i--) { data.unshift(multiheader[i]) } var ws_name = "sheetjs"; var wb = new workbook(), ws = sheet_from_array_of_arrays(data); if (merges.length > 0) { if (!ws['!merges']) ws['!merges'] = []; merges.foreach(item => { ws['!merges'].push(xlsx.utils.decode_range(item)) }) } if (autowidth) { /*设置worksheet每列的最大宽度*/ const colwidth = data.map(row => row.map(val => { /*先判断是否为null/undefined*/ if (val == null) { return { 'wch': 10 }; } /*再判断是否为中文*/ else if (val.tostring().charcodeat(0) > 255) { return { 'wch': val.tostring().length * 2 }; } else { return { 'wch': val.tostring().length }; } })) /*以第一行为初始值*/ let result = colwidth[0]; for (let i = 1; i < colwidth.length; i++) { for (let j = 0; j < colwidth[i].length; j++) { if (result[j]['wch'] < colwidth[i][j]['wch']) { result[j]['wch'] = colwidth[i][j]['wch']; } } } ws['!cols'] = result; } /* add worksheet to workbook */ wb.sheetnames.push(ws_name); wb.sheets[ws_name] = ws; /** * 自定义 */ var datainfo = wb.sheets[wb.sheetnames[0]]; let arr = [ "a1", "b1", "c1", "d1", "e1", "f1", "g1", "h1", "i1", "j1", "k1", "l1", "m1", "n1", "o1", "p1", "q1", "r1", "s1", "t1", "u1", "v1", "w1", "x1", "y1", "z1" ]; let style = { font: { color: { rgb: "000000" }, bold: true }, alignment: { horizontal: "center", vertical: "center" } }; for (var i = 0; i < header.length; i++) { datainfo[arr[i]].s = style; } var wbout = xlsx.write(wb, { booktype: booktype, booksst: false, type: 'binary' }); saveas(new blob([s2ab(wbout)], { type: "application/octet-stream" }), `${filename}.${booktype}`); }
补充:
所用到的数据格式
tabledata: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1517 弄' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1519 弄' }, { date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1516 弄' }]
3.使用方法(一级表头)
导出单级表头
- html部分:
<el-button @click="handledownload" class="addbutton-class">批量导出</el-button>
- js部分:
// 导出数据 handledownload() { import('@/vendor/export2excel').then(excel => { // 表头数据 const header = ['日期', '条形码', '所属区域', '所属部门', '商场名称', '兑奖员工'] // 数据来源中,代替表头的变量 const filterval = ['create_time', 'bar_code', 'aname', 'dname', 'warehouse_name', 'sell_name'] // 数据来源 const list = this.tabledata // 拼接数据 const data = this.formatjson(filterval, list) excel.export_json_to_excel({ header, data, // 导出表格的文件名字 filename:'销售产品清单', }) }) }, // 拼接数据 formatjson(filterval, jsondata) { return jsondata.map(v => filterval.map(j => { return v[j] })) },
示例效果
4.多级表头
导出多级表头
导出多级表头首先要理解,单元格合并
- 日期 所占 单元格为 a1:a3
- 配送信息 所占 单元格为 b1:f1
- 姓名 所占 单元格为 b2:b3
依次类推
理解这一点,下面代码就好理解了
- html部分:
<el-button @click="handledownload" class="addbutton-class">批量导出</el-button>
// 导出单个表头 handledownload() { import('@/vendor/export2excel').then(excel => { const multiheader = [ ['对账清单','', '', '', '', '','', '', '', '', ''],// 业务需求可删除 ['结算单位:',this.name, '', '', '', '','', '结算日期:', this.brgintime, '至', this.endtime], // 业务需求可删除 ['日期', '上期结存', '', '本期进货', '', '本期退货','', '本期销售', '', '本期库存', ''], ] // 前两行的表头数据,二维数组,不够的用空白补全 const header = ['', '数量', '金额', '数量', '金额', '数量', '金额', '数量', '金额', '数量', '金额'] // 最后一行的表头数据 const filterval= ['goods_brand', 'cq_count', 'cq_total', 'bqrk_count', 'bqrk_total', 'bqck_count','bqck_total','bqxs_count','bqxs_total','bqkc_count','bqkc_total'] // 这里要注意 header 和 filterval 的数组长度一定要相等,否则会报错 const list = this.tabledata const data = this.formatjson(filterval, list) const merges = ['a1:k1','a3:a4','b3:c3','d3:e3','f3:g3','h3:i3','j3:k3'] // 合并单元格的数据,如何合并参考上面图片讲解 excel.export_json_to_excel({ multiheader, header, merges, data, filename:'对账清单', }) }) }, // 拼接数据 formatjson(filterval, jsondata) { return jsondata.map(v => filterval.map(j => { return v[j] })) },
大致就是这样,就是没有居中效果(菜鸟,勿喷)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论