当画面有自定义的表格或者样式过于复杂的表格时,导出功能可以由前端实现
1. 使用的插件 : sheet.js-xlsx
文档地址:https://docs.sheetjs.com/
中文地址:https://geekdaxue.co/read/SheetJS-docs-zh/README.md
xlsx-style:https://www.npmjs.com/package/xlsx-style
2. 安装引用
安装插件-vue3
yarn add xlsx
yarn add xlsx-style-vite (有样式需求才需要安装;背景色等)
引用插件
import*asXLSXfrom'xlsx';import*asXLSX_STYLEfrom'xlsx-style-vite'
3. 组件表格的导出(无样式)
以ant design vue 表格为例,只导出表格内容
<a-table:columns="columns":dataSource="detaildata":scroll="{ x: 'max-content',y:700 }"></table?><a-button@click="exportData">导出</a-button><script>//数据处理为数组consttransData=(columns, tableList)=>{const obj = columns.reduce((acc, cur)=>{if(!acc.titles &&!acc.keys){
acc.titles =[];
acc.keys =[];}
acc.titles.push(cur.title);
acc.keys.push(cur.dataIndex);return acc;},{});const tableBody = tableList.map((item,i)=>{return obj.keys.map((key,index)=> item[key]);});return[ obj.titles,...tableBody ];}constexportData=()=>{const tableData =transData(
columns.value,
detaildata.value
);// 将数据数组转换为工作表const ws =XLSX.utils.aoa_to_sheet(tableData);// 创建 workbookconst wb =XLSX.utils.book_new();
ws['!ref']=`A1:AI${tableData.length}`;//设置列宽
ws["!cols"]=[{wpx:120},{wpx:100},{wpx:110},{wpx:110},];//合并单元格
ws['!merges']=[{s:{r:0,c:0},e:{r:0,c:1}}]// 将 工作表 添加到 workbookXLSX.utils.book_append_sheet(wb, ws,'Sheet1');// 将 workbook 写入文件XLSX.writeFile(wb,'tablename.xlsx');}</script>
3. 自定义表格的导出 (div拼成的表格)
比如这种前端拼成的,又附带各种样式的表格
一些常用的格式:
(1):合并单元格
(2):列宽
(3):背景色
(4):字体相关-大小粗细颜色字体等
(5):表格线,边框
详细的格式可以参考:
https://www.jianshu.com/p/869375439fee
https://www.npmjs.com/package/xlsx-style
数据处理就不写了,数据处理为数组就可以了
consttoExcel=()=>{const data =[['左上表头','','','右上',''],['标题1','','','',''],['标题','测试合并','','',''],['固定标题','123','123','',''],['左下表头','','','右下',''],['2021','¥28337','测试数据','北京','黑龙江'],......]const worksheet =XLSX.utils.aoa_to_sheet([headers,...data])const workbook =XLSX.utils.book_new()
worksheet['!ref']=`A1:AI${data.length}`//列宽 按excel的列顺序排列,对应A列,B列, C列......
worksheet["!cols"]=[{wpx:200},{wpx:80},{wpx:80},{wpx:110},{wpx:110},];/*
合并单元格 默认合并当前格的右侧格子
{ s: { r: 0, c: 0 }, e: { r: 0, c: 1 } }
A1 与 B1 合并 内容为 A1 的内容
s:start 合并开始 e:end 合并结束
r:row 行 c:col 列
*/
worksheet['!merges']=[{ s:{ r:0, c:0}, e:{ r:0, c:1}},{ s:{ r:0, c:4}, e:{ r:0, c:5}},{ s:{ r:4, c:0}, e:{ r:4, c:1}},......];//表格详细样式for(let key in worksheet){if(key =='!ref'|| key =='!merges'|| key =='!cols'|| key =='!rows'){continue}else{//通过key值来选择筛选想要的设置样式的单元格if(key.substring(1)=='1'||key.substring(1)=='5'|| key =='A2'){
worksheet[key].s ={// 设置单元格样式
fill:{// 设置背景色
fgColor:{ rgb:'F2F3F7'},},
font:{// 设置字体
name:'等线',// 字体名称
sz:16,// 字体大小
bold:true,// 字体是否加粗
color:{//字体颜色
rgb:'ed263d'}},
border:{//设置边框
top:{
style:'thin',
color:{
rgb:'e5e7eb'}},
bottom:{
style:'thin',
color:{
rgb:'e5e7eb'}}},
alignment:{
horizontal:'center',// 横向(向左、向右、居中)
vertical:'center',// 纵向(向上、向下、居中)
wrapText:true,// 设置单元格自动换行,目前仅对非合并单元格生效
indent:0// 设置单元格缩进}}}elseif(key =='B1'){......}}}XLSX.utils.book_append_sheet(workbook, worksheet,'Sheet1')const tmpDown =newBlob([s2ab(XLSX_STYLE.write(workbook,{
bookType:'xlsx',
bookSST:false,
type:'binary',
cellStyles:true,})),])downloadExcelFile(tmpDown,'excelname'+'.xlsx')}/*用到的方法*/exportfunctions2ab(s){if(typeof ArrayBuffer !=='undefined'){const buf =newArrayBuffer(s.length)const view =newUint8Array(buf);for(let i =0; i != s.length;++i){
view[i]= s.charCodeAt(i)&0xff}return buf
}else{const buf =newArray(s.length)for(let i =0; i != s.length;++i){
buf[i]= s.charCodeAt(i)&0xff}return buf
}}/**
* 使用 a 标签下载文件
*/exportfunctiondownloadExcelFile(obj, fileName){const a_node = document.createElement('a')
a_node.download = fileName
if('msSaveOrOpenBlob'in navigator){
window.navigator.msSaveOrOpenBlob(obj, fileName)}else{
a_node.href =URL.createObjectURL(obj)}
a_node.click()setTimeout(()=>{URL.revokeObjectURL(obj)},2000)}
参考文章:https://blog.csdn.net/Cai181191/article/details/131130926
版权归原作者 止语之语 所有, 如有侵权,请联系我们删除。