当前位置: 首页 > news >正文

不使用后端接口导出excel的三种方式

文章目录

    • 1、使用xlsx库进行表格导出
    • 2、使用xlsx-js-style库,带样式导出
    • 3、使用exceljs插件进行表格导出
      • 完整代码

最近项目需要导出功能,就将之前用的excel导出整合了一下,整合出来下面这三种方案,三种方案分别使用 了xlsx库、xlsx-js-style库和exceljs库

1、使用xlsx库进行表格导出

优点:
1、代码简单 、适合紧急需求
2、不用处理数据,自动识别表格内容
3、兼容性好
缺点:
1、不适用复杂表格
2、不能设置样式
3、不能自定义宽高

// 下载插件
npm install xlsx --save
// 引入插件
import * as XLSX from "xlsx";export function importFiles(tableElement, fileName = '文件名称') {if (!tableElement || !(tableElement instanceof HTMLElement)) {console.error('传入的参数不是有效的 HTML 表格元素');return;}let wb = XLSX.utils.table_to_book(tableElement);let wbout = XLSX.write(wb, {bookType: "xlsx",bookSST: true,type: "array",});try {saveAs(new Blob([wbout], { type: "application/octet-stream" }),fileName + ".xlsx");} catch (e) {if (typeof console !== "undefined") console.log(e, wbout);}// 返回Excel文件的二进制数据wbout。return wbout;
}

2、使用xlsx-js-style库,带样式导出

优点:
1、样式丰富:支持字体、颜色、边框等
2、支持合并单元格,设置列宽和行高
3、不依赖于DOM,直接通过数据生成,更灵活
缺点:
1、需要手动构建数据结构和样式,代码量较大。
2、数据量大时不如原生的xlsx的性能
3、对于复杂的表格,需要预先计算合并单元格的范围

 // 下载相应的依赖包并导入npm install xlsx-js-style file-saverimport XLSXS from "xlsx-js-style";
import { saveAs } from "file-saver";/*** 将数据导出为带样式的 Excel 文件* @param {Array} data - 数据源(数组)* @param {Object} options - 配置选项* @param {string} [options.fileName='表格.xlsx'] - 导出文件名* @param {Array} [options.headers] - 表头配置(每个元素是一个对象或字符串)* @param {Array} [options.merges] - 合并单元格配置(格式:[{ s: { r, c }, e: { r, c } }])* @param {Array} [options.cols] - 列宽配置(格式:[{ wch: 10 }])* @param {Array} [options.rows] - 行高配置(格式:[{ hpx: 20 }])*/export function styleImportFile (data, options = {}) {const { headers = [], merges = [], cols = [], rows = [], sheetName = "sheet名称", fileName = "excel名称.xlsx" } = options;// 处理数据行 - 确保每个数据项都是数组格式const body = data.map(item => {// 如果item已经是数组,直接使用;否则转换为数组const rowData = Array.isArray(item) ? item : Object.values(item);return xlsxCellStyle(rowData.map(cell => (typeof cell === 'object' ? cell : { text: cell })));});console.log('处理后的数据:', data, body);// 处理表头const header = headers.map(headerRow => {return xlsxCellStyle(headerRow);});// 合并表头和数据const allData = [...header, ...body];// 创建工作表const sheet = XLSXS.utils.aoa_to_sheet(allData);// 设置合并单元格if (merges && merges.length > 0) {sheet["!merges"] = merges;}// 设置列宽if (cols && cols.length > 0) {sheet["!cols"] = cols;}// 设置行高if (rows && rows.length > 0) {sheet["!rows"] = rows;}// 创建工作簿并导出const workbook = XLSXS.utils.book_new();XLSXS.utils.book_append_sheet(workbook, sheet, sheetName);XLSXS.writeFile(workbook, fileName);console.log('导出的完整数据:', allData);
}export function xlsxCellStyle (value) {if (!Array.isArray(value)) {console.warn('cells 不是数组,已将其转换为单元素数组');value = [value];}let arr = value.map((x) => {// 处理字符串类型的简单单元格if (typeof x === 'string' || typeof x === 'number') {x = { text: x.toString() };}return {v: x.text || x.value || "",t: "s",s: {font: x.font || {name: "宋体",size: 11,bold: false,italic: false,underline: false,color: "#000000",},alignment: x.alignment || {horizontal: "center",vertical: "center",wrapText: true,},fill: x.fill || "",border: x.border? x.border !== "auto"? x.border: {top: {style: "thin",color: { rgb: "000000" },},bottom: {style: "thin",color: { rgb: "000000" },},left: {style: "thin",color: { rgb: "000000" },},right: {style: "thin",color: { rgb: "000000" },},}: "",},};});return arr;
}

3、使用exceljs插件进行表格导出

优点:
1、功能强大,支持复杂的excel功能(比如:字体、颜色、边框、背景等)
2、支持异步操作,提升用户体验(可以在导出时给用户加载提示等)
3、代码结构清晰:将表头、样式设置等步骤分离,便于理解和维护
缺点:
1、处里超大数据时,性能不如原生xlsx,可能会出现卡顿
2、灵活性不走:样式固定无法通过配置修改,列如字体、颜色等都都是写死的
3、包体积大:相比于xlsx等,exceljs体积更大,可能会影响性能

 // 下载相应的依赖包并导入
npm install exceljs file-saver
import ExcelJS from 'exceljs'
import { saveAs } from "file-saver";// 可以动态获取列的显示名称
const findColName = (item) => {return item.name || item.title || item.key;
};
// 可以将多级表头转化为单级表头(简单来说就是把复杂的多级表头,通过下面方法变为简单的一级表头)
const flatTableHeader = (tableHeader) => {let flatHeader = [];for (let i = 0; i < tableHeader.length; i++) {const item = tableHeader[i];const name = findColName(item); // 中文标题if (item.children && item.children.length > 0) {const childrenColName = item.children.map((child) => ({...child,name: `${name}-${findColName(child)}`,}));flatHeader.push(...childrenColName);} else {flatHeader.push(item);}}return flatHeader;
};export async function exportCustomExcel (tableHeader = [],json = [],fileName = "文件名称",sheetName = "Sheet1"
) {console.log(json);const flatHeader = flatTableHeader(tableHeader);const loading = ElLoading.service({lock: true,text: "正在下载中...",background: "rgba(0, 0, 0, 0.7)",});const workbook = new ExcelJS.Workbook(); // 创建工作簿const worksheet = workbook.addWorksheet(sheetName, {properties: { defaultColWidth: 24 }, // 默认列宽});console.log(flatHeader, '表头');// 设置表头列配置(比如字体、大小、背景色)worksheet.columns = flatHeader.map((item) => ({header: findColName(item), // 中文标题key: item.key,width: 24, // 设置列宽style: {font: {name: "微软雅黑",size: 14,bold: false, // 表头加粗// color: { argb: "FF000000" },color: { argb: "FFFFFFFF" }, // 白色字体},fill: {type: "pattern",pattern: "solid",},alignment: {vertical: "middle",horizontal: "left",wrapText: false,},},}));// 只给表头行(第1行)添加背景色const headerRow = worksheet.getRow(1);headerRow.fill = {type: "pattern",pattern: "solid",fgColor: { argb: "FF0070C0" }, // 蓝色背景};// 插入数据行if (json && json.length) {for (let i = 0; i < json.length; i++) {const rowData = json[i];// 数据处理if (rowData) {// 导出数据拼接处理if (JSON.stringify(flatHeader).indexOf("exportHandleFun") !== -1) {for (let j = 0; j < flatHeader.length; j++) {rowData[flatHeader[j].key] = flatHeader[j].formatter(rowData[flatHeader[j].key],rowData);}}// 设置数据行样式(字体、大小)const row = worksheet.addRow(rowData);row.eachCell((cell, colNumber) => {cell.style = {font: {name: "微软雅黑",size: 12,bold: false,color: { argb: "FF000000" },},alignment: {vertical: "middle",horizontal: "left",wrapText: false,},};});}}}// 导出文件const buffer = await workbook.xlsx.writeBuffer();const blob = new Blob([buffer], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",});const url = window.URL.createObjectURL(blob);const a = document.createElement("a");a.href = url;a.download = `${fileName}.xlsx`;a.click();window.URL.revokeObjectURL(url);loading.close();
}

完整代码

<template><div class="container"><div><el-table :data="tableData" :span-method="arraySpanMethod" border style="width: 100%" id="selectTable" ref="selectTable"><el-table-column prop="id" label="ID" width="180"></el-table-column><el-table-column prop="name" label="姓名"></el-table-column><el-table-column prop="amount1" label="数值1"></el-table-column><el-table-column prop="amount2" label="数值2"></el-table-column><el-table-column prop="amount3" label="数值3"></el-table-column></el-table><el-button type="primary" @click="exportExcel">xslx导出</el-button><el-button type="primary" @click="exportExcelCopy">xlsx + xlsx-js-style导出</el-button><el-button type="primary" @click="exportExcelFile">exportExcelFile导出</el-button></div></div>
</template>
<script setup name="setup">
import { importFiles, styleImportFile, exportCustomExcel } from '@/assets/common/importFIles'
import { ref } from 'vue'
const tableData = ref([{id: "12987122",name: "王小虎",amount1: "234",amount2: "3.2",amount3: 10,},{id: "12987123",name: "王小虎",amount1: "165",amount2: "4.43",amount3: 12,},{id: "12987124",name: "王小虎",amount1: "324",amount2: "1.9",amount3: 9,},{id: "12987125",name: "王小虎",amount1: "621",amount2: "2.2",amount3: 17,},{id: "12987126",name: "王小虎",amount1: "539",amount2: "4.1",amount3: 15,},
],)
const selectTable = ref([])
//--------------------xlsx----------------
const exportExcel = () => {const tableElement = selectTable.value.$el;importFiles(tableElement, 'Element表格数据');
}
// ------------------xlsx-js-style-------------
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {if (rowIndex % 2 === 0) {if (columnIndex === 0) {return [1, 2];} else if (columnIndex === 1) {return [0, 0];}}
}
// 导出方法 - 带样式(xlsx-js-style)
const exportExcelCopy = () => {const bodyData = tableData.value.map(item => [{ text: item.id, fill: { fgColor: { rgb: "87CEEB" } } },{ text: item.name },{ text: item.amount1 },{ text: item.amount2 },{ text: item.amount3 },])const headers = [[{text: "表格",font: {name: "宋体",size: 14,bold: true,italic: true,underline: true,color: "#FF0000",},fill: {fgColor: { rgb: "87CEEB" },},}],[{text: "信息",fill: { fgColor: { rgb: "FFC0CB" } },border: "auto",},{ text: "", border: "auto" },{ text: "数值", fill: { fgColor: { rgb: "FFC0CB" } } }],[{ text: "ID" },{ text: "姓名" },{ text: "数值1" },{ text: "数值2" },{ text: "数值3" }]]
//------------------exceljs--------------------------styleImportFile(bodyData, {headers: headers,merges: [{ s: { r: 0, c: 0 }, e: { r: 0, c: 4 } },{ s: { r: 1, c: 0 }, e: { r: 1, c: 1 } },{ s: { r: 1, c: 2 }, e: { r: 1, c: 4 } },],cols: [{ wch: 10 },{ wch: 10 },{ wch: 10 },{ wch: 10 },{ wch: 10 },],sheetName: "数据表",fileName: "导出数据.xlsx"})
}// 导出方法 - 自定义导出(exportCustomExcel)
const exportExcelFile = () => {const headers = [{ name: "ID", key: "id" },{ name: "姓名", key: "name" },{ name: "数值1", key: "amount1" },{ name: "数值2", key: "amount2" },{ name: "数值3", key: "amount3" }]exportCustomExcel(headers, tableData.value, '导出数据.xlsx')
}
</script><style scoped lang="less">
.container {width: 100%;height: 100%;
}
</style>
http://www.dtcms.com/a/609906.html

相关文章:

  • leetcode 394 字符串解码
  • 如何做充值网站seo模拟点击软件源码
  • 好看的旅游网站模板下载镇江百度推广公司
  • 智慧物业|物业管理|基于SprinBoot+vue的智慧物业管理系统(源码+数据库+文档)
  • Android thermal (7)_thermal core
  • 网站的维护费用售后服务网站建设
  • Databend SQL nom Parser 性能优化
  • wordpress的标签页网站seo竞争分析工具
  • Clip模型与Vit模型的区别?
  • 前端 CSS selector
  • 《嵌入式开发硬核指南:91问一次讲透底层到架构》
  • 贵阳市网站建设wordpress改为邮箱验证注册
  • 深入解析与应用:Delphi-2M 健康轨迹预测模型的开源实践与研究(下)
  • 可信网站值得做吗网站中怎么做下载链接
  • 在 UniApp 中为小程序实现视频播放记录功能
  • 嗑一下Vue3 生态新插件
  • 31、【Ubuntu】【远程开发】内网穿透:反向隧道建立(三)
  • ubuntu20.04下使用D435i实时运行ORB-SLAM3
  • 网站建设哪便宜wordpress建手机版6
  • 东莞如何搭建网站建设wordpress视频压缩
  • Rust 宏:深入理解与高效使用
  • 基于异质专家协同一致性学习的弱监督红外 - 可见光行人重识别
  • 挂载配置文件以Docker启动Redis服务
  • 网站被墙怎么做跳转深圳龙岗个人网站建设
  • 标准输入输出stdio和JSON-RPC
  • 免费seo网站推荐一下软件手机网站建立教程
  • 有哪些网站可以用常州小程序开发报价
  • Python自动化浏览器操作与定时任务实战指南
  • web中国民族文化展示网站4页面
  • 【剑斩OFFER】算法的暴力美学——【模板】前缀和