在Vue中使用xlsx组件实现Excel导出功能的步骤详解
作者:sg_knight
在现代Web应用程序中,数据导出到Excel格式是一项常见的需求,Vue.js是一种流行的JavaScript框架,允许我们构建动态的前端应用程序,本文将介绍如何使用Vue.js和xlsx组件轻松实现Excel数据导出功能,需要的朋友可以参考下
1、项目设置
首先,在控制台执行以下命令安装xlsx组件;
npm install xlsx --save 或 yarn add xlsx --save
然后,在vue项目中引入xls组件;
2、准备数据
要导出到Excel,您需要有数据。您可以使用本地数据或从API获取数据。在本示例中,我们将使用本地数据:
exportData: [ { name: "John", age: 30, city: "New York" }, { name: "Alice", age: 25, city: "Los Angeles" }, { name: "Bob", age: 35, city: "Chicago" } ]
3、实现导出功能
创建导出到Excel的方法。这个方法将触发Excel文件的生成和下载:
exportToExcel() { const worksheet = XLSX.utils.json_to_sheet(this.exportData); const workbook = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(workbook, worksheet, "Sheet1"); XLSX.writeFile(workbook, "exported-data.xlsx"); }
这个方法使用xlsx组件将数据转换为Excel工作表,然后创建一个工作簿并将工作表添加到工作簿中。最后,它使用XLSX.writeFile
方法将工作簿保存为名为"exported-data.xlsx"的Excel文件。
4、设置列宽自适应
根据导出数据的长度,通过遍历计算每列的最大长度,然后通过worksheet['!cols']方法设置每列宽度;
// 设置列宽 exportData.forEach((row, rowIndex) => { row.forEach((cell, cellIndex) => { const list = arrData.map(item => { const val = item[cellIndex] as string; if(isEmptyString(val)){ return 1; } else if(val.toString().charCodeAt(0) > 255){ // 判断是否有中文 return val.toString().length * 2 } else{ return val.toString().length; } }); const maxLength = Math.max(...list); const width = maxLength * 1.1; // 根据实际内容长度自动调整列宽 if(!worksheet["!cols"]) worksheet["!cols"] = []; if(!worksheet["!cols"][cellIndex]) worksheet["!cols"][cellIndex] = {wch: 8}; worksheet['!cols'][cellIndex].wch = width; // 使用worksheet的 '!cols' 来设置列宽 }); });
5、设置合并单元格
通过worksheet["!merges"]方法可以设置合并单元格;
// 合并单元格 merges.forEach((item) => { if(!worksheet["!merges"]){ worksheet["!merges"] = []; }; worksheet["!merges"].push(item); // worksheet["!merges"].push({ // s: { r: 2, c: 1 }, // s ("start"): c = 1 r = 2 -> "B3" // e: { r: 3, c: 4 } // e ("end"): c = 4 r = 3 -> "E4" // }); });
6、设置导出Excel表格的样式
xlsx组件库是不支持设置Excel表格样式的,但是可以通过引入xlsx-style-vite组件库来实现样式的设置;然后通过file-saver导出文件;
6.1 安装并引入xlsx-style-vite和file-saver组件
yarn add xlsx-style-vite --save yarn add file-saver --save
import XLSXStyle from 'xlsx-style-vite'; import XLSX_SAVE from 'file-saver';
其中 xlsx-style-vite组件是xlsx-style组件的vite版本,用于解决在vite下引入xlsx-style异常的问题;
6.2 设置单元格居中
遍历所有单元格,然后通过worksheet[column].s方法设置每个单元格的样式;
exportData.forEach((row, rowIndex) => { row.forEach((cell, cellIndex) => { // 设置所有单元格居中 let column = utils.encode_cell({c: cellIndex, r: rowIndex}); worksheet[column].s = { alignment: { horizontal: 'center', vertical: 'center', wrapText: false, // 自动换行 }, } }); });
6.3 设置单元格背景色和字体
exportData.forEach((row, rowIndex) => { row.forEach((cell, cellIndex) => { // 设置所有单元格居中 let column = utils.encode_cell({c: cellIndex, r: rowIndex}); if(worksheet[column]){ // 设置背景色、加粗展示 worksheet[column].s = { font: { name: "微软雅黑", sz: 16, color: { rgb: "000000" }, bold: true, italic: false, underline: false, }, fill: { fgColor: { rgb: "C5D9F1" }, }, alignment: { horizontal: 'center', vertical: 'center', wrapText: false, // 自动换行 }, } } } }); });
6.4 设置单元格边框
//单元格外侧框线 const borderAll = { top: { style: "thin", }, bottom: { style: "thin", }, left: { style: "thin", }, right: { style: "thin", }, }; // 设置单元格边框 arrData.forEach((row, rowIndex) => { row.forEach((cell, cellIndex) => { let column = utils.encode_cell({c: cellIndex, r: rowIndex}); if(worksheet[column]){ worksheet[column].s = { border: borderAll, } } } }); });
6.5 导出文件
必须通过file-saver组件导出Excel文件,不能通过xlsx组件的writeFile方法导出文件,否则样式无法生效;
const wbout = XLSXStyle.write(workbook, { type: 'binary', bookType: 'xlsx', }); XLSX_SAVE.saveAs( new Blob([s2ab(wbout)], { type: 'application/octet-stream', }), 'exported-data.xlsx', ); // 数据转换 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; }
7、完整代码示例
import * as xlsx from 'xlsx'; import type { WorkBook } from 'xlsx'; import type { JsonToSheet, AoAToSheet } from './typing'; import XLSXStyle from 'xlsx-style-vite'; import XLSX_SAVE from 'file-saver'; import { isEmptyString } from '@/utils/table'; const { utils, writeFile } = xlsx; const DEF_FILE_NAME = 'excel-list.xlsx'; export function aoaToSheetXlsx<T = any>({ data, header, filename = DEF_FILE_NAME, write2excelOpts = { bookType: 'xlsx' }, merges = [], }: AoAToSheet<T>) { const arrData = [...data]; if (header) { arrData.unshift(header); } const worksheet = utils.aoa_to_sheet(arrData); /* add worksheet to workbook */ const workbook: WorkBook = { SheetNames: [filename], Sheets: { [filename]: worksheet, }, }; //单元格外侧框线 const borderAll = { top: { style: "thin", }, bottom: { style: "thin", }, left: { style: "thin", }, right: { style: "thin", }, }; // 设置列宽 arrData.forEach((row, rowIndex) => { row.forEach((cell, cellIndex) => { const list = arrData.map(item => { const val = item[cellIndex] as string; if(isEmptyString(val)){ return 1; } else if(val.toString().charCodeAt(0) > 255){ // 判断是否有中文 return val.toString().length * 2 } else{ return val.toString().length; } }); const maxLength = Math.max(...list); const width = maxLength * 1.1; // 根据实际内容长度自动调整列宽 if(!worksheet["!cols"]) worksheet["!cols"] = []; if(!worksheet["!cols"][cellIndex]) worksheet["!cols"][cellIndex] = {wch: 8}; worksheet['!cols'][cellIndex].wch = width; // 使用worksheet的 '!cols' 来设置列宽 // 设置所有单元格居中 let column = utils.encode_cell({c: cellIndex, r: rowIndex}); if(worksheet[column]){ if(rowIndex === 0) { // 标题行设置背景色、加粗展示 worksheet[column].s = { border: borderAll, font: { // name: "微软雅黑", // sz: 16, color: { rgb: "000000" }, bold: true, italic: false, underline: false, }, fill: { fgColor: { rgb: "C5D9F1" }, }, alignment: { horizontal: 'center', vertical: 'center', wrapText: false, // 自动换行 }, } } else { worksheet[column].s = { alignment: { horizontal: 'center', vertical: 'center', wrapText: false, // 自动换行 }, } } } }); }); // 合并单元格 merges.forEach((item) => { if(!worksheet["!merges"]){ worksheet["!merges"] = []; }; worksheet["!merges"].push(item); // worksheet["!merges"].push({ // s: { r: 2, c: 1 }, // s ("start"): c = 1 r = 2 -> "B3" // e: { r: 3, c: 4 } // e ("end"): c = 4 r = 3 -> "E4" // }); }); const wbout = XLSXStyle.write(workbook, { type: 'binary', bookType: 'xlsx', }); XLSX_SAVE.saveAs( new Blob([s2ab(wbout)], { type: 'application/octet-stream', }), `${filename}.${write2excelOpts.bookType}`, ); /* output format determined by filename */ // writeFile(workbook, filename, write2excelOpts); /* at this point, out.xlsb will have been downloaded */ } // 数据转换 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; }
以上就是在Vue中使用xlsx组件实现Excel导出功能的步骤详解的详细内容,更多关于Vue xlsx组件实现Excel导出的资料请关注脚本之家其它相关文章!