前言:
首先我想描述一下我想实现的需求:需求很简单,我想在自己的项目中实现一个最简单且可用的excel导出功能,而且后续并不会有需求变更,除了导出数据不会有更复杂的操作
实现思路介绍:
- 第一种实现思路:先将数据重组成一个表格,然后将重组后的表格塞入html的body中,通过Blob转化成excel的类型然后进行下载即可。 具体实现:
/**
* @description: 一个原生导出excel的工具(针对:可用即可的需求)
* @param {string} name 文件名
* @param {array} list 列表数据 [{}]
* @param {array} column 表头数据-数据格式要求[{label: '标题', prop: 'title'}]
* @return {file} 输出一个正在下载的excel文件
*/
export const exportExcel = (name, list, column) => {
let html = setHtml(list, column)
let blob = new Blob([html], {
type: "application/vnd.ms-excel"
});
let a = document.createElement('a');
let url = window.URL.createObjectURL(blob);
a.href = url;
a.download = name + '.xls'
a.click();
a.remove();
}
/**
* @description: 拼接出表格片段
* @param {array} list 列表数据 [{}]
* @param {array} column 表头数据-数据格式要求[{label: '标题', prop: 'title'}]
* @return {html} 返回一个表格的html片段
*/
const setTable = (list, column) => {
// 表头构建
let th = ''
let col = ''
column.forEach(item => {
th += '<th style="background: yellow;color:red;">' + item.label + '</th>'
})
col = '<tr>' + th + '</tr>'
let td = ''
// 表格内容
let content = ''
list.forEach(i => {
column.forEach(j => {
td += '<td>' + i[j.prop] + '</td>'
})
content = '<tr>' + td + '</tr>'
})
let table = '<table id="my-table" border="1" style="display: none;">' + col + content + '</table>'
return table
}
/**
* @description: 拼接出html片段
* @param {array} list 列表数据 [{}]
* @param {array} column 表头数据-数据格式要求[{label: '标题', prop: 'title'}]
* @return {html} 将table塞进html之后的完整片段
*/
const setHtml = (list, column) => {
let table = setTable(list, column)
let html =
`<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
${table}
</body>
</html>`;
return html;
}
注:这样操作的前置条件是表格必须满足elementUI的表格被二次封装过,表头需要成[{label: '标题', prop: 'title'}]的形式,其中label为表头的文字,prop为当前列对应的字段名
这样做存在的问题:
如果是使用的电脑自带的office则会出现这种问题,如果是用的wps office则不会.但是点击是的话,是可以正常访问的,但内部表格显示也存在一定问题,于是需要解决这个问题
第二种实现思路是使用xlsx的插件,就这一个插件就足矣,我的直觉就告诉我这是一个处理excel格式问题的插件。处理方式更简单,先拼接处完整的table格式的html片段,然后将其数据通过插件导出到excel即可。(详情可搜索npm,点开网站后再搜索这个插件)
- 安装
// (如果没用cnpm,请使用你安装的工具)
cnpm install xlsx
- 引入
var XLSX = require("xlsx");
- 具体实现:
/**
* @description: 采用xlsx实现导出(针对:可用即可的需求)
* @param {string} name 文件名
* @param {array} list 列表数据 [{}]
* @param {array} column 表头数据-数据格式要求[{label: '标题', prop: 'title'}]
* @return {file} 输出一个正在下载的excel文件
*/
export const exportExcel = (name, list, column) => {
// 获取表格html片段
var table = setTable(list, column)
// 提取数据(从表中创建一个工作簿对象)
var workbook = XLSX.utils.table_to_book(table);
// 处理数据
var ws = workbook.Sheets["Sheet1"];
// 打包和发布数据(`writeFile` 尝试写入和保存 XLSB 文件)
XLSX.writeFile(workbook, name + ".xlsx");
}
/**
* @description: 拼接出表格片段
* @param {array} list 列表数据 [{}]
* @param {array} column 表头数据-数据格式要求[{label: '标题', prop: 'title'}]
* @return {html} 返回一个表格的html片段
*/
const setTable = (list, column) => {
// 表头构建
let th = ''
let col = ''
column.forEach(item => {
th += '<th>' + item.label + '</th>'
})
col = '<tr>' + th + '</tr>'
let td = ''
// 表格内容
let content = ''
list.forEach(i => {
column.forEach(j => {
td += '<td>' + i[j.prop] + '</td>'
})
content = '<tr>' + td + '</tr>'
})
let table
table = document.createElement('table');//创建HTML标签
table.innerHTML = col + content;//文本节点追加到HTML标签中
return table
}
导出后的效果:
参考文献:
后记:
这仅仅是纯前端导入,功能做的很基础,可扩展。实际上,并不用动态去生成table的html,直接通过class获取到页面中的表格,进行导出也可以,但是如果表格第一列有复选框,则会出现空位的情况,我需要导出的表格第一列就有复选框,所以没有这样做。这只是excel导出的其中一种方式:纯前端导出,还有导出excel的文件流,以及导出excel的文件等两种方式,文件要么window.open要么用ajax进行下载即可,文件流由于我不会写这样的接口,所以暂时做不了。写的很烂的原创文章,各位大佬轻点儿喷!