vue纯前端使用exceljs导出excel文件手把手教程,非官方文档直粘

夜十前端 2024-08-15 09:33:01 阅读 92

有好多私信小伙伴,问我的那篇帖子:

vue纯前端导出excel,包括列表批量导出图片、文件超链接

上篇文章只是将公司的需求代码实现粘贴了进来,对于没有使用过exceljs插件的人来说,确实是有点晦涩的,本文就按自己的理解,一步一步将exceljs插件的使用讲解一下,有不明确或理解错误的地方欢迎指出,促进我进步。

最终实现样式展示:

目录

一、exceljs的安装、引用

二、创建excel工作簿

三、创建excel工作表(sheet栏)

四、为excel工作表定义每列的数据

五、excel设置样式(合并单元格等)

六、excel的行级操作

七、遍历所有行

八、遍历所有单元格

九、向excel中插入图片

十、插入超链接 

十一、主图完整代码

一、exceljs的安装、引用

        首先执行npm i exceljs,将依赖安装到你的项目中

<code>npm i exceljs

        在vue页面中,创建一个方法,将exceljs引入

exportExcel() {

const Exceljs = require('exceljs'); // 引入exceljs

},

二、创建excel工作簿

        引入成功后,先来创建一个excel工作簿

exportExcel() {

const Exceljs = require('exceljs'); // 引入exceljs

const workbook = new Exceljs.Workbook();// 创建工作簿

},

        此时,我们增加以下内容,就会下载出一个excel文件啦。

        我用了 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是列宽

[

{

header: '姓名',

key: 'name',

width: 14

},

{

header: '年龄',

key: 'age',

width: 14

},

{

header: '性别',

key: 'sex',

width: 14

},

{

header: '生日',

key: 'birth',

width: 14

}

]

        定义表头后,插入数据:

workSheet.addRows(this.exportDataList); // 往工作表插入数据

        将代码连起来,已经可以执行啦,导出一个完整的excel

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的提示'

};

将上述操作全部用上,相信你的excel就可以任意定义啦~

十一、主图完整代码

最后,附主图的完整屎山代码,接口就不放了

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();

},



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。