ToB企服应用市场:ToB评测及商务社交产业平台

标题: vue纯前端使用exceljs导出excel文件手把手教程,非官方文档直粘 [打印本页]

作者: 道家人    时间: 2024-8-29 00:44
标题: vue纯前端使用exceljs导出excel文件手把手教程,非官方文档直粘
有许多多少私信小同伴,问我的那篇帖子:
  
  vue纯前端导出excel,包括列表批量导出图片、文件超链接
  
  上篇文章只是将公司的需求代码实现粘贴了进来,对于没有使用过exceljs插件的人来说,确实是有点晦涩的,本文就按自己的理解,一步一步将exceljs插件的使用讲解一下,有不明白或理解错误的地方接待指出,促进我进步。
  最终实现样式展示:


目录
一、exceljs的安装、引用
二、创建excel工作簿
三、创建excel工作表(sheet栏)
四、为excel工作表定义每列的数据
五、excel设置样式(合并单元格等)
六、excel的行级操纵
七、遍历所有行
八、遍历所有单元格
九、向excel中插入图片
十、插入超链接 
十一、主图完整代码



一、exceljs的安装、引用

        首先执行npm i exceljs,将依赖安装到你的项目中
  1. npm i exceljs
复制代码
        在vue页面中,创建一个方法,将exceljs引入
  1. exportExcel() {
  2.         const Exceljs = require('exceljs'); // 引入exceljs
  3. },
复制代码
二、创建excel工作簿

        引入成功后,先来创建一个excel工作簿
  1. exportExcel() {
  2.         const Exceljs = require('exceljs'); // 引入exceljs
  3.         const workbook = new Exceljs.Workbook();// 创建工作簿
  4. },
复制代码
        此时,我们增加以下内容,就会下载出一个excel文件啦。
        我用了 saveAs 插件下载,安装方式任意搜一下,这里就不赘述了。
  1. exportExcel() {
  2.         const Exceljs = require('exceljs'); // 引入exceljs
  3.         const workbook = new Exceljs.Workbook(); // 创建工作簿
  4.         // 下载工作簿
  5.         workbook.xlsx.writeBuffer().then((buffer) => {
  6.         saveAs(new Blob([buffer], { type: 'application/octet-stream' }), '测试导出.xlsx');});
  7. },
复制代码
        如果下载成功,阐明组件引入都没有问题,进行下一步操纵~
三、创建excel工作表(sheet栏)

        excel是可以有多个sheet栏的,创建好工作簿后,下一步一定是创建一个工作表,也就是sheet,调用  workbook.addWorksheet('sheet栏的名字') ,必须用变量吸收一下,因为后续要对它进行操纵!
  1. exportExcel() {
  2.         const Exceljs = require('exceljs'); // 引入exceljs
  3.         const workbook = new Exceljs.Workbook(); // 创建工作簿
  4.         const workSheet = workbook.addWorksheet('总报价');// 创建工作表(sheet1)
  5. },
复制代码
四、为excel工作表定义每列的数据

        exceljs支持快速定义表头,每列的数据字段,传入表头配置数组,对应的列,就会主动赋值,与 el-table 的理念差不多,前端理解后,使用非常方便。
  1. workSheet.columns = this.exportTableProp; // 工作表添加表头
复制代码
        exportTableProp的格式为:
        header是表头列名,key是每列的数据源,width是列宽
  1. [
  2.     {
  3.             header: '姓名',
  4.             key: 'name',
  5.             width: 14
  6.     },
  7.     {
  8.             header: '年龄',
  9.             key: 'age',
  10.             width: 14
  11.     },
  12.     {
  13.             header: '性别',
  14.             key: 'sex',
  15.             width: 14
  16.     },
  17.     {
  18.             header: '生日',
  19.             key: 'birth',
  20.             width: 14
  21.     }
  22. ]
复制代码
        定义表头后,插入数据:
  1. workSheet.addRows(this.exportDataList);  // 往工作表插入数据
复制代码
        将代码连起来,已经可以执行啦,导出一个完整的excel
  1. exportExcel() {
  2.         const Exceljs = require('exceljs'); // 引入exceljs
  3.         const workbook = new Exceljs.Workbook(); // 创建工作簿
  4.         const workSheet = workbook.addWorksheet('sheet1');// 创建工作表(sheet1)
  5.         workSheet.columns = this.exportTableProp; // 工作表添加表头
  6.         workSheet.addRows(this.exportDataList);// 往工作表插入数据
  7.         // 下载工作簿
  8.         workbook.xlsx.writeBuffer().then((buffer) => {
  9.         saveAs(new Blob([buffer], { type: 'application/octet-stream' }), '测试导出.xlsx');});
  10. },
复制代码
五、excel设置样式(合并单元格等)

        exceljs提供了一系列方法,精确调用即可画出任何样式的excel
        合并单元格:
  1. workSheet.mergeCells('A1:M1'); //将A1到M1的单元格合并
复制代码
        获取单元格:(设置样式的前提)
  1. const cell = workSheet.getCell('A1'); // 获取A1单元格
复制代码
        设置A1单元格显示的内容:
  1. cell.value = '我是A1各自的数据';
复制代码
        设置A1单元格的样式:
        font设置文字样式,alignment设置格子内文本怎样显示,fill 设置单元格配景致
  1. cell.font = { size: 16, bold: true, name: '仿宋' }; // 设置字体大小为16,加粗,仿宋
  2. cell.alignment = {
  3.         vertical: 'middle', // 垂直居中
  4.         horizontal: 'center', // 水平居中
  5.         wrapText: true // 自动换行
  6. };
  7. cell.fill = {
  8.         type: 'pattern',
  9.         pattern: 'solid',
  10.         fgColor: { argb: 'A9D08E' } // 设置背景色
  11. };
复制代码
六、excel的行级操纵

        获取第一行:
  1. workSheet.getRow(1)
复制代码
        调解第一行的行高
  1. workSheet.getRow(1).height = 70;
复制代码
        手动添加一行:
  1. workSheet.addRow();
  2. workSheet.addRow(2);
  3. workSheet.addRow(['姓名','年龄','性别']);
复制代码
        不传参:在最下方加一行
        传数字:在指定列加一行
        传数组:加一行,且设置行内数据
七、遍历所有行

        调用workSheet.eachRow 可以遍历所有行,好比快捷设置全部行高
  1. workSheet.eachRow((row, rowIndex) => {
  2.         // 循环每一行
  3.     console.log(row)       
  4.     row.height = 17;                       
  5. });
复制代码
八、遍历所有单元格

        嵌套操纵,可以遍历到全部单元格,代码演示:
  1. workSheet.eachRow((row, rowIndex) => {
  2.         // 循环每个单元格               
  3.         row.eachCell((cell, colIndex) => {
  4.                 cell.font = { size: 11, bold: true };
  5.                 cell.alignment = {
  6.                         vertical: 'middle', // 垂直居中
  7.                         horizontal: 'center', // 水平居中
  8.                         wrapText: true // 自动换行
  9.                 };
  10.         });
  11.                                        
  12. });
复制代码
        当然,也可以加判断
  1. workSheet.eachRow((row, rowIndex) => {                       
  2.         if (rowIndex === 14) {
  3.                 row.eachCell((cell, colIndex) => {
  4.                         cell.font = { size: 11, bold: true };
  5.                         cell.alignment = {
  6.                                 vertical: 'middle', // 垂直居中
  7.                                 horizontal: 'center', // 水平居中
  8.                                 wrapText: true // 自动换行
  9.                         };
  10.                 });
  11.         }
  12.         if (rowIndex > 14 && rowIndex <= 25) {
  13.                 row.height = 17;
  14.                 row.eachCell((cell, colIndex) => {
  15.                     cell.font = { size: 11 };
  16.                     cell.alignment = {
  17.                             vertical: 'middle', // 垂直居中
  18.                             horizontal: 'center', // 水平居中
  19.                             wrapText: true // 自动换行
  20.                     };
  21.                 });
  22.         }
  23. });
复制代码
来个实用案例: 为所有单元格设置边框:
  1. // 定义边框样式
  2. const borderStyle = {
  3.         top: { style: 'thin' },
  4.         left: { style: 'thin' },
  5.         bottom: { style: 'thin' },
  6.         right: { style: 'thin' }
  7. };
  8. // 遍历工作表中的所有单元格并添加边框
  9. workSheet.eachRow((row, rowIndex) => {
  10.         row.eachCell((cell, colIndex) => {
  11.                 cell.border = borderStyle;
  12.         });
  13. });
复制代码
九、向excel中插入图片

如果是base64编码图片,直接插入就可以,如果不是,需要转为base64
  1. // 将logo放入第一行
  2. const base64 = await this.imageToBase64(); // 这里是转base64方法,不放了
  3. // 把base64编码的图片插入excel工作簿里面
  4. const imageId = workbook.addImage({
  5.                 base64: base64,
  6.                 extension: 'png'
  7. });
  8. // 当前工作表(当前excel页)加入图片,tl.col:excel第几列,tl.row:excel第几行,ext里面表示图片宽高
  9. workSheet.addImage(imageId, {
  10.         tl: { col: 0.1, row: 0.1 },
  11.         // br: { col: columns.length + ai - 11.1, row: ri + 2 }
  12.         ext: { width: 100, height: 85 }
  13. });
复制代码
十、插入超链接

超链接一定是单元格级别的,先获取到单元格,然后设置value即可
  1. cell.value = {
  2.                 text: '要显示的文字',
  3.                 hyperlink: 'www.baidu.com',
  4.                 tooltip: 'hover的提示'
  5. };
复制代码
将上述操纵全部用上,信赖你的excel就可以任意定义啦~
十一、主图完整代码

最后,附主图的完整屎山代码,接口就不放了
  1. async exportExcel(row) {
  2.                         const loading = this.$loading({
  3.                                 lock: true,
  4.                                 text: '导出excel中...(若长时间无响应请刷新页面)',
  5.                                 spinner: 'el-icon-loading',
  6.                                 background: 'rgba(0, 0, 0, 0.7)'
  7.                         });
  8.                         // 查商务报价版本
  9.                         let para = {
  10.                                 CommercialQuotationVersionId: row.commercialQuotationVersionId
  11.                         };
  12.                         let res = await GetCommercialQuotationVersion(para);
  13.                         if (res.success) {
  14.                                 let totalQuotationData = res.response;
  15.                                 const Exceljs = require('exceljs');
  16.                                 // 创建工作簿
  17.                                 const workbook = new Exceljs.Workbook();
  18.                                 // 创建工作表(sheet1)
  19.                                 const workSheet = workbook.addWorksheet('总报价');
  20.                                 // 表格的表头配置
  21.                                 workSheet.columns = this.exportTableProp; // 工作表添加表头
  22.                                 //======================================= 第一行 =================================
  23.                                 // 合并A1到L1的单元格 (大标题)
  24.                                 workSheet.mergeCells('A1:M1');
  25.                                 const cell = workSheet.getCell('A1');
  26.                                 cell.value = 'Mechanical  CO., LTD. - Quotation \n - 报价单';
  27.                                 // 设置第一行的单元格样式
  28.                                 cell.font = { size: 16, bold: true, name: '仿宋' }; // 设置字体大小为16,加粗,仿宋
  29.                                 cell.alignment = {
  30.                                         vertical: 'middle', // 垂直居中
  31.                                         horizontal: 'center', // 水平居中
  32.                                         wrapText: true // 自动换行
  33.                                 };
  34.                                 // 调整第一行的高度
  35.                                 workSheet.getRow(1).height = 70;
  36.                                 // ==================================== 第二 到 第十二行 ================= 样式差不多,一起搞
  37.                                 for (let ri = 2; ri < 14; ri++) {
  38.                                         // 创建第ri行
  39.                                         workSheet.addRow(ri);
  40.                                         // 合并单元格
  41.                                         workSheet.mergeCells(`A${ri}:C${ri}`);
  42.                                         workSheet.mergeCells(`D${ri}:F${ri}`);
  43.                                         workSheet.mergeCells(`G${ri}:I${ri}`);
  44.                                         workSheet.mergeCells(`J${ri}:M${ri}`);
  45.                                         // A列的标题数据
  46.                                         let headerCellA = workSheet.getCell(`A${ri}`);
  47.                                         headerCellA.value = this.excelHeader[(ri - 2) * 2].label;
  48.                                         headerCellA.alignment = {
  49.                                                 vertical: 'middle' // 垂直居中
  50.                                         };
  51.                                         if (ri <= 10) {
  52.                                                 headerCellA.font = { size: 11, name: '仿宋' };
  53.                                         } else {
  54.                                                 headerCellA.font = { size: 11, name: '仿宋', bold: true, color: { argb: 'FF0000' } };
  55.                                         }
  56.                                         // D列
  57.                                         let headerCellD = workSheet.getCell(`D${ri}`);
  58.                                         if (ri > 10) {
  59.                                                 headerCellD.fill = {
  60.                                                         type: 'pattern',
  61.                                                         pattern: 'solid',
  62.                                                         fgColor: { argb: 'FFD966' } // 设置背景色
  63.                                                 };
  64.                                         }
  65.                                         headerCellD.alignment = {
  66.                                                 vertical: 'middle', // 垂直居中
  67.                                                 horizontal: 'center', // 水平居中
  68.                                                 wrapText: true // 自动换行
  69.                                         };
  70.                                         // G列
  71.                                         let headerCellG = workSheet.getCell(`G${ri}`);
  72.                                         headerCellG.value = this.excelHeader[(ri - 1) * 2 - 1].label;
  73.                                         headerCellG.alignment = {
  74.                                                 vertical: 'middle' // 垂直居中
  75.                                         };
  76.                                         if (ri <= 10) {
  77.                                                 headerCellG.font = { size: 11, name: '仿宋' };
  78.                                         } else {
  79.                                                 headerCellG.font = { size: 11, name: '仿宋', bold: true, color: { argb: 'FF0000' } };
  80.                                         }
  81.                                         // J列
  82.                                         let headerCellJ = workSheet.getCell(`J${ri}`);
  83.                                         if (ri > 10 && ri !== 13) {
  84.                                                 headerCellJ.fill = {
  85.                                                         type: 'pattern',
  86.                                                         pattern: 'solid',
  87.                                                         fgColor: { argb: 'FFD966' } // 设置背景色
  88.                                                 };
  89.                                         }
  90.                                         headerCellJ.alignment = {
  91.                                                 vertical: 'middle', // 垂直居中
  92.                                                 horizontal: 'center', // 水平居中
  93.                                                 wrapText: true // 自动换行
  94.                                         };
  95.                                         workSheet.getRow(ri).height = 15;
  96.                                         // 获取第ri行的单元格
  97.                                         // const cell = workSheet.getCell(`A${ri}`);
  98.                                         // 设置单元格样式
  99.                                 }
  100.                                 // 插入表头一堆数据 row 是主表数据 totalQuotationData 是子表数据
  101.                                 workSheet.getCell('D2').value = row.inquiryName; // 项目名称
  102.                                 workSheet.getCell('D3').value = row.commercialQuotationNumber; // 报价单号
  103.                                 workSheet.getCell('J3').value = row.creationTime; // 报价日期
  104.                                 workSheet.getCell('D4').value = row.customer; // 客户名称
  105.                                 workSheet.getCell('D11').value = ''; // 交费周期
  106.                                 let string = '';
  107.                                 this.PaymentMethod.forEach((item) => {
  108.                                         if (item.key === totalQuotationData.paymentMethod) {
  109.                                                 string = item.value;
  110.                                         }
  111.                                 });
  112.                                 workSheet.getCell('J11').value = string; // 付款方式
  113.                                 workSheet.getCell('D12').value = totalQuotationData.customerRequirementVersion; // 技术要求版本号
  114.                                 workSheet.getCell('J12').value = totalQuotationData.versionNumber; // 报价版本号
  115.                                 workSheet.getCell('D13').value = totalQuotationData.solutionVersion; // 方案版本号
  116.                                 // ================================ 数据部分行 =============================================================
  117.                                 workSheet.addRow(
  118.                                         this.exportTableProp.map((item) => {
  119.                                                 return item.header;
  120.                                         })
  121.                                 );
  122.                                 // 添加数据,表头信息已经在最上面定好了(这里是从接口取回来的数据)
  123.                                 totalQuotationData.commercialQuotationVersionWorkstationList.forEach((item, index) => {
  124.                                         for (let key in item) {
  125.                                                 if (item[key] === null) item[key] = '';
  126.                                         }
  127.                                         item.index = index + 1;
  128.                                 });
  129.                                 let tableData = totalQuotationData.commercialQuotationVersionWorkstationList;
  130.                                 workSheet.addRows(tableData);
  131.                                 // 设置第14行到数据结束 行的所有单元格的样式
  132.                                 workSheet.eachRow((row, rowIndex) => {
  133.                                         // 循环每一行
  134.                                         if (rowIndex === 14) {
  135.                                                 row.eachCell((cell, colIndex) => {
  136.                                                         cell.font = { size: 11, bold: true };
  137.                                                         cell.alignment = {
  138.                                                                 vertical: 'middle', // 垂直居中
  139.                                                                 horizontal: 'center', // 水平居中
  140.                                                                 wrapText: true // 自动换行
  141.                                                         };
  142.                                                 });
  143.                                         }
  144.                                         if (rowIndex > 14 && rowIndex <= 14 + tableData.length) {
  145.                                                 row.height = 17;
  146.                                                 row.eachCell((cell, colIndex) => {
  147.                                                         cell.font = { size: 11 };
  148.                                                         cell.alignment = {
  149.                                                                 vertical: 'middle', // 垂直居中
  150.                                                                 horizontal: 'center', // 水平居中
  151.                                                                 wrapText: true // 自动换行
  152.                                                         };
  153.                                                 });
  154.                                         }
  155.                                 });
  156.                                 // =======================================最下方合计部分 ============================================
  157.                                 // ======================================= 成本小计行 ==========================================
  158.                                 let rowNUM = 15 + tableData.length; // 从第几行开始
  159.                                 workSheet.addRow();
  160.                                 workSheet.mergeCells(`A${rowNUM}:C${rowNUM}`);
  161.                                 workSheet.getCell(`A${rowNUM}`).value = '成本小计';
  162.                                 //         下面是 成本小计行的数据
  163.                                 workSheet.getCell(`D${rowNUM}`).value = totalQuotationData.mechanicalMaterialsAndProcessingCosts_TotalCost || '';
  164.                                 workSheet.getCell(`E${rowNUM}`).value = totalQuotationData.mechanicalPurchaseCost_TotalCost || '';
  165.                                 workSheet.getCell(`F${rowNUM}`).value = totalQuotationData.electricalpurchaseCost_TotalCost || '';
  166.                                 workSheet.getCell(`G${rowNUM}`).value = totalQuotationData.industrialControlCost_TotalCost || '';
  167.                                 workSheet.getCell(`H${rowNUM}`).value = totalQuotationData.totalHardwareCost_TotalCost || '';
  168.                                 workSheet.getCell(`I${rowNUM}`).value = totalQuotationData.laborCost_TotalCost || '';
  169.                                 workSheet.getCell(`J${rowNUM}`).value = totalQuotationData.travelAndAccommodationCost_TotalCost || '';
  170.                                 workSheet.getCell(`K${rowNUM}`).value = totalQuotationData.transportationAndOtherMaterialCosts_TotalCost || '';
  171.                                 workSheet.getCell(`L${rowNUM}`).value = totalQuotationData.totalCost || '';
  172.                                 workSheet.getCell(`M${rowNUM}`).value = totalQuotationData.costSubtotal_Remarks || '';
  173.                                 // 设置成本小计样式
  174.                                 workSheet.eachRow((row, rowIndex) => {
  175.                                         if (rowIndex === rowNUM) {
  176.                                                 row.eachCell((cell, colIndex) => {
  177.                                                         cell.font = { size: 11 };
  178.                                                         cell.alignment = {
  179.                                                                 vertical: 'middle', // 垂直居中
  180.                                                                 horizontal: 'center', // 水平居中
  181.                                                                 wrapText: true // 自动换行
  182.                                                         };
  183.                                                         // 除备注列外,其他列设置颜色
  184.                                                         if (cell._address.indexOf('M') < 0) {
  185.                                                                 cell.fill = {
  186.                                                                         type: 'pattern',
  187.                                                                         pattern: 'solid',
  188.                                                                         fgColor: { argb: 'F8CBAD' } // 设置背景色
  189.                                                                 };
  190.                                                         }
  191.                                                 });
  192.                                                 row.height = 17;
  193.                                         }
  194.                                 });
  195.                                 // =================================================== 其他合计行 ===================================================
  196.                                 let otherSunRow = [
  197.                                         {
  198.                                                 name: '成本合计(未税)/ 元',
  199.                                                 prop: 'totalCost',
  200.                                                 remark: 'totalCost_Remarks'
  201.                                         },
  202.                                         {
  203.                                                 name: '管理费 / 元:',
  204.                                                 prop: 'managementFee_TotalCost',
  205.                                                 remark: 'managementFee_Remarks'
  206.                                         },
  207.                                         {
  208.                                                 name: '财务费 / 元:',
  209.                                                 prop: 'financialFee_TotalCost',
  210.                                                 remark: 'financialFee_Remarks'
  211.                                         },
  212.                                         {
  213.                                                 name: '利润 / 元:',
  214.                                                 prop: 'profit_TotalCost',
  215.                                                 remark: 'profit_Remarks'
  216.                                         },
  217.                                         {
  218.                                                 name: '价格合计(未税)/ 元:',
  219.                                                 prop: 'totalPriceExcludingTax_TotalCost',
  220.                                                 remark: 'totalPriceExcludingTax_Remarks'
  221.                                         },
  222.                                         {
  223.                                                 name: '增值税 / 元:',
  224.                                                 prop: 'valueAddedTax_TotalCost',
  225.                                                 remark: 'valueAddedTax_Remarks'
  226.                                         },
  227.                                         {
  228.                                                 name: '价格合计(含税)/ 元:',
  229.                                                 prop: 'totalPriceIncludingTax_TotalCost',
  230.                                                 remark: 'totalPriceIncludingTax_Remarks'
  231.                                         },
  232.                                         {
  233.                                                 name: '优惠后价格(含税)/ 元:',
  234.                                                 prop: 'discountedPrice',
  235.                                                 remark: 'discountedPrice_Remarks'
  236.                                         },
  237.                                         {
  238.                                                 name: '针对此次报价的其他说明',
  239.                                                 prop: 'remarks',
  240.                                                 remark: 'remarks'
  241.                                         }
  242.                                 ];
  243.                                 // 如果没有优惠后价格就不显示
  244.                                 let havePrice = true;
  245.                                 if (totalQuotationData.discountedPrice === null || totalQuotationData.discountedPrice === '' || totalQuotationData.discountedPrice === undefined) {
  246.                                         havePrice = false;
  247.                                         otherSunRow = otherSunRow.filter((item) => {
  248.                                                 return item.prop !== 'discountedPrice';
  249.                                         });
  250.                                 }
  251.                                 // 插入数据
  252.                                 let otherNum = rowNUM + 1;
  253.                                 for (let oi = 0; oi < otherSunRow.length; oi++) {
  254.                                         workSheet.addRow();
  255.                                         workSheet.mergeCells(`A${oi + otherNum}:C${oi + otherNum}`);
  256.                                         workSheet.getCell(`A${oi + otherNum}`).value = otherSunRow[oi].name || '';
  257.                                         if (oi === otherSunRow.length - 1) {
  258.                                                 workSheet.mergeCells(`D${oi + otherNum}:M${oi + otherNum}`);
  259.                                         } else {
  260.                                                 workSheet.mergeCells(`D${oi + otherNum}:L${oi + otherNum}`);
  261.                                         }
  262.                                         workSheet.getCell(`D${oi + otherNum}`).value = totalQuotationData[otherSunRow[oi].prop] || '';
  263.                                         workSheet.getCell(`M${oi + otherNum}`).value = totalQuotationData[otherSunRow[oi].remark] || '';
  264.                                 }
  265.                                 // 设置其他合计样式
  266.                                 workSheet.eachRow((row, rowIndex) => {
  267.                                         if (rowIndex > rowNUM && rowIndex < rowNUM + otherSunRow.length + 1) {
  268.                                                 if (rowIndex === rowNUM + 6) {
  269.                                                         row.height = 17;
  270.                                                         // 增值税
  271.                                                         row.eachCell((cell, colIndex) => {
  272.                                                                 cell.font = { size: 11 };
  273.                                                                 cell.alignment = {
  274.                                                                         vertical: 'middle', // 垂直居中
  275.                                                                         horizontal: 'center', // 水平居中
  276.                                                                         wrapText: true // 自动换行
  277.                                                                 };
  278.                                                                 // 除备注列外,其他列设置颜色
  279.                                                                 if (cell._address.indexOf('M') < 0) {
  280.                                                                         cell.fill = {
  281.                                                                                 type: 'pattern',
  282.                                                                                 pattern: 'solid',
  283.                                                                                 fgColor: { argb: '9BC2E6' } // 设置背景色
  284.                                                                         };
  285.                                                                 }
  286.                                                         });
  287.                                                 } else if (rowIndex === rowNUM + 7 || (havePrice ? rowIndex === rowNUM + 8 : false)) {
  288.                                                         row.height = 17;
  289.                                                         // 价税合计 、优惠后价格
  290.                                                         row.eachCell((cell, colIndex) => {
  291.                                                                 cell.font = { size: 11 };
  292.                                                                 cell.alignment = {
  293.                                                                         vertical: 'middle', // 垂直居中
  294.                                                                         horizontal: 'center', // 水平居中
  295.                                                                         wrapText: true // 自动换行
  296.                                                                 };
  297.                                                                 if (cell._address.indexOf('M') < 0) {
  298.                                                                         cell.fill = {
  299.                                                                                 type: 'pattern',
  300.                                                                                 pattern: 'solid',
  301.                                                                                 fgColor: { argb: 'FFD966' } // 设置背景色
  302.                                                                         };
  303.                                                                 }
  304.                                                         });
  305.                                                 } else if (havePrice ? rowIndex === rowNUM + 9 : rowIndex === rowNUM + 8) {
  306.                                                         row.height = 17;
  307.                                                         // 最后的其他说明
  308.                                                         row.eachCell((cell, colIndex) => {
  309.                                                                 cell.font = { size: 11, bold: true };
  310.                                                                 cell.alignment = {
  311.                                                                         vertical: 'middle', // 垂直居中
  312.                                                                         horizontal: 'center', // 水平居中
  313.                                                                         wrapText: true // 自动换行
  314.                                                                 };
  315.                                                                 cell.fill = {
  316.                                                                         type: 'pattern',
  317.                                                                         pattern: 'solid',
  318.                                                                         fgColor: { argb: 'A9D08E' } // 设置背景色
  319.                                                                 };
  320.                                                         });
  321.                                                 } else {
  322.                                                         row.height = 17;
  323.                                                         row.eachCell((cell, colIndex) => {
  324.                                                                 cell.font = { size: 11 };
  325.                                                                 cell.alignment = {
  326.                                                                         vertical: 'middle', // 垂直居中
  327.                                                                         horizontal: 'center', // 水平居中
  328.                                                                         wrapText: true // 自动换行
  329.                                                                 };
  330.                                                                 if (cell._address.indexOf('M') < 0) {
  331.                                                                         cell.fill = {
  332.                                                                                 type: 'pattern',
  333.                                                                                 pattern: 'solid',
  334.                                                                                 fgColor: { argb: 'F8CBAD' } // 设置背景色
  335.                                                                         };
  336.                                                                 }
  337.                                                         });
  338.                                                 }
  339.                                         }
  340.                                 });
  341.                                 // 将logo放入第一行 放到最后就行啦
  342.                                 // 获取图片的 Blob 数据
  343.                                 const base64 = await this.imageToBase64();
  344.                                 // 把base64编码的图片插入excel工作簿里面
  345.                                 const imageId = workbook.addImage({
  346.                                         base64: base64,
  347.                                         extension: 'png'
  348.                                 });
  349.                                 // 当前工作表(当前excel页)加入图片,tl.col:excel第几列,tl.row:excel第几行,ext里面表示图片宽高
  350.                                 workSheet.addImage(imageId, {
  351.                                         tl: { col: 0.1, row: 0.1 },
  352.                                         // br: { col: columns.length + ai - 11.1, row: ri + 2 }
  353.                                         ext: { width: 100, height: 85 }
  354.                                 });
  355.                                 // 调整所有列的宽度
  356.                                 workSheet.columns.forEach((column) => {
  357.                                         column.width = 17; // 将宽度设为20个字符
  358.                                 });
  359.                                 // 定义边框样式
  360.                                 const borderStyle = {
  361.                                         top: { style: 'thin' },
  362.                                         left: { style: 'thin' },
  363.                                         bottom: { style: 'thin' },
  364.                                         right: { style: 'thin' }
  365.                                 };
  366.                                 // 遍历工作表中的所有单元格并添加边框
  367.                                 workSheet.eachRow((row, rowIndex) => {
  368.                                         row.eachCell((cell, colIndex) => {
  369.                                                 cell.border = borderStyle;
  370.                                         });
  371.                                 });
  372.                                 // =================================== 工位 Sheet =======================================
  373.                                 var that = this;
  374.                                 async function getData() {
  375.                                         let details = totalQuotationData.commercialQuotationVersionWorkstationList; // 这是所有工位
  376.                                         for (let i = 0; i < details.length; i++) {
  377.                                                 let spara = {
  378.                                                         CommercialQuotationVersionWorkstationId: details[i].commercialQuotationVersionWorkstationId
  379.                                                 };
  380.                                                 let sres = await GetCommercialQuotationVersionWorkstation(spara);
  381.                                                 console.log('工位', sres);
  382.                                                 let tableData = sres.response;
  383.                                                 // 创建工位的工作表
  384.                                                 let sworkSheet = workbook.addWorksheet(details[i].inquiryStationCode);
  385.                                                 //======================================= 第一行 =================================
  386.                                                 // 合并A1到L1的单元格 (大标题)
  387.                                                 sworkSheet.mergeCells('A1:L1');
  388.                                                 const cell = sworkSheet.getCell('A1');
  389.                                                 cell.value = 'ChangChun HeXin Mechanical Manufacturing CO., LTD. - Quotation \n 长春合心机械制造有限公司 - 报价单';
  390.                                                 // 设置第一行的单元格样式
  391.                                                 cell.font = { size: 16, bold: true, name: '仿宋' }; // 设置字体大小为16,加粗,仿宋
  392.                                                 cell.alignment = {
  393.                                                         vertical: 'middle', // 垂直居中
  394.                                                         horizontal: 'center', // 水平居中
  395.                                                         wrapText: true // 自动换行
  396.                                                 };
  397.                                                 // 调整第一行的高度
  398.                                                 sworkSheet.getRow(1).height = 70;
  399.                                                 // ==================================== 第二 到 第十二行 ================= 样式差不多,一起搞
  400.                                                 for (let ri = 2; ri < 14; ri++) {
  401.                                                         // 创建第ri行
  402.                                                         sworkSheet.addRow(ri);
  403.                                                         // 合并单元格
  404.                                                         sworkSheet.mergeCells(`A${ri}:C${ri}`);
  405.                                                         sworkSheet.mergeCells(`D${ri}:F${ri}`);
  406.                                                         sworkSheet.mergeCells(`G${ri}:I${ri}`);
  407.                                                         sworkSheet.mergeCells(`J${ri}:L${ri}`);
  408.                                                         // A列的标题数据
  409.                                                         let headerCellA = sworkSheet.getCell(`A${ri}`);
  410.                                                         headerCellA.value = that.excelHeader[(ri - 2) * 2].label;
  411.                                                         headerCellA.alignment = {
  412.                                                                 vertical: 'middle' // 垂直居中
  413.                                                         };
  414.                                                         if (ri <= 10) {
  415.                                                                 headerCellA.font = { size: 11, name: '仿宋' };
  416.                                                         } else {
  417.                                                                 headerCellA.font = { size: 11, name: '仿宋', bold: true, color: { argb: 'FF0000' } };
  418.                                                         }
  419.                                                         // D列
  420.                                                         let headerCellD = sworkSheet.getCell(`D${ri}`);
  421.                                                         if (ri > 10) {
  422.                                                                 headerCellD.fill = {
  423.                                                                         type: 'pattern',
  424.                                                                         pattern: 'solid',
  425.                                                                         fgColor: { argb: 'FFD966' } // 设置背景色
  426.                                                                 };
  427.                                                         }
  428.                                                         headerCellD.alignment = {
  429.                                                                 vertical: 'middle', // 垂直居中
  430.                                                                 horizontal: 'center', // 水平居中
  431.                                                                 wrapText: true // 自动换行
  432.                                                         };
  433.                                                         // G列
  434.                                                         let headerCellG = sworkSheet.getCell(`G${ri}`);
  435.                                                         headerCellG.value = that.excelHeader[(ri - 1) * 2 - 1].label;
  436.                                                         headerCellG.alignment = {
  437.                                                                 vertical: 'middle' // 垂直居中
  438.                                                         };
  439.                                                         if (ri <= 10) {
  440.                                                                 headerCellG.font = { size: 11, name: '仿宋' };
  441.                                                         } else {
  442.                                                                 headerCellG.font = { size: 11, name: '仿宋', bold: true, color: { argb: 'FF0000' } };
  443.                                                         }
  444.                                                         // J列
  445.                                                         let headerCellJ = sworkSheet.getCell(`J${ri}`);
  446.                                                         if (ri > 10 && ri !== 13) {
  447.                                                                 headerCellJ.fill = {
  448.                                                                         type: 'pattern',
  449.                                                                         pattern: 'solid',
  450.                                                                         fgColor: { argb: 'FFD966' } // 设置背景色
  451.                                                                 };
  452.                                                         }
  453.                                                         headerCellJ.alignment = {
  454.                                                                 vertical: 'middle', // 垂直居中
  455.                                                                 horizontal: 'center', // 水平居中
  456.                                                                 wrapText: true // 自动换行
  457.                                                         };
  458.                                                         sworkSheet.getRow(ri).height = 15;
  459.                                                         // 获取第ri行的单元格
  460.                                                         // const cell = sworkSheet.getCell(`A${ri}`);
  461.                                                         // 设置单元格样式
  462.                                                 }
  463.                                                 // 插入表头一堆数据 row 是主表数据 totalQuotationData 是子表数据
  464.                                                 sworkSheet.getCell('D2').value = row.inquiryName; // 项目名称
  465.                                                 sworkSheet.getCell('D3').value = row.commercialQuotationNumber; // 报价单号
  466.                                                 sworkSheet.getCell('J3').value = row.creationTime; // 报价日期
  467.                                                 sworkSheet.getCell('D4').value = row.customer; // 客户名称
  468.                                                 sworkSheet.getCell('D11').value = ''; // 交费周期
  469.                                                 let string = '';
  470.                                                 that.PaymentMethod.forEach((item) => {
  471.                                                         if (item.key === totalQuotationData.paymentMethod) {
  472.                                                                 string = item.value;
  473.                                                         }
  474.                                                 });
  475.                                                 sworkSheet.getCell('J11').value = string; // 付款方式
  476.                                                 sworkSheet.getCell('D12').value = totalQuotationData.customerRequirementVersion; // 技术要求版本号
  477.                                                 sworkSheet.getCell('J12').value = totalQuotationData.versionNumber; // 报价版本号
  478.                                                 sworkSheet.getCell('D13').value = totalQuotationData.solutionVersion; // 方案版本号
  479.                                                 // ==================================== 工位的数据部分 =================================================
  480.                                                 // 标题行 ['No.','Item 项目','小时数','费率','Price 价格','备注:']
  481.                                                 sworkSheet.addRow();
  482.                                                 sworkSheet.getCell('A14').value = 'No.';
  483.                                                 sworkSheet.mergeCells(`B14:C14`);
  484.                                                 sworkSheet.getCell('B14').value = 'Item 项目';
  485.                                                 sworkSheet.getCell('D14').value = '小时数';
  486.                                                 sworkSheet.getCell('E14').value = '费率';
  487.                                                 sworkSheet.getCell('F14').value = 'Price 价格';
  488.                                                 sworkSheet.getCell('G14').value = '备注:';
  489.                                                 sworkSheet.mergeCells(`G14:L14`);
  490.                                                 // 机械材料成本
  491.                                                 sworkSheet.addRow();
  492.                                                 sworkSheet.getCell('A15').value = 1; // 序号
  493.                                                 sworkSheet.mergeCells(`B15:C15`);
  494.                                                 sworkSheet.getCell('B15').value = '机械材料成本';
  495.                                                 sworkSheet.getCell('D15').value = '/'; // 小时数
  496.                                                 sworkSheet.getCell('E15').value = '/'; // 费率
  497.                                                 sworkSheet.getCell('F15').value = ''; // 价格
  498.                                                 sworkSheet.getCell('G15').value = ''; // 备注
  499.                                                 sworkSheet.mergeCells(`G15:L15`);
  500.                                                 // 机械加工成本
  501.                                                 sworkSheet.addRow();
  502.                                                 sworkSheet.getCell('A16').value = 2;
  503.                                                 sworkSheet.mergeCells(`B16:C16`);
  504.                                                 sworkSheet.getCell('B16').value = '机械加工成本';
  505.                                                 sworkSheet.getCell('D16').value = '/'; // 小时数
  506.                                                 sworkSheet.getCell('E16').value = '/'; // 费率
  507.                                                 sworkSheet.getCell('F16').value = tableData.mechanicalMaterialsAndProcessingCosts_AfterMarkup || ''; // 价格
  508.                                                 sworkSheet.getCell('G16').value = tableData.mechanicalMaterialsAndProcessingCosts_Remarks || ''; // 备注
  509.                                                 sworkSheet.mergeCells(`G16:L16`);
  510.                                                 // 机械采购成本
  511.                                                 sworkSheet.addRow();
  512.                                                 sworkSheet.getCell('A17').value = 3;
  513.                                                 sworkSheet.mergeCells(`B17:C17`);
  514.                                                 sworkSheet.getCell('B17').value = '机械采购成本';
  515.                                                 sworkSheet.getCell('D17').value = '/'; // 小时数
  516.                                                 sworkSheet.getCell('E17').value = '/'; // 费率
  517.                                                 sworkSheet.getCell('F17').value = tableData.mechanicalPurchaseCost_AfterMarkup || ''; // 价格
  518.                                                 sworkSheet.getCell('G17').value = tableData.mechanicalPurchaseCost_Remarks || ''; // 备注
  519.                                                 sworkSheet.mergeCells(`G17:L17`);
  520.                                                 // 型材及配件
  521.                                                 sworkSheet.addRow();
  522.                                                 sworkSheet.getCell('A18').value = 4;
  523.                                                 sworkSheet.mergeCells(`B18:C18`);
  524.                                                 sworkSheet.getCell('B18').value = '型材及配件';
  525.                                                 sworkSheet.getCell('D18').value = '/'; // 小时数
  526.                                                 sworkSheet.getCell('E18').value = '/'; // 费率
  527.                                                 sworkSheet.getCell('F18').value = ''; // 价格
  528.                                                 sworkSheet.getCell('G18').value = ''; // 备注
  529.                                                 sworkSheet.mergeCells(`G18:L18`);
  530.                                                 // 电气采购成本
  531.                                                 sworkSheet.addRow();
  532.                                                 sworkSheet.getCell('A19').value = 5;
  533.                                                 sworkSheet.mergeCells(`B19:C19`);
  534.                                                 sworkSheet.getCell('B19').value = '电气采购成本';
  535.                                                 sworkSheet.getCell('D19').value = '/'; // 小时数
  536.                                                 sworkSheet.getCell('E19').value = '/'; // 费率
  537.                                                 sworkSheet.getCell('F19').value = tableData.electricalpurchaseCost_AfterMarkup || ''; // 价格
  538.                                                 sworkSheet.getCell('G19').value = tableData.electricalpurchaseCost_Remarks || ''; // 备注
  539.                                                 sworkSheet.mergeCells(`G19:L19`);
  540.                                                 // 机械设计费
  541.                                                 sworkSheet.addRow();
  542.                                                 sworkSheet.getCell('A20').value = 6;
  543.                                                 sworkSheet.mergeCells(`B20:C20`);
  544.                                                 sworkSheet.getCell('B20').value = '机械设计费';
  545.                                                 sworkSheet.getCell('D20').value = tableData.mechanicalDesignFee_Hours || ''; // 小时数
  546.                                                 sworkSheet.getCell('E20').value = tableData.mechanicalDesignFee_PerHourRate || ''; // 费率
  547.                                                 sworkSheet.getCell('F20').value = tableData.mechanicalDesignFee_TotalCost || ''; // 价格
  548.                                                 sworkSheet.getCell('G20').value = tableData.mechanicalDesignFee_Remarks || ''; // 备注
  549.                                                 sworkSheet.mergeCells(`G20:L20`);
  550.                                                 // 电气设计费
  551.                                                 sworkSheet.addRow();
  552.                                                 sworkSheet.getCell('A21').value = 7;
  553.                                                 sworkSheet.mergeCells(`B21:C21`);
  554.                                                 sworkSheet.getCell('B21').value = '电气设计费';
  555.                                                 sworkSheet.getCell('D21').value = tableData.electricalDesignFee_Hours || ''; // 小时数
  556.                                                 sworkSheet.getCell('E21').value = tableData.electricalDesignFee_PerHourRate || ''; // 费率
  557.                                                 sworkSheet.getCell('F21').value = tableData.electricalDesignFee_TotalCost || ''; // 价格
  558.                                                 sworkSheet.getCell('G21').value = tableData.electricalDesignFee_Remarks || ''; // 备注
  559.                                                 sworkSheet.mergeCells(`G21:L21`);
  560.                                                 // 软件编程及开发
  561.                                                 sworkSheet.addRow();
  562.                                                 sworkSheet.getCell('A22').value = 8;
  563.                                                 sworkSheet.mergeCells(`B22:C22`);
  564.                                                 sworkSheet.getCell('B22').value = '软件编程及开发';
  565.                                                 sworkSheet.getCell('D22').value = tableData.softwareProgramming_Hours || ''; // 小时数
  566.                                                 sworkSheet.getCell('E22').value = tableData.softwareProgramming_PerHourRate || ''; // 费率
  567.                                                 sworkSheet.getCell('F22').value = tableData.softwareProgramming_TotalCost || ''; // 价格
  568.                                                 sworkSheet.getCell('G22').value = tableData.softwareProgramming_Remarks || ''; // 备注
  569.                                                 sworkSheet.mergeCells(`G22:L22`);
  570.                                                 // 机器人调试
  571.                                                 sworkSheet.addRow();
  572.                                                 sworkSheet.getCell('A23').value = 9;
  573.                                                 sworkSheet.mergeCells(`B23:C23`);
  574.                                                 sworkSheet.getCell('B23').value = '机器人调试';
  575.                                                 sworkSheet.getCell('D23').value = tableData.robotDebugging_Hours || ''; // 小时数
  576.                                                 sworkSheet.getCell('E23').value = tableData.robotDebugging_PerHourRate || ''; // 费率
  577.                                                 sworkSheet.getCell('F23').value = tableData.robotDebugging_TotalCost || ''; // 价格
  578.                                                 sworkSheet.getCell('G23').value = tableData.robotDebugging_Remarks || ''; // 备注
  579.                                                 sworkSheet.mergeCells(`G23:L23`);
  580.                                                 // 项目经理费用
  581.                                                 sworkSheet.addRow();
  582.                                                 sworkSheet.getCell('A24').value = 10;
  583.                                                 sworkSheet.mergeCells(`B24:C24`);
  584.                                                 sworkSheet.getCell('B24').value = '项目经理费用';
  585.                                                 sworkSheet.getCell('D24').value = tableData.projectManagerFee_Hours || ''; // 小时数
  586.                                                 sworkSheet.getCell('E24').value = tableData.projectManagerFee_PerHourRate || ''; // 费率
  587.                                                 sworkSheet.getCell('F24').value = tableData.projectManagerFee_TotalCost || ''; // 价格
  588.                                                 sworkSheet.getCell('G24').value = tableData.projectManagerFee_Remarks || ''; // 备注
  589.                                                 sworkSheet.mergeCells(`G24:L24`);
  590.                                                 // 机械安装调试费用
  591.                                                 sworkSheet.addRow();
  592.                                                 sworkSheet.getCell('A25').value = 11;
  593.                                                 sworkSheet.mergeCells(`B25:C25`);
  594.                                                 sworkSheet.getCell('B25').value = '机械安装调试费用';
  595.                                                 sworkSheet.getCell('D25').value = tableData.mechanicalInstallationDebugging_Hours || ''; // 小时数
  596.                                                 sworkSheet.getCell('E25').value = tableData.mechanicalInstallationDebugging_PerHourRate || ''; // 费率
  597.                                                 sworkSheet.getCell('F25').value = tableData.mechanicalInstallationDebugging_TotalCost || ''; // 价格
  598.                                                 sworkSheet.getCell('G25').value = tableData.mechanicalInstallationDebugging_Remarks || ''; // 备注
  599.                                                 sworkSheet.mergeCells(`G25:L25`);
  600.                                                 // 电气安装调试费用
  601.                                                 sworkSheet.addRow();
  602.                                                 sworkSheet.getCell('A26').value = 12;
  603.                                                 sworkSheet.mergeCells(`B26:C26`);
  604.                                                 sworkSheet.getCell('B26').value = '电气安装调试费用';
  605.                                                 sworkSheet.getCell('D26').value = tableData.electricalInstallationDebugging_Hours || ''; // 小时数
  606.                                                 sworkSheet.getCell('E26').value = tableData.electricalInstallationDebugging_PerHourRate || ''; // 费率
  607.                                                 sworkSheet.getCell('F26').value = tableData.electricalInstallationDebugging_TotalCost || ''; // 价格
  608.                                                 sworkSheet.getCell('G26').value = tableData.electricalInstallationDebugging_Remarks || ''; // 备注
  609.                                                 sworkSheet.mergeCells(`G26:L26`);
  610.                                                 // 现场调试服务费
  611.                                                 sworkSheet.addRow();
  612.                                                 sworkSheet.getCell('A27').value = 13;
  613.                                                 sworkSheet.mergeCells(`B27:C27`);
  614.                                                 sworkSheet.getCell('B27').value = '现场调试服务费';
  615.                                                 sworkSheet.getCell('D27').value = tableData.onSiteDebuggingService_Hours || ''; // 小时数
  616.                                                 sworkSheet.getCell('E27').value = tableData.onSiteDebuggingService_PerHourRate || ''; // 费率
  617.                                                 sworkSheet.getCell('F27').value = tableData.onSiteDebuggingService_TotalCost || ''; // 价格
  618.                                                 sworkSheet.getCell('G27').value = tableData.onSiteDebuggingService_Remarks || ''; // 备注
  619.                                                 sworkSheet.mergeCells(`G27:L27`);
  620.                                                 // 售后服务费
  621.                                                 sworkSheet.addRow();
  622.                                                 sworkSheet.getCell('A28').value = 14;
  623.                                                 sworkSheet.mergeCells(`B28:C28`);
  624.                                                 sworkSheet.getCell('B28').value = '售后服务费';
  625.                                                 sworkSheet.getCell('D28').value = tableData.afterSalesService_Hours || ''; // 小时数
  626.                                                 sworkSheet.getCell('E28').value = tableData.afterSalesService_PerHourRate || ''; // 费率
  627.                                                 sworkSheet.getCell('F28').value = tableData.afterSalesService_TotalCost || ''; // 价格
  628.                                                 sworkSheet.getCell('G28').value = tableData.afterSalesService_Remarks || ''; // 备注
  629.                                                 sworkSheet.mergeCells(`G28:L28`);
  630.                                                 // 包装及运输费用
  631.                                                 sworkSheet.addRow();
  632.                                                 sworkSheet.getCell('A29').value = 15;
  633.                                                 sworkSheet.mergeCells(`B29:C29`);
  634.                                                 sworkSheet.getCell('B29').value = '包装及运输费用';
  635.                                                 sworkSheet.getCell('D29').value = '/'; // 小时数
  636.                                                 sworkSheet.getCell('E29').value = '/'; // 费率
  637.                                                 sworkSheet.getCell('F29').value = tableData.shippingPackagingCost_AfterMarkup || ''; // 价格
  638.                                                 sworkSheet.getCell('G29').value = tableData.shippingPackagingCost_Remarks || ''; // 备注
  639.                                                 sworkSheet.mergeCells(`G29:L29`);
  640.                                                 // 差旅费
  641.                                                 sworkSheet.addRow();
  642.                                                 sworkSheet.getCell('A30').value = 16;
  643.                                                 sworkSheet.mergeCells(`B30:C30`);
  644.                                                 sworkSheet.getCell('B30').value = '差旅费';
  645.                                                 sworkSheet.getCell('D30').value = '/'; // 小时数
  646.                                                 sworkSheet.getCell('E30').value = '/'; // 费率
  647.                                                 sworkSheet.getCell('F30').value = tableData.travelAndAccommodationCost_AfterMarkup || ''; // 价格
  648.                                                 sworkSheet.getCell('G30').value = tableData.travelAndAccommodationCost_Remarks || ''; // 备注
  649.                                                 sworkSheet.mergeCells(`G30:L30`);
  650.                                                 // 资料费
  651.                                                 sworkSheet.addRow();
  652.                                                 sworkSheet.getCell('A31').value = 17;
  653.                                                 sworkSheet.mergeCells(`B31:C31`);
  654.                                                 sworkSheet.getCell('B31').value = '资料费';
  655.                                                 sworkSheet.getCell('D31').value = '/'; // 小时数
  656.                                                 sworkSheet.getCell('E31').value = '/'; // 费率
  657.                                                 sworkSheet.getCell('F31').value = tableData.documentCost_AfterMarkup || ''; // 价格
  658.                                                 sworkSheet.getCell('G31').value = tableData.documentCost_Remarks || ''; // 备注
  659.                                                 sworkSheet.mergeCells(`G31:L31`);
  660.                                                 // 成本合计(小结)
  661.                                                 sworkSheet.addRow();
  662.                                                 sworkSheet.getCell('A32').value = 18;
  663.                                                 sworkSheet.mergeCells(`B32:C32`);
  664.                                                 sworkSheet.getCell('B32').value = '成本合计(小结)';
  665.                                                 sworkSheet.getCell('D32').value = '/'; // 小时数
  666.                                                 sworkSheet.getCell('E32').value = '/'; // 费率
  667.                                                 sworkSheet.getCell('F32').value = tableData.totalCost || ''; // 价格
  668.                                                 sworkSheet.getCell('G32').value = ''; // 备注
  669.                                                 sworkSheet.mergeCells(`G32:L32`);
  670.                                                 // 管理费
  671.                                                 sworkSheet.addRow();
  672.                                                 sworkSheet.getCell('A33').value = 19;
  673.                                                 sworkSheet.mergeCells(`B33:C33`);
  674.                                                 sworkSheet.getCell('B33').value = '管理费';
  675.                                                 sworkSheet.getCell('D33').value = '/'; // 小时数
  676.                                                 sworkSheet.getCell('E33').value = '/'; // 费率
  677.                                                 sworkSheet.getCell('F33').value = tableData.managementFee || ''; // 价格
  678.                                                 sworkSheet.getCell('G33').value = ''; // 备注
  679.                                                 sworkSheet.mergeCells(`G33:L33`);
  680.                                                 // 财务费
  681.                                                 sworkSheet.addRow();
  682.                                                 sworkSheet.getCell('A34').value = 20;
  683.                                                 sworkSheet.mergeCells(`B34:C34`);
  684.                                                 sworkSheet.getCell('B34').value = '财务费';
  685.                                                 sworkSheet.getCell('D34').value = '/'; // 小时数
  686.                                                 sworkSheet.getCell('E34').value = '/'; // 费率
  687.                                                 sworkSheet.getCell('F34').value = tableData.financialFee || ''; // 价格
  688.                                                 sworkSheet.getCell('G34').value = ''; // 备注
  689.                                                 sworkSheet.mergeCells(`G34:L34`);
  690.                                                 // 利润
  691.                                                 sworkSheet.addRow();
  692.                                                 sworkSheet.getCell('A35').value = 21;
  693.                                                 sworkSheet.mergeCells(`B35:C35`);
  694.                                                 sworkSheet.getCell('B35').value = '利润';
  695.                                                 sworkSheet.getCell('D35').value = '/'; // 小时数
  696.                                                 sworkSheet.getCell('E35').value = '/'; // 费率
  697.                                                 sworkSheet.getCell('F35').value = tableData.profit || ''; // 价格
  698.                                                 sworkSheet.getCell('G35').value = ''; // 备注
  699.                                                 sworkSheet.mergeCells(`G35:L35`);
  700.                                                 // 价格合计(未税)
  701.                                                 sworkSheet.addRow();
  702.                                                 sworkSheet.getCell('A36').value = 22;
  703.                                                 sworkSheet.mergeCells(`B36:C36`);
  704.                                                 sworkSheet.getCell('B36').value = '价格合计(未税)';
  705.                                                 sworkSheet.getCell('D36').value = '/'; // 小时数
  706.                                                 sworkSheet.getCell('E36').value = '/'; // 费率
  707.                                                 sworkSheet.getCell('F36').value = tableData.totalPriceExcludingTax || ''; // 价格
  708.                                                 sworkSheet.getCell('G36').value = ''; // 备注
  709.                                                 sworkSheet.mergeCells(`G36:L36`);
  710.                                                 // 增值税
  711.                                                 sworkSheet.addRow();
  712.                                                 sworkSheet.getCell('A37').value = 23;
  713.                                                 sworkSheet.mergeCells(`B37:C37`);
  714.                                                 sworkSheet.getCell('B37').value = '增值税';
  715.                                                 sworkSheet.getCell('D37').value = '/'; // 小时数
  716.                                                 sworkSheet.getCell('E37').value = '/'; // 费率
  717.                                                 sworkSheet.getCell('F37').value = tableData.valueAddedTax || ''; // 价格
  718.                                                 sworkSheet.getCell('G37').value = ''; // 备注
  719.                                                 sworkSheet.mergeCells(`G37:L37`);
  720.                                                 // 价格合计(含税)
  721.                                                 sworkSheet.addRow();
  722.                                                 sworkSheet.getCell('A38').value = 24;
  723.                                                 sworkSheet.mergeCells(`B38:C38`);
  724.                                                 sworkSheet.getCell('B38').value = '价格合计(含税)';
  725.                                                 sworkSheet.getCell('D38').value = '/'; // 小时数
  726.                                                 sworkSheet.getCell('E38').value = '/'; // 费率
  727.                                                 sworkSheet.getCell('F38').value = tableData.valueAddedTax || ''; // 价格
  728.                                                 sworkSheet.getCell('G38').value = ''; // 备注
  729.                                                 sworkSheet.mergeCells(`G38:L38`);
  730.                                                 // 数据行统一样式处理
  731.                                                 sworkSheet.eachRow((row, rowIndex) => {
  732.                                                         // 循环每一行
  733.                                                         if (rowIndex >= 14 && rowIndex <= 38) {
  734.                                                                 if (rowIndex === 14) {
  735.                                                                         // 标题行
  736.                                                                         row.eachCell((cell, colIndex) => {
  737.                                                                                 console.log('cell', cell);
  738.                                                                                 cell.alignment = {
  739.                                                                                         vertical: 'middle', // 垂直居中
  740.                                                                                         horizontal: 'center', // 水平居中
  741.                                                                                         wrapText: true // 自动换行
  742.                                                                                 };
  743.                                                                                 cell.font = { size: 11, bold: true };
  744.                                                                                 if (cell._address === 'D14' || cell._address === 'E14') {
  745.                                                                                         cell.fill = {
  746.                                                                                                 type: 'pattern',
  747.                                                                                                 pattern: 'solid',
  748.                                                                                                 fgColor: { argb: '00B0F0' } // 设置背景色
  749.                                                                                         };
  750.                                                                                 }
  751.                                                                         });
  752.                                                                 } else if (rowIndex >= 20 && rowIndex <= 28) {
  753.                                                                         // 从机械设计 到 售后服务行
  754.                                                                         row.eachCell((cell, colIndex) => {
  755.                                                                                 console.log('cell', cell);
  756.                                                                                 cell.font = { size: 11 };
  757.                                                                                 cell.alignment = {
  758.                                                                                         vertical: 'middle', // 垂直居中
  759.                                                                                         horizontal: 'center', // 水平居中
  760.                                                                                         wrapText: true // 自动换行
  761.                                                                                 };
  762.                                                                                 if (cell._address.indexOf('B') > -1 || cell._address.indexOf('F') > -1) {
  763.                                                                                         cell.fill = {
  764.                                                                                                 type: 'pattern',
  765.                                                                                                 pattern: 'solid',
  766.                                                                                                 fgColor: { argb: 'D9E1F2' } // 设置背景色
  767.                                                                                         };
  768.                                                                                 }
  769.                                                                                 if (cell._address.indexOf('D') > -1 || cell._address.indexOf('E') > -1) {
  770.                                                                                         cell.fill = {
  771.                                                                                                 type: 'pattern',
  772.                                                                                                 pattern: 'solid',
  773.                                                                                                 fgColor: { argb: '00B0F0' } // 设置背景色
  774.                                                                                         };
  775.                                                                                 }
  776.                                                                         });
  777.                                                                 } else if (rowIndex === 32) {
  778.                                                                         row.eachCell((cell, colIndex) => {
  779.                                                                                 console.log('cell', cell);
  780.                                                                                 cell.font = { size: 11 };
  781.                                                                                 cell.alignment = {
  782.                                                                                         vertical: 'middle', // 垂直居中
  783.                                                                                         horizontal: 'center', // 水平居中
  784.                                                                                         wrapText: true // 自动换行
  785.                                                                                 };
  786.                                                                                 if (cell._address.indexOf('B') > -1 || cell._address.indexOf('F') > -1) {
  787.                                                                                         cell.fill = {
  788.                                                                                                 type: 'pattern',
  789.                                                                                                 pattern: 'solid',
  790.                                                                                                 fgColor: { argb: 'E2EFDA' } // 设置背景色
  791.                                                                                         };
  792.                                                                                 }
  793.                                                                         });
  794.                                                                 } else if (rowIndex === 36) {
  795.                                                                         row.eachCell((cell, colIndex) => {
  796.                                                                                 console.log('cell', cell);
  797.                                                                                 cell.font = { size: 11 };
  798.                                                                                 cell.alignment = {
  799.                                                                                         vertical: 'middle', // 垂直居中
  800.                                                                                         horizontal: 'center', // 水平居中
  801.                                                                                         wrapText: true // 自动换行
  802.                                                                                 };
  803.                                                                                 if (cell._address.indexOf('B') > -1 || cell._address.indexOf('F') > -1) {
  804.                                                                                         cell.fill = {
  805.                                                                                                 type: 'pattern',
  806.                                                                                                 pattern: 'solid',
  807.                                                                                                 fgColor: { argb: 'C6E0B4' } // 设置背景色
  808.                                                                                         };
  809.                                                                                 }
  810.                                                                         });
  811.                                                                 } else if (rowIndex === 38) {
  812.                                                                         row.eachCell((cell, colIndex) => {
  813.                                                                                 console.log('cell', cell);
  814.                                                                                 cell.font = { size: 11 };
  815.                                                                                 cell.alignment = {
  816.                                                                                         vertical: 'middle', // 垂直居中
  817.                                                                                         horizontal: 'center', // 水平居中
  818.                                                                                         wrapText: true // 自动换行
  819.                                                                                 };
  820.                                                                                 if (cell._address.indexOf('B') > -1 || cell._address.indexOf('F') > -1) {
  821.                                                                                         cell.fill = {
  822.                                                                                                 type: 'pattern',
  823.                                                                                                 pattern: 'solid',
  824.                                                                                                 fgColor: { argb: 'A9D08E' } // 设置背景色
  825.                                                                                         };
  826.                                                                                 }
  827.                                                                         });
  828.                                                                 } else {
  829.                                                                         row.eachCell((cell, colIndex) => {
  830.                                                                                 console.log('cell', cell);
  831.                                                                                 cell.font = { size: 11 };
  832.                                                                                 cell.alignment = {
  833.                                                                                         vertical: 'middle', // 垂直居中
  834.                                                                                         horizontal: 'center', // 水平居中
  835.                                                                                         wrapText: true // 自动换行
  836.                                                                                 };
  837.                                                                                 if (cell._address.indexOf('B') > -1 || cell._address.indexOf('F') > -1) {
  838.                                                                                         cell.fill = {
  839.                                                                                                 type: 'pattern',
  840.                                                                                                 pattern: 'solid',
  841.                                                                                                 fgColor: { argb: 'D9E1F2' } // 设置背景色
  842.                                                                                         };
  843.                                                                                 }
  844.                                                                         });
  845.                                                                 }
  846.                                                                 row.height = 17;
  847.                                                         }
  848.                                                 });
  849.                                                 // 最下方针对报价其他说明列
  850.                                                 sworkSheet.addRow();
  851.                                                 sworkSheet.mergeCells(`A39:C39`);
  852.                                                 sworkSheet.mergeCells(`D39:L39`);
  853.                                                 let remarkcell = sworkSheet.getCell('A39');
  854.                                                 remarkcell.value = '针对此次报价的其他说明:';
  855.                                                 remarkcell.font = { size: 12, bold: true };
  856.                                                 remarkcell.alignment = {
  857.                                                         vertical: 'middle', // 垂直居中
  858.                                                         horizontal: 'center', // 水平居中
  859.                                                         wrapText: true // 自动换行
  860.                                                 };
  861.                                                 remarkcell.fill = {
  862.                                                         type: 'pattern',
  863.                                                         pattern: 'solid',
  864.                                                         fgColor: { argb: 'A9D08E' } // 设置背景色
  865.                                                 };
  866.                                                 let remarkcell1 = sworkSheet.getCell('D39');
  867.                                                 remarkcell1.font = { size: 12 };
  868.                                                 remarkcell1.alignment = {
  869.                                                         vertical: 'middle', // 垂直居中
  870.                                                         horizontal: 'center', // 水平居中
  871.                                                         wrapText: true // 自动换行
  872.                                                 };
  873.                                                 remarkcell1.fill = {
  874.                                                         type: 'pattern',
  875.                                                         pattern: 'solid',
  876.                                                         fgColor: { argb: 'A9D08E' } // 设置背景色
  877.                                                 };
  878.                                                 sworkSheet.getRow(39).height = 20;
  879.                                                 // 将logo放入第一行 放到最后就行啦(复用总报价)
  880.                                                 // 前面已经加载了 imageid,这里直接用
  881.                                                 // 当前工作表(当前excel页)加入图片,tl.col:excel第几列,tl.row:excel第几行,ext里面表示图片宽高
  882.                                                 sworkSheet.addImage(imageId, {
  883.                                                         tl: { col: 0.1, row: 0.1 },
  884.                                                         // br: { col: columns.length + ai - 11.1, row: ri + 2 }
  885.                                                         ext: { width: 100, height: 85 }
  886.                                                 });
  887.                                                 // 调整所有列的宽度
  888.                                                 sworkSheet.columns.forEach((column) => {
  889.                                                         column.width = 17; // 将宽度设为20个字符
  890.                                                 });
  891.                                                 // 定义边框样式
  892.                                                 const borderStyle = {
  893.                                                         top: { style: 'thin' },
  894.                                                         left: { style: 'thin' },
  895.                                                         bottom: { style: 'thin' },
  896.                                                         right: { style: 'thin' }
  897.                                                 };
  898.                                                 // 遍历工作表中的所有单元格并添加边框
  899.                                                 sworkSheet.eachRow((row, rowIndex) => {
  900.                                                         row.eachCell((cell, colIndex) => {
  901.                                                                 cell.border = borderStyle;
  902.                                                         });
  903.                                                 });
  904.                                         }
  905.                                 }
  906.                                 await getData();
  907.                                 // 保存工作簿
  908.                                 workbook.xlsx.writeBuffer().then((buffer) => {
  909.                                         saveAs(new Blob([buffer], { type: 'application/octet-stream' }), '商务报价单导出.xlsx');
  910.                                 });
  911.                         } else {
  912.                                 this.$message(res.msg);
  913.                         }
  914.                         loading.close();
  915.                 },
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4