概述
本文是使用excel.js 插件结合 vue,实现的纯前端excel文件导出!下面是实现后的实例!
大致分为以下几步:
一:excel.js 插件的安装及引用
使用 npm 或者根据具体项目使用的 包管理工具下载:
npm i exceljs
在具体使用页面中直接 import 动态引入,或者使用require方法:
import exceljs form 'exceljs' // 或者 exportexcel() { const exceljs = require('exceljs'); // 引入exceljs }
二:创建excel工作簿
exportexcel() { const exceljs = require('exceljs'); // 引入exceljs const workbook = new exceljs.workbook();// 创建工作簿 }
根据官网方法使用配置,这里采用的 saveas 方法,这个插件直接搜索下载就行,这里就不做介绍了!
exportexcel() { const exceljs = require('exceljs'); // 引入exceljs const workbook = new exceljs.workbook(); // 创建工作簿 // 下载工作簿 workbook.xlsx.writebuffer().then((buffer) => { saveas(new blob([buffer], { type: 'application/octet-stream' }), '测试导出.xlsx');}); }
如果下载成功,说明组件引入都没有问题,进行下一步操作
三:创建excel工作表(sheet栏)
excel是可以有多个sheet栏的,创建好工作簿后,下一步一定是创建一个工作表,也就是sheet,调用 workbook.addworksheet(‘sheet栏的名字’) ,必须用变量接收一下,因为后续要对它进行操作!
exportexcel() { const exceljs = require('exceljs'); // 引入exceljs const workbook = new exceljs.workbook(); // 创建工作簿 const worksheet = workbook.addworksheet('总报价');// 创建工作表(sheet1) }
四:为excel工作表定义每列的数据
exceljs支持快速定义表头,每列的数据字段,传入表头配置数组,对应的列,就会自动赋值,与 el-table 的理念差不多,前端理解后,使用非常方便。
worksheet.columns = this.exporttableprop; // 工作表添加表头
exporttableprop的格式为:header是表头列名,key是每列的数据源,width是列宽。
const exporttableprop = [ { header: '姓名', key: 'name', width: 14 }, { header: '年龄', key: 'age', width: 14 }, { header: '性别', key: 'sex', width: 14 }, { header: '生日', key: 'birth', width: 14 } ]
表头定义好后,之后就要灌输数据啦:
// exportdatalist:键值跟上方定义的列 key 一样。 // { name: '姓名', age: '年龄', sex: '性别', birth: '生日' } worksheet.addrows(this.exportdatalist); // 往工作表插入数据 // 最后代码集合 exportexcel() { const exceljs = require('exceljs'); // 引入exceljs const workbook = new exceljs.workbook(); // 创建工作簿 const worksheet = workbook.addworksheet('sheet1');// 创建工作表(sheet1) worksheet.columns = this.exporttableprop; // 工作表添加表头 worksheet.addrows(this.exportdatalist);// 往工作表插入数据 // 下载工作簿 workbook.xlsx.writebuffer().then((buffer) => { saveas(new blob([buffer], { type: 'application/octet-stream' }), '测试导出.xlsx');}); }
五:excel设置样式(合并单元格等)
exceljs提供了一系列方法,正确调用即可画出任何样式的excel。
合并单元格: worksheet.mergecells('a1:m1') // 将a1到m1的单元格合并 获取单元格:(设置样式的前提) const cell = worksheet.getcell('a1') // 获取a1单元格 设置a1单元格显示的内容: cell.value = '我是a1各自的数据'
设置a1单元格的样式:font设置文字样式,alignment设置格子内文本如何显示,fill 设置单元格背景色。
cell.font = { size: 16, bold: true, name: '仿宋' }; // 设置字体大小为16,加粗,仿宋 cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'a9d08e' } // 设置背景色 };
六:excel的行级操作
获取第一行: worksheet.getrow(1) 调整第一行的行高: worksheet.getrow(1).height = 70 手动添加一行: worksheet.addrow(); // 不传参:在最下方加一行 worksheet.addrow(2); // 传数字:在指定列加一行 worksheet.addrow(['姓名','年龄','性别']) // 传数组:加一行,且设置行内数据
七:遍历所有行
调用worksheet.eachrow 可以遍历所有行,比如快捷设置全部行高。
worksheet.eachrow((row, rowindex) => { // 循环每一行 console.log(row) row.height = 17; })
八:遍历所有单元格
嵌套操作,可以遍历到全部单元格,代码演示:
worksheet.eachrow((row, rowindex) => { // 循环每个单元格 row.eachcell((cell, colindex) => { cell.font = { size: 11, bold: true }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; }); })
当然,加一些判断:
worksheet.eachrow((row, rowindex) => { if (rowindex === 14) { row.eachcell((cell, colindex) => { cell.font = { size: 11, bold: true }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; }); } if (rowindex > 14 && rowindex <= 25) { row.height = 17; row.eachcell((cell, colindex) => { cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; }); } })
来个实用案例: 为所有单元格设置边框:
// 定义边框样式 const borderstyle = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } } // 遍历工作表中的所有单元格并添加边框 worksheet.eachrow((row, rowindex) => { row.eachcell((cell, colindex) => { cell.border = borderstyle; }); })
九:向excel中插入图片
如果是base64编码图片,直接插入就可以,如果不是,需要转为base64。
// 将logo放入第一行 const base64 = await this.imagetobase64(); // 这里是转base64方法,不放了 // 把base64编码的图片插入excel工作簿里面 const imageid = workbook.addimage({ base64: base64, extension: 'png' }) // 当前工作表(当前excel页)加入图片,tl.col:excel第几列,tl.row:excel第几行,ext里面表示图片宽高 worksheet.addimage(imageid, { tl: { col: 0.1, row: 0.1 }, // br: { col: columns.length + ai - 11.1, row: ri + 2 } ext: { width: 100, height: 85 } })
十:插入超链接
超链接一定是单元格级别的,先获取到单元格,然后设置value即可。
cell.value = { text: '要显示的文字', hyperlink: 'www.baidu.com', tooltip: 'hover的提示' };
最后,附主图的完整代码。
async exportexcel(row) { const loading = this.$loading({ lock: true, text: '导出excel中...(若长时间无响应请刷新页面)', spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.7)' }); // 查商务报价版本 let para = { commercialquotationversionid: row.commercialquotationversionid }; let res = await getcommercialquotationversion(para); if (res.success) { let totalquotationdata = res.response; const exceljs = require('exceljs'); // 创建工作簿 const workbook = new exceljs.workbook(); // 创建工作表(sheet1) const worksheet = workbook.addworksheet('总报价'); // 表格的表头配置 worksheet.columns = this.exporttableprop; // 工作表添加表头 //======================================= 第一行 ================================= // 合并a1到l1的单元格 (大标题) worksheet.mergecells('a1:m1'); const cell = worksheet.getcell('a1'); cell.value = 'mechanical co., ltd. - quotation \n - 报价单'; // 设置第一行的单元格样式 cell.font = { size: 16, bold: true, name: '仿宋' }; // 设置字体大小为16,加粗,仿宋 cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; // 调整第一行的高度 worksheet.getrow(1).height = 70; // ==================================== 第二 到 第十二行 ================= 样式差不多,一起搞 for (let ri = 2; ri < 14; ri++) { // 创建第ri行 worksheet.addrow(ri); // 合并单元格 worksheet.mergecells(`a${ri}:c${ri}`); worksheet.mergecells(`d${ri}:f${ri}`); worksheet.mergecells(`g${ri}:i${ri}`); worksheet.mergecells(`j${ri}:m${ri}`); // a列的标题数据 let headercella = worksheet.getcell(`a${ri}`); headercella.value = this.excelheader[(ri - 2) * 2].label; headercella.alignment = { vertical: 'middle' // 垂直居中 }; if (ri <= 10) { headercella.font = { size: 11, name: '仿宋' }; } else { headercella.font = { size: 11, name: '仿宋', bold: true, color: { argb: 'ff0000' } }; } // d列 let headercelld = worksheet.getcell(`d${ri}`); if (ri > 10) { headercelld.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'ffd966' } // 设置背景色 }; } headercelld.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; // g列 let headercellg = worksheet.getcell(`g${ri}`); headercellg.value = this.excelheader[(ri - 1) * 2 - 1].label; headercellg.alignment = { vertical: 'middle' // 垂直居中 }; if (ri <= 10) { headercellg.font = { size: 11, name: '仿宋' }; } else { headercellg.font = { size: 11, name: '仿宋', bold: true, color: { argb: 'ff0000' } }; } // j列 let headercellj = worksheet.getcell(`j${ri}`); if (ri > 10 && ri !== 13) { headercellj.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'ffd966' } // 设置背景色 }; } headercellj.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; worksheet.getrow(ri).height = 15; // 获取第ri行的单元格 // const cell = worksheet.getcell(`a${ri}`); // 设置单元格样式 } // 插入表头一堆数据 row 是主表数据 totalquotationdata 是子表数据 worksheet.getcell('d2').value = row.inquiryname; // 项目名称 worksheet.getcell('d3').value = row.commercialquotationnumber; // 报价单号 worksheet.getcell('j3').value = row.creationtime; // 报价日期 worksheet.getcell('d4').value = row.customer; // 客户名称 worksheet.getcell('d11').value = ''; // 交费周期 let string = ''; this.paymentmethod.foreach((item) => { if (item.key === totalquotationdata.paymentmethod) { string = item.value; } }); worksheet.getcell('j11').value = string; // 付款方式 worksheet.getcell('d12').value = totalquotationdata.customerrequirementversion; // 技术要求版本号 worksheet.getcell('j12').value = totalquotationdata.versionnumber; // 报价版本号 worksheet.getcell('d13').value = totalquotationdata.solutionversion; // 方案版本号 // ================================ 数据部分行 ============================================================= worksheet.addrow( this.exporttableprop.map((item) => { return item.header; }) ); // 添加数据,表头信息已经在最上面定好了(这里是从接口取回来的数据) totalquotationdata.commercialquotationversionworkstationlist.foreach((item, index) => { for (let key in item) { if (item[key] === null) item[key] = ''; } item.index = index + 1; }); let tabledata = totalquotationdata.commercialquotationversionworkstationlist; worksheet.addrows(tabledata); // 设置第14行到数据结束 行的所有单元格的样式 worksheet.eachrow((row, rowindex) => { // 循环每一行 if (rowindex === 14) { row.eachcell((cell, colindex) => { cell.font = { size: 11, bold: true }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; }); } if (rowindex > 14 && rowindex <= 14 + tabledata.length) { row.height = 17; row.eachcell((cell, colindex) => { cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; }); } }); // =======================================最下方合计部分 ============================================ // ======================================= 成本小计行 ========================================== let rownum = 15 + tabledata.length; // 从第几行开始 worksheet.addrow(); worksheet.mergecells(`a${rownum}:c${rownum}`); worksheet.getcell(`a${rownum}`).value = '成本小计'; // 下面是 成本小计行的数据 worksheet.getcell(`d${rownum}`).value = totalquotationdata.mechanicalmaterialsandprocessingcosts_totalcost || ''; worksheet.getcell(`e${rownum}`).value = totalquotationdata.mechanicalpurchasecost_totalcost || ''; worksheet.getcell(`f${rownum}`).value = totalquotationdata.electricalpurchasecost_totalcost || ''; worksheet.getcell(`g${rownum}`).value = totalquotationdata.industrialcontrolcost_totalcost || ''; worksheet.getcell(`h${rownum}`).value = totalquotationdata.totalhardwarecost_totalcost || ''; worksheet.getcell(`i${rownum}`).value = totalquotationdata.laborcost_totalcost || ''; worksheet.getcell(`j${rownum}`).value = totalquotationdata.travelandaccommodationcost_totalcost || ''; worksheet.getcell(`k${rownum}`).value = totalquotationdata.transportationandothermaterialcosts_totalcost || ''; worksheet.getcell(`l${rownum}`).value = totalquotationdata.totalcost || ''; worksheet.getcell(`m${rownum}`).value = totalquotationdata.costsubtotal_remarks || ''; // 设置成本小计样式 worksheet.eachrow((row, rowindex) => { if (rowindex === rownum) { row.eachcell((cell, colindex) => { cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; // 除备注列外,其他列设置颜色 if (cell._address.indexof('m') < 0) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'f8cbad' } // 设置背景色 }; } }); row.height = 17; } }); // =================================================== 其他合计行 =================================================== let othersunrow = [ { name: '成本合计(未税)/ 元', prop: 'totalcost', remark: 'totalcost_remarks' }, { name: '管理费 / 元:', prop: 'managementfee_totalcost', remark: 'managementfee_remarks' }, { name: '财务费 / 元:', prop: 'financialfee_totalcost', remark: 'financialfee_remarks' }, { name: '利润 / 元:', prop: 'profit_totalcost', remark: 'profit_remarks' }, { name: '价格合计(未税)/ 元:', prop: 'totalpriceexcludingtax_totalcost', remark: 'totalpriceexcludingtax_remarks' }, { name: '增值税 / 元:', prop: 'valueaddedtax_totalcost', remark: 'valueaddedtax_remarks' }, { name: '价格合计(含税)/ 元:', prop: 'totalpriceincludingtax_totalcost', remark: 'totalpriceincludingtax_remarks' }, { name: '优惠后价格(含税)/ 元:', prop: 'discountedprice', remark: 'discountedprice_remarks' }, { name: '针对此次报价的其他说明', prop: 'remarks', remark: 'remarks' } ]; // 如果没有优惠后价格就不显示 let haveprice = true; if (totalquotationdata.discountedprice === null || totalquotationdata.discountedprice === '' || totalquotationdata.discountedprice === undefined) { haveprice = false; othersunrow = othersunrow.filter((item) => { return item.prop !== 'discountedprice'; }); } // 插入数据 let othernum = rownum + 1; for (let oi = 0; oi < othersunrow.length; oi++) { worksheet.addrow(); worksheet.mergecells(`a${oi + othernum}:c${oi + othernum}`); worksheet.getcell(`a${oi + othernum}`).value = othersunrow[oi].name || ''; if (oi === othersunrow.length - 1) { worksheet.mergecells(`d${oi + othernum}:m${oi + othernum}`); } else { worksheet.mergecells(`d${oi + othernum}:l${oi + othernum}`); } worksheet.getcell(`d${oi + othernum}`).value = totalquotationdata[othersunrow[oi].prop] || ''; worksheet.getcell(`m${oi + othernum}`).value = totalquotationdata[othersunrow[oi].remark] || ''; } // 设置其他合计样式 worksheet.eachrow((row, rowindex) => { if (rowindex > rownum && rowindex < rownum + othersunrow.length + 1) { if (rowindex === rownum + 6) { row.height = 17; // 增值税 row.eachcell((cell, colindex) => { cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; // 除备注列外,其他列设置颜色 if (cell._address.indexof('m') < 0) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: '9bc2e6' } // 设置背景色 }; } }); } else if (rowindex === rownum + 7 || (haveprice ? rowindex === rownum + 8 : false)) { row.height = 17; // 价税合计 、优惠后价格 row.eachcell((cell, colindex) => { cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; if (cell._address.indexof('m') < 0) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'ffd966' } // 设置背景色 }; } }); } else if (haveprice ? rowindex === rownum + 9 : rowindex === rownum + 8) { row.height = 17; // 最后的其他说明 row.eachcell((cell, colindex) => { cell.font = { size: 11, bold: true }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'a9d08e' } // 设置背景色 }; }); } else { row.height = 17; row.eachcell((cell, colindex) => { cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; if (cell._address.indexof('m') < 0) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'f8cbad' } // 设置背景色 }; } }); } } }); // 将logo放入第一行 放到最后就行啦 // 获取图片的 blob 数据 const base64 = await this.imagetobase64(); // 把base64编码的图片插入excel工作簿里面 const imageid = workbook.addimage({ base64: base64, extension: 'png' }); // 当前工作表(当前excel页)加入图片,tl.col:excel第几列,tl.row:excel第几行,ext里面表示图片宽高 worksheet.addimage(imageid, { tl: { col: 0.1, row: 0.1 }, // br: { col: columns.length + ai - 11.1, row: ri + 2 } ext: { width: 100, height: 85 } }); // 调整所有列的宽度 worksheet.columns.foreach((column) => { column.width = 17; // 将宽度设为20个字符 }); // 定义边框样式 const borderstyle = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }; // 遍历工作表中的所有单元格并添加边框 worksheet.eachrow((row, rowindex) => { row.eachcell((cell, colindex) => { cell.border = borderstyle; }); }); // =================================== 工位 sheet ======================================= var that = this; async function getdata() { let details = totalquotationdata.commercialquotationversionworkstationlist; // 这是所有工位 for (let i = 0; i < details.length; i++) { let spara = { commercialquotationversionworkstationid: details[i].commercialquotationversionworkstationid }; let sres = await getcommercialquotationversionworkstation(spara); console.log('工位', sres); let tabledata = sres.response; // 创建工位的工作表 let sworksheet = workbook.addworksheet(details[i].inquirystationcode); //======================================= 第一行 ================================= // 合并a1到l1的单元格 (大标题) sworksheet.mergecells('a1:l1'); const cell = sworksheet.getcell('a1'); cell.value = 'changchun hexin mechanical manufacturing co., ltd. - quotation \n 长春合心机械制造有限公司 - 报价单'; // 设置第一行的单元格样式 cell.font = { size: 16, bold: true, name: '仿宋' }; // 设置字体大小为16,加粗,仿宋 cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; // 调整第一行的高度 sworksheet.getrow(1).height = 70; // ==================================== 第二 到 第十二行 ================= 样式差不多,一起搞 for (let ri = 2; ri < 14; ri++) { // 创建第ri行 sworksheet.addrow(ri); // 合并单元格 sworksheet.mergecells(`a${ri}:c${ri}`); sworksheet.mergecells(`d${ri}:f${ri}`); sworksheet.mergecells(`g${ri}:i${ri}`); sworksheet.mergecells(`j${ri}:l${ri}`); // a列的标题数据 let headercella = sworksheet.getcell(`a${ri}`); headercella.value = that.excelheader[(ri - 2) * 2].label; headercella.alignment = { vertical: 'middle' // 垂直居中 }; if (ri <= 10) { headercella.font = { size: 11, name: '仿宋' }; } else { headercella.font = { size: 11, name: '仿宋', bold: true, color: { argb: 'ff0000' } }; } // d列 let headercelld = sworksheet.getcell(`d${ri}`); if (ri > 10) { headercelld.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'ffd966' } // 设置背景色 }; } headercelld.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; // g列 let headercellg = sworksheet.getcell(`g${ri}`); headercellg.value = that.excelheader[(ri - 1) * 2 - 1].label; headercellg.alignment = { vertical: 'middle' // 垂直居中 }; if (ri <= 10) { headercellg.font = { size: 11, name: '仿宋' }; } else { headercellg.font = { size: 11, name: '仿宋', bold: true, color: { argb: 'ff0000' } }; } // j列 let headercellj = sworksheet.getcell(`j${ri}`); if (ri > 10 && ri !== 13) { headercellj.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'ffd966' } // 设置背景色 }; } headercellj.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; sworksheet.getrow(ri).height = 15; // 获取第ri行的单元格 // const cell = sworksheet.getcell(`a${ri}`); // 设置单元格样式 } // 插入表头一堆数据 row 是主表数据 totalquotationdata 是子表数据 sworksheet.getcell('d2').value = row.inquiryname; // 项目名称 sworksheet.getcell('d3').value = row.commercialquotationnumber; // 报价单号 sworksheet.getcell('j3').value = row.creationtime; // 报价日期 sworksheet.getcell('d4').value = row.customer; // 客户名称 sworksheet.getcell('d11').value = ''; // 交费周期 let string = ''; that.paymentmethod.foreach((item) => { if (item.key === totalquotationdata.paymentmethod) { string = item.value; } }); sworksheet.getcell('j11').value = string; // 付款方式 sworksheet.getcell('d12').value = totalquotationdata.customerrequirementversion; // 技术要求版本号 sworksheet.getcell('j12').value = totalquotationdata.versionnumber; // 报价版本号 sworksheet.getcell('d13').value = totalquotationdata.solutionversion; // 方案版本号 // ==================================== 工位的数据部分 ================================================= // 标题行 ['no.','item 项目','小时数','费率','price 价格','备注:'] sworksheet.addrow(); sworksheet.getcell('a14').value = 'no.'; sworksheet.mergecells(`b14:c14`); sworksheet.getcell('b14').value = 'item 项目'; sworksheet.getcell('d14').value = '小时数'; sworksheet.getcell('e14').value = '费率'; sworksheet.getcell('f14').value = 'price 价格'; sworksheet.getcell('g14').value = '备注:'; sworksheet.mergecells(`g14:l14`); // 机械材料成本 sworksheet.addrow(); sworksheet.getcell('a15').value = 1; // 序号 sworksheet.mergecells(`b15:c15`); sworksheet.getcell('b15').value = '机械材料成本'; sworksheet.getcell('d15').value = '/'; // 小时数 sworksheet.getcell('e15').value = '/'; // 费率 sworksheet.getcell('f15').value = ''; // 价格 sworksheet.getcell('g15').value = ''; // 备注 sworksheet.mergecells(`g15:l15`); // 机械加工成本 sworksheet.addrow(); sworksheet.getcell('a16').value = 2; sworksheet.mergecells(`b16:c16`); sworksheet.getcell('b16').value = '机械加工成本'; sworksheet.getcell('d16').value = '/'; // 小时数 sworksheet.getcell('e16').value = '/'; // 费率 sworksheet.getcell('f16').value = tabledata.mechanicalmaterialsandprocessingcosts_aftermarkup || ''; // 价格 sworksheet.getcell('g16').value = tabledata.mechanicalmaterialsandprocessingcosts_remarks || ''; // 备注 sworksheet.mergecells(`g16:l16`); // 机械采购成本 sworksheet.addrow(); sworksheet.getcell('a17').value = 3; sworksheet.mergecells(`b17:c17`); sworksheet.getcell('b17').value = '机械采购成本'; sworksheet.getcell('d17').value = '/'; // 小时数 sworksheet.getcell('e17').value = '/'; // 费率 sworksheet.getcell('f17').value = tabledata.mechanicalpurchasecost_aftermarkup || ''; // 价格 sworksheet.getcell('g17').value = tabledata.mechanicalpurchasecost_remarks || ''; // 备注 sworksheet.mergecells(`g17:l17`); // 型材及配件 sworksheet.addrow(); sworksheet.getcell('a18').value = 4; sworksheet.mergecells(`b18:c18`); sworksheet.getcell('b18').value = '型材及配件'; sworksheet.getcell('d18').value = '/'; // 小时数 sworksheet.getcell('e18').value = '/'; // 费率 sworksheet.getcell('f18').value = ''; // 价格 sworksheet.getcell('g18').value = ''; // 备注 sworksheet.mergecells(`g18:l18`); // 电气采购成本 sworksheet.addrow(); sworksheet.getcell('a19').value = 5; sworksheet.mergecells(`b19:c19`); sworksheet.getcell('b19').value = '电气采购成本'; sworksheet.getcell('d19').value = '/'; // 小时数 sworksheet.getcell('e19').value = '/'; // 费率 sworksheet.getcell('f19').value = tabledata.electricalpurchasecost_aftermarkup || ''; // 价格 sworksheet.getcell('g19').value = tabledata.electricalpurchasecost_remarks || ''; // 备注 sworksheet.mergecells(`g19:l19`); // 机械设计费 sworksheet.addrow(); sworksheet.getcell('a20').value = 6; sworksheet.mergecells(`b20:c20`); sworksheet.getcell('b20').value = '机械设计费'; sworksheet.getcell('d20').value = tabledata.mechanicaldesignfee_hours || ''; // 小时数 sworksheet.getcell('e20').value = tabledata.mechanicaldesignfee_perhourrate || ''; // 费率 sworksheet.getcell('f20').value = tabledata.mechanicaldesignfee_totalcost || ''; // 价格 sworksheet.getcell('g20').value = tabledata.mechanicaldesignfee_remarks || ''; // 备注 sworksheet.mergecells(`g20:l20`); // 电气设计费 sworksheet.addrow(); sworksheet.getcell('a21').value = 7; sworksheet.mergecells(`b21:c21`); sworksheet.getcell('b21').value = '电气设计费'; sworksheet.getcell('d21').value = tabledata.electricaldesignfee_hours || ''; // 小时数 sworksheet.getcell('e21').value = tabledata.electricaldesignfee_perhourrate || ''; // 费率 sworksheet.getcell('f21').value = tabledata.electricaldesignfee_totalcost || ''; // 价格 sworksheet.getcell('g21').value = tabledata.electricaldesignfee_remarks || ''; // 备注 sworksheet.mergecells(`g21:l21`); // 软件编程及开发 sworksheet.addrow(); sworksheet.getcell('a22').value = 8; sworksheet.mergecells(`b22:c22`); sworksheet.getcell('b22').value = '软件编程及开发'; sworksheet.getcell('d22').value = tabledata.softwareprogramming_hours || ''; // 小时数 sworksheet.getcell('e22').value = tabledata.softwareprogramming_perhourrate || ''; // 费率 sworksheet.getcell('f22').value = tabledata.softwareprogramming_totalcost || ''; // 价格 sworksheet.getcell('g22').value = tabledata.softwareprogramming_remarks || ''; // 备注 sworksheet.mergecells(`g22:l22`); // 机器人调试 sworksheet.addrow(); sworksheet.getcell('a23').value = 9; sworksheet.mergecells(`b23:c23`); sworksheet.getcell('b23').value = '机器人调试'; sworksheet.getcell('d23').value = tabledata.robotdebugging_hours || ''; // 小时数 sworksheet.getcell('e23').value = tabledata.robotdebugging_perhourrate || ''; // 费率 sworksheet.getcell('f23').value = tabledata.robotdebugging_totalcost || ''; // 价格 sworksheet.getcell('g23').value = tabledata.robotdebugging_remarks || ''; // 备注 sworksheet.mergecells(`g23:l23`); // 项目经理费用 sworksheet.addrow(); sworksheet.getcell('a24').value = 10; sworksheet.mergecells(`b24:c24`); sworksheet.getcell('b24').value = '项目经理费用'; sworksheet.getcell('d24').value = tabledata.projectmanagerfee_hours || ''; // 小时数 sworksheet.getcell('e24').value = tabledata.projectmanagerfee_perhourrate || ''; // 费率 sworksheet.getcell('f24').value = tabledata.projectmanagerfee_totalcost || ''; // 价格 sworksheet.getcell('g24').value = tabledata.projectmanagerfee_remarks || ''; // 备注 sworksheet.mergecells(`g24:l24`); // 机械安装调试费用 sworksheet.addrow(); sworksheet.getcell('a25').value = 11; sworksheet.mergecells(`b25:c25`); sworksheet.getcell('b25').value = '机械安装调试费用'; sworksheet.getcell('d25').value = tabledata.mechanicalinstallationdebugging_hours || ''; // 小时数 sworksheet.getcell('e25').value = tabledata.mechanicalinstallationdebugging_perhourrate || ''; // 费率 sworksheet.getcell('f25').value = tabledata.mechanicalinstallationdebugging_totalcost || ''; // 价格 sworksheet.getcell('g25').value = tabledata.mechanicalinstallationdebugging_remarks || ''; // 备注 sworksheet.mergecells(`g25:l25`); // 电气安装调试费用 sworksheet.addrow(); sworksheet.getcell('a26').value = 12; sworksheet.mergecells(`b26:c26`); sworksheet.getcell('b26').value = '电气安装调试费用'; sworksheet.getcell('d26').value = tabledata.electricalinstallationdebugging_hours || ''; // 小时数 sworksheet.getcell('e26').value = tabledata.electricalinstallationdebugging_perhourrate || ''; // 费率 sworksheet.getcell('f26').value = tabledata.electricalinstallationdebugging_totalcost || ''; // 价格 sworksheet.getcell('g26').value = tabledata.electricalinstallationdebugging_remarks || ''; // 备注 sworksheet.mergecells(`g26:l26`); // 现场调试服务费 sworksheet.addrow(); sworksheet.getcell('a27').value = 13; sworksheet.mergecells(`b27:c27`); sworksheet.getcell('b27').value = '现场调试服务费'; sworksheet.getcell('d27').value = tabledata.onsitedebuggingservice_hours || ''; // 小时数 sworksheet.getcell('e27').value = tabledata.onsitedebuggingservice_perhourrate || ''; // 费率 sworksheet.getcell('f27').value = tabledata.onsitedebuggingservice_totalcost || ''; // 价格 sworksheet.getcell('g27').value = tabledata.onsitedebuggingservice_remarks || ''; // 备注 sworksheet.mergecells(`g27:l27`); // 售后服务费 sworksheet.addrow(); sworksheet.getcell('a28').value = 14; sworksheet.mergecells(`b28:c28`); sworksheet.getcell('b28').value = '售后服务费'; sworksheet.getcell('d28').value = tabledata.aftersalesservice_hours || ''; // 小时数 sworksheet.getcell('e28').value = tabledata.aftersalesservice_perhourrate || ''; // 费率 sworksheet.getcell('f28').value = tabledata.aftersalesservice_totalcost || ''; // 价格 sworksheet.getcell('g28').value = tabledata.aftersalesservice_remarks || ''; // 备注 sworksheet.mergecells(`g28:l28`); // 包装及运输费用 sworksheet.addrow(); sworksheet.getcell('a29').value = 15; sworksheet.mergecells(`b29:c29`); sworksheet.getcell('b29').value = '包装及运输费用'; sworksheet.getcell('d29').value = '/'; // 小时数 sworksheet.getcell('e29').value = '/'; // 费率 sworksheet.getcell('f29').value = tabledata.shippingpackagingcost_aftermarkup || ''; // 价格 sworksheet.getcell('g29').value = tabledata.shippingpackagingcost_remarks || ''; // 备注 sworksheet.mergecells(`g29:l29`); // 差旅费 sworksheet.addrow(); sworksheet.getcell('a30').value = 16; sworksheet.mergecells(`b30:c30`); sworksheet.getcell('b30').value = '差旅费'; sworksheet.getcell('d30').value = '/'; // 小时数 sworksheet.getcell('e30').value = '/'; // 费率 sworksheet.getcell('f30').value = tabledata.travelandaccommodationcost_aftermarkup || ''; // 价格 sworksheet.getcell('g30').value = tabledata.travelandaccommodationcost_remarks || ''; // 备注 sworksheet.mergecells(`g30:l30`); // 资料费 sworksheet.addrow(); sworksheet.getcell('a31').value = 17; sworksheet.mergecells(`b31:c31`); sworksheet.getcell('b31').value = '资料费'; sworksheet.getcell('d31').value = '/'; // 小时数 sworksheet.getcell('e31').value = '/'; // 费率 sworksheet.getcell('f31').value = tabledata.documentcost_aftermarkup || ''; // 价格 sworksheet.getcell('g31').value = tabledata.documentcost_remarks || ''; // 备注 sworksheet.mergecells(`g31:l31`); // 成本合计(小结) sworksheet.addrow(); sworksheet.getcell('a32').value = 18; sworksheet.mergecells(`b32:c32`); sworksheet.getcell('b32').value = '成本合计(小结)'; sworksheet.getcell('d32').value = '/'; // 小时数 sworksheet.getcell('e32').value = '/'; // 费率 sworksheet.getcell('f32').value = tabledata.totalcost || ''; // 价格 sworksheet.getcell('g32').value = ''; // 备注 sworksheet.mergecells(`g32:l32`); // 管理费 sworksheet.addrow(); sworksheet.getcell('a33').value = 19; sworksheet.mergecells(`b33:c33`); sworksheet.getcell('b33').value = '管理费'; sworksheet.getcell('d33').value = '/'; // 小时数 sworksheet.getcell('e33').value = '/'; // 费率 sworksheet.getcell('f33').value = tabledata.managementfee || ''; // 价格 sworksheet.getcell('g33').value = ''; // 备注 sworksheet.mergecells(`g33:l33`); // 财务费 sworksheet.addrow(); sworksheet.getcell('a34').value = 20; sworksheet.mergecells(`b34:c34`); sworksheet.getcell('b34').value = '财务费'; sworksheet.getcell('d34').value = '/'; // 小时数 sworksheet.getcell('e34').value = '/'; // 费率 sworksheet.getcell('f34').value = tabledata.financialfee || ''; // 价格 sworksheet.getcell('g34').value = ''; // 备注 sworksheet.mergecells(`g34:l34`); // 利润 sworksheet.addrow(); sworksheet.getcell('a35').value = 21; sworksheet.mergecells(`b35:c35`); sworksheet.getcell('b35').value = '利润'; sworksheet.getcell('d35').value = '/'; // 小时数 sworksheet.getcell('e35').value = '/'; // 费率 sworksheet.getcell('f35').value = tabledata.profit || ''; // 价格 sworksheet.getcell('g35').value = ''; // 备注 sworksheet.mergecells(`g35:l35`); // 价格合计(未税) sworksheet.addrow(); sworksheet.getcell('a36').value = 22; sworksheet.mergecells(`b36:c36`); sworksheet.getcell('b36').value = '价格合计(未税)'; sworksheet.getcell('d36').value = '/'; // 小时数 sworksheet.getcell('e36').value = '/'; // 费率 sworksheet.getcell('f36').value = tabledata.totalpriceexcludingtax || ''; // 价格 sworksheet.getcell('g36').value = ''; // 备注 sworksheet.mergecells(`g36:l36`); // 增值税 sworksheet.addrow(); sworksheet.getcell('a37').value = 23; sworksheet.mergecells(`b37:c37`); sworksheet.getcell('b37').value = '增值税'; sworksheet.getcell('d37').value = '/'; // 小时数 sworksheet.getcell('e37').value = '/'; // 费率 sworksheet.getcell('f37').value = tabledata.valueaddedtax || ''; // 价格 sworksheet.getcell('g37').value = ''; // 备注 sworksheet.mergecells(`g37:l37`); // 价格合计(含税) sworksheet.addrow(); sworksheet.getcell('a38').value = 24; sworksheet.mergecells(`b38:c38`); sworksheet.getcell('b38').value = '价格合计(含税)'; sworksheet.getcell('d38').value = '/'; // 小时数 sworksheet.getcell('e38').value = '/'; // 费率 sworksheet.getcell('f38').value = tabledata.valueaddedtax || ''; // 价格 sworksheet.getcell('g38').value = ''; // 备注 sworksheet.mergecells(`g38:l38`); // 数据行统一样式处理 sworksheet.eachrow((row, rowindex) => { // 循环每一行 if (rowindex >= 14 && rowindex <= 38) { if (rowindex === 14) { // 标题行 row.eachcell((cell, colindex) => { console.log('cell', cell); cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; cell.font = { size: 11, bold: true }; if (cell._address === 'd14' || cell._address === 'e14') { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: '00b0f0' } // 设置背景色 }; } }); } else if (rowindex >= 20 && rowindex <= 28) { // 从机械设计 到 售后服务行 row.eachcell((cell, colindex) => { console.log('cell', cell); cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; if (cell._address.indexof('b') > -1 || cell._address.indexof('f') > -1) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'd9e1f2' } // 设置背景色 }; } if (cell._address.indexof('d') > -1 || cell._address.indexof('e') > -1) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: '00b0f0' } // 设置背景色 }; } }); } else if (rowindex === 32) { row.eachcell((cell, colindex) => { console.log('cell', cell); cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; if (cell._address.indexof('b') > -1 || cell._address.indexof('f') > -1) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'e2efda' } // 设置背景色 }; } }); } else if (rowindex === 36) { row.eachcell((cell, colindex) => { console.log('cell', cell); cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; if (cell._address.indexof('b') > -1 || cell._address.indexof('f') > -1) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'c6e0b4' } // 设置背景色 }; } }); } else if (rowindex === 38) { row.eachcell((cell, colindex) => { console.log('cell', cell); cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; if (cell._address.indexof('b') > -1 || cell._address.indexof('f') > -1) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'a9d08e' } // 设置背景色 }; } }); } else { row.eachcell((cell, colindex) => { console.log('cell', cell); cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; if (cell._address.indexof('b') > -1 || cell._address.indexof('f') > -1) { cell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'd9e1f2' } // 设置背景色 }; } }); } row.height = 17; } }); // 最下方针对报价其他说明列 sworksheet.addrow(); sworksheet.mergecells(`a39:c39`); sworksheet.mergecells(`d39:l39`); let remarkcell = sworksheet.getcell('a39'); remarkcell.value = '针对此次报价的其他说明:'; remarkcell.font = { size: 12, bold: true }; remarkcell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; remarkcell.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'a9d08e' } // 设置背景色 }; let remarkcell1 = sworksheet.getcell('d39'); remarkcell1.font = { size: 12 }; remarkcell1.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wraptext: true // 自动换行 }; remarkcell1.fill = { type: 'pattern', pattern: 'solid', fgcolor: { argb: 'a9d08e' } // 设置背景色 }; sworksheet.getrow(39).height = 20; // 将logo放入第一行 放到最后就行啦(复用总报价) // 前面已经加载了 imageid,这里直接用 // 当前工作表(当前excel页)加入图片,tl.col:excel第几列,tl.row:excel第几行,ext里面表示图片宽高 sworksheet.addimage(imageid, { tl: { col: 0.1, row: 0.1 }, // br: { col: columns.length + ai - 11.1, row: ri + 2 } ext: { width: 100, height: 85 } }); // 调整所有列的宽度 sworksheet.columns.foreach((column) => { column.width = 17; // 将宽度设为20个字符 }); // 定义边框样式 const borderstyle = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' } }; // 遍历工作表中的所有单元格并添加边框 sworksheet.eachrow((row, rowindex) => { row.eachcell((cell, colindex) => { cell.border = borderstyle; }); }); } } await getdata(); // 保存工作簿 workbook.xlsx.writebuffer().then((buffer) => { saveas(new blob([buffer], { type: 'application/octet-stream' }), '商务报价单导出.xlsx'); }); } else { this.$message(res.msg); } loading.close(); },
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论