Vue使用exceljs導(dǎo)出excel文件的詳細(xì)教程
最終實(shí)現(xiàn)樣式展示
一、exceljs的安裝、引用
首先執(zhí)行npm i exceljs,將依賴安裝到你的項(xiàng)目中
npm i exceljs
在vue頁面中,創(chuàng)建一個方法,將exceljs引入
exportExcel() { const Exceljs = require('exceljs'); // 引入exceljs },
二、創(chuàng)建excel工作簿
引入成功后,先來創(chuàng)建一個excel工作簿
exportExcel() { const Exceljs = require('exceljs'); // 引入exceljs const workbook = new Exceljs.Workbook();// 創(chuàng)建工作簿 },
此時,我們增加以下內(nèi)容,就會下載出一個excel文件啦。
我用了 saveAs 插件下載,安裝方式隨便搜一下,這里就不贅述了。
exportExcel() { const Exceljs = require('exceljs'); // 引入exceljs const workbook = new Exceljs.Workbook(); // 創(chuàng)建工作簿 // 下載工作簿 workbook.xlsx.writeBuffer().then((buffer) => { saveAs(new Blob([buffer], { type: 'application/octet-stream' }), '測試導(dǎo)出.xlsx');}); },
如果下載成功,說明組件引入都沒有問題,進(jìn)行下一步操作~
三、創(chuàng)建excel工作表(sheet欄)
excel是可以有多個sheet欄的,創(chuàng)建好工作簿后,下一步一定是創(chuàng)建一個工作表,也就是sheet,調(diào)用 workbook.addWorksheet('sheet欄的名字') ,必須用變量接收一下,因?yàn)楹罄m(xù)要對它進(jìn)行操作!
exportExcel() { const Exceljs = require('exceljs'); // 引入exceljs const workbook = new Exceljs.Workbook(); // 創(chuàng)建工作簿 const workSheet = workbook.addWorksheet('總報(bào)價(jià)');// 創(chuàng)建工作表(sheet1) },
四、為excel工作表定義每列的數(shù)據(jù)
exceljs支持快速定義表頭,每列的數(shù)據(jù)字段,傳入表頭配置數(shù)組,對應(yīng)的列,就會自動賦值,與 el-table 的理念差不多,前端理解后,使用非常方便。
workSheet.columns = this.exportTableProp; // 工作表添加表頭
exportTableProp的格式為:
header是表頭列名,key是每列的數(shù)據(jù)源,width是列寬
[ { header: '姓名', key: 'name', width: 14 }, { header: '年齡', key: 'age', width: 14 }, { header: '性別', key: 'sex', width: 14 }, { header: '生日', key: 'birth', width: 14 } ]
定義表頭后,插入數(shù)據(jù):
workSheet.addRows(this.exportDataList); // 往工作表插入數(shù)據(jù)
將代碼連起來,已經(jīng)可以執(zhí)行啦,導(dǎo)出一個完整的excel
exportExcel() { const Exceljs = require('exceljs'); // 引入exceljs const workbook = new Exceljs.Workbook(); // 創(chuàng)建工作簿 const workSheet = workbook.addWorksheet('sheet1');// 創(chuàng)建工作表(sheet1) workSheet.columns = this.exportTableProp; // 工作表添加表頭 workSheet.addRows(this.exportDataList);// 往工作表插入數(shù)據(jù) // 下載工作簿 workbook.xlsx.writeBuffer().then((buffer) => { saveAs(new Blob([buffer], { type: 'application/octet-stream' }), '測試導(dǎo)出.xlsx');}); },
五、excel設(shè)置樣式(合并單元格等)
exceljs提供了一系列方法,正確調(diào)用即可畫出任何樣式的excel
合并單元格:
workSheet.mergeCells('A1:M1'); //將A1到M1的單元格合并
獲取單元格:(設(shè)置樣式的前提)
const cell = workSheet.getCell('A1'); // 獲取A1單元格
設(shè)置A1單元格顯示的內(nèi)容:
cell.value = '我是A1各自的數(shù)據(jù)';
設(shè)置A1單元格的樣式:
font設(shè)置文字樣式,alignment設(shè)置格子內(nèi)文本如何顯示,fill 設(shè)置單元格背景色
cell.font = { size: 16, bold: true, name: '仿宋' }; // 設(shè)置字體大小為16,加粗,仿宋 cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wrapText: true // 自動換行 }; cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'A9D08E' } // 設(shè)置背景色 };
六、excel的行級操作
獲取第一行:
workSheet.getRow(1)
調(diào)整第一行的行高
workSheet.getRow(1).height = 70;
手動添加一行:
workSheet.addRow(); workSheet.addRow(2); workSheet.addRow(['姓名','年齡','性別']);
不傳參:在最下方加一行
傳數(shù)字:在指定列加一行
傳數(shù)組:加一行,且設(shè)置行內(nèi)數(shù)據(jù)
七、遍歷所有行
調(diào)用workSheet.eachRow 可以遍歷所有行,比如快捷設(shè)置全部行高
workSheet.eachRow((row, rowIndex) => { // 循環(huán)每一行 console.log(row) row.height = 17; });
八、遍歷所有單元格
嵌套操作,可以遍歷到全部單元格,代碼演示:
workSheet.eachRow((row, rowIndex) => { // 循環(huán)每個單元格 row.eachCell((cell, colIndex) => { cell.font = { size: 11, bold: true }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wrapText: true // 自動換行 }; }); });
當(dāng)然,也可以加判斷
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 // 自動換行 }; }); } });
來個實(shí)用案例: 為所有單元格設(shè)置邊框:
// 定義邊框樣式 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編碼圖片,直接插入就可以,如果不是,需要轉(zhuǎn)為base64
// 將logo放入第一行 const base64 = await this.imageToBase64(); // 這里是轉(zhuǎn)base64方法,不放了 // 把base64編碼的圖片插入excel工作簿里面 const imageId = workbook.addImage({ base64: base64, extension: 'png' }); // 當(dāng)前工作表(當(dāng)前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 } });
十、插入超鏈接
超鏈接一定是單元格級別的,先獲取到單元格,然后設(shè)置value即可
cell.value = { text: '要顯示的文字', hyperlink: 'www.baidu.com', tooltip: 'hover的提示' };
將上述操作全部用上,相信你的excel就可以任意定義啦~
十一、主圖完整代碼
最后,附主圖的完整屎山代碼,接口就不放了
async exportExcel(row) { const loading = this.$loading({ lock: true, text: '導(dǎo)出excel中...(若長時間無響應(yīng)請刷新頁面)', spinner: 'el-icon-loading', background: 'rgba(0, 0, 0, 0.7)' }); // 查商務(wù)報(bào)價(jià)版本 let para = { CommercialQuotationVersionId: row.commercialQuotationVersionId }; let res = await GetCommercialQuotationVersion(para); if (res.success) { let totalQuotationData = res.response; const Exceljs = require('exceljs'); // 創(chuàng)建工作簿 const workbook = new Exceljs.Workbook(); // 創(chuàng)建工作表(sheet1) const workSheet = workbook.addWorksheet('總報(bào)價(jià)'); // 表格的表頭配置 workSheet.columns = this.exportTableProp; // 工作表添加表頭 //======================================= 第一行 ================================= // 合并A1到L1的單元格 (大標(biāo)題) workSheet.mergeCells('A1:M1'); const cell = workSheet.getCell('A1'); cell.value = 'Mechanical CO., LTD. - Quotation \n - 報(bào)價(jià)單'; // 設(shè)置第一行的單元格樣式 cell.font = { size: 16, bold: true, name: '仿宋' }; // 設(shè)置字體大小為16,加粗,仿宋 cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wrapText: true // 自動換行 }; // 調(diào)整第一行的高度 workSheet.getRow(1).height = 70; // ==================================== 第二 到 第十二行 ================= 樣式差不多,一起搞 for (let ri = 2; ri < 14; ri++) { // 創(chuàng)建第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列的標(biāo)題數(shù)據(jù) 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' } // 設(shè)置背景色 }; } 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' } // 設(shè)置背景色 }; } headerCellJ.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wrapText: true // 自動換行 }; workSheet.getRow(ri).height = 15; // 獲取第ri行的單元格 // const cell = workSheet.getCell(`A${ri}`); // 設(shè)置單元格樣式 } // 插入表頭一堆數(shù)據(jù) row 是主表數(shù)據(jù) totalQuotationData 是子表數(shù)據(jù) workSheet.getCell('D2').value = row.inquiryName; // 項(xiàng)目名稱 workSheet.getCell('D3').value = row.commercialQuotationNumber; // 報(bào)價(jià)單號 workSheet.getCell('J3').value = row.creationTime; // 報(bào)價(jià)日期 workSheet.getCell('D4').value = row.customer; // 客戶名稱 workSheet.getCell('D11').value = ''; // 交費(fèi)周期 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; // 技術(shù)要求版本號 workSheet.getCell('J12').value = totalQuotationData.versionNumber; // 報(bào)價(jià)版本號 workSheet.getCell('D13').value = totalQuotationData.solutionVersion; // 方案版本號 // ================================ 數(shù)據(jù)部分行 ============================================================= workSheet.addRow( this.exportTableProp.map((item) => { return item.header; }) ); // 添加數(shù)據(jù),表頭信息已經(jīng)在最上面定好了(這里是從接口取回來的數(shù)據(jù)) 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); // 設(shè)置第14行到數(shù)據(jù)結(jié)束 行的所有單元格的樣式 workSheet.eachRow((row, rowIndex) => { // 循環(huán)每一行 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 // 自動換行 }; }); } }); // =======================================最下方合計(jì)部分 ============================================ // ======================================= 成本小計(jì)行 ========================================== let rowNUM = 15 + tableData.length; // 從第幾行開始 workSheet.addRow(); workSheet.mergeCells(`A${rowNUM}:C${rowNUM}`); workSheet.getCell(`A${rowNUM}`).value = '成本小計(jì)'; // 下面是 成本小計(jì)行的數(shù)據(jù) 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 || ''; // 設(shè)置成本小計(jì)樣式 workSheet.eachRow((row, rowIndex) => { if (rowIndex === rowNUM) { row.eachCell((cell, colIndex) => { cell.font = { size: 11 }; cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wrapText: true // 自動換行 }; // 除備注列外,其他列設(shè)置顏色 if (cell._address.indexOf('M') < 0) { cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'F8CBAD' } // 設(shè)置背景色 }; } }); row.height = 17; } }); // =================================================== 其他合計(jì)行 =================================================== let otherSunRow = [ { name: '成本合計(jì)(未稅)/ 元', prop: 'totalCost', remark: 'totalCost_Remarks' }, { name: '管理費(fèi) / 元:', prop: 'managementFee_TotalCost', remark: 'managementFee_Remarks' }, { name: '財(cái)務(wù)費(fèi) / 元:', prop: 'financialFee_TotalCost', remark: 'financialFee_Remarks' }, { name: '利潤 / 元:', prop: 'profit_TotalCost', remark: 'profit_Remarks' }, { name: '價(jià)格合計(jì)(未稅)/ 元:', prop: 'totalPriceExcludingTax_TotalCost', remark: 'totalPriceExcludingTax_Remarks' }, { name: '增值稅 / 元:', prop: 'valueAddedTax_TotalCost', remark: 'valueAddedTax_Remarks' }, { name: '價(jià)格合計(jì)(含稅)/ 元:', prop: 'totalPriceIncludingTax_TotalCost', remark: 'totalPriceIncludingTax_Remarks' }, { name: '優(yōu)惠后價(jià)格(含稅)/ 元:', prop: 'discountedPrice', remark: 'discountedPrice_Remarks' }, { name: '針對此次報(bào)價(jià)的其他說明', prop: 'remarks', remark: 'remarks' } ]; // 如果沒有優(yōu)惠后價(jià)格就不顯示 let havePrice = true; if (totalQuotationData.discountedPrice === null || totalQuotationData.discountedPrice === '' || totalQuotationData.discountedPrice === undefined) { havePrice = false; otherSunRow = otherSunRow.filter((item) => { return item.prop !== 'discountedPrice'; }); } // 插入數(shù)據(jù) 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] || ''; } // 設(shè)置其他合計(jì)樣式 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 // 自動換行 }; // 除備注列外,其他列設(shè)置顏色 if (cell._address.indexOf('M') < 0) { cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: '9BC2E6' } // 設(shè)置背景色 }; } }); } else if (rowIndex === rowNUM + 7 || (havePrice ? rowIndex === rowNUM + 8 : false)) { row.height = 17; // 價(jià)稅合計(jì) 、優(yōu)惠后價(jià)格 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' } // 設(shè)置背景色 }; } }); } 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' } // 設(shè)置背景色 }; }); } 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' } // 設(shè)置背景色 }; } }); } } }); // 將logo放入第一行 放到最后就行啦 // 獲取圖片的 Blob 數(shù)據(jù) const base64 = await this.imageToBase64(); // 把base64編碼的圖片插入excel工作簿里面 const imageId = workbook.addImage({ base64: base64, extension: 'png' }); // 當(dāng)前工作表(當(dāng)前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 } }); // 調(diào)整所有列的寬度 workSheet.columns.forEach((column) => { column.width = 17; // 將寬度設(shè)為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; // 創(chuàng)建工位的工作表 let sworkSheet = workbook.addWorksheet(details[i].inquiryStationCode); //======================================= 第一行 ================================= // 合并A1到L1的單元格 (大標(biāo)題) sworkSheet.mergeCells('A1:L1'); const cell = sworkSheet.getCell('A1'); cell.value = 'ChangChun HeXin Mechanical Manufacturing CO., LTD. - Quotation \n 長春合心機(jī)械制造有限公司 - 報(bào)價(jià)單'; // 設(shè)置第一行的單元格樣式 cell.font = { size: 16, bold: true, name: '仿宋' }; // 設(shè)置字體大小為16,加粗,仿宋 cell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wrapText: true // 自動換行 }; // 調(diào)整第一行的高度 sworkSheet.getRow(1).height = 70; // ==================================== 第二 到 第十二行 ================= 樣式差不多,一起搞 for (let ri = 2; ri < 14; ri++) { // 創(chuàng)建第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列的標(biāo)題數(shù)據(jù) 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' } // 設(shè)置背景色 }; } 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' } // 設(shè)置背景色 }; } headerCellJ.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wrapText: true // 自動換行 }; sworkSheet.getRow(ri).height = 15; // 獲取第ri行的單元格 // const cell = sworkSheet.getCell(`A${ri}`); // 設(shè)置單元格樣式 } // 插入表頭一堆數(shù)據(jù) row 是主表數(shù)據(jù) totalQuotationData 是子表數(shù)據(jù) sworkSheet.getCell('D2').value = row.inquiryName; // 項(xiàng)目名稱 sworkSheet.getCell('D3').value = row.commercialQuotationNumber; // 報(bào)價(jià)單號 sworkSheet.getCell('J3').value = row.creationTime; // 報(bào)價(jià)日期 sworkSheet.getCell('D4').value = row.customer; // 客戶名稱 sworkSheet.getCell('D11').value = ''; // 交費(fèi)周期 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; // 技術(shù)要求版本號 sworkSheet.getCell('J12').value = totalQuotationData.versionNumber; // 報(bào)價(jià)版本號 sworkSheet.getCell('D13').value = totalQuotationData.solutionVersion; // 方案版本號 // ==================================== 工位的數(shù)據(jù)部分 ================================================= // 標(biāo)題行 ['No.','Item 項(xiàng)目','小時數(shù)','費(fèi)率','Price 價(jià)格','備注:'] sworkSheet.addRow(); sworkSheet.getCell('A14').value = 'No.'; sworkSheet.mergeCells(`B14:C14`); sworkSheet.getCell('B14').value = 'Item 項(xiàng)目'; sworkSheet.getCell('D14').value = '小時數(shù)'; sworkSheet.getCell('E14').value = '費(fèi)率'; sworkSheet.getCell('F14').value = 'Price 價(jià)格'; sworkSheet.getCell('G14').value = '備注:'; sworkSheet.mergeCells(`G14:L14`); // 機(jī)械材料成本 sworkSheet.addRow(); sworkSheet.getCell('A15').value = 1; // 序號 sworkSheet.mergeCells(`B15:C15`); sworkSheet.getCell('B15').value = '機(jī)械材料成本'; sworkSheet.getCell('D15').value = '/'; // 小時數(shù) sworkSheet.getCell('E15').value = '/'; // 費(fèi)率 sworkSheet.getCell('F15').value = ''; // 價(jià)格 sworkSheet.getCell('G15').value = ''; // 備注 sworkSheet.mergeCells(`G15:L15`); // 機(jī)械加工成本 sworkSheet.addRow(); sworkSheet.getCell('A16').value = 2; sworkSheet.mergeCells(`B16:C16`); sworkSheet.getCell('B16').value = '機(jī)械加工成本'; sworkSheet.getCell('D16').value = '/'; // 小時數(shù) sworkSheet.getCell('E16').value = '/'; // 費(fèi)率 sworkSheet.getCell('F16').value = tableData.mechanicalMaterialsAndProcessingCosts_AfterMarkup || ''; // 價(jià)格 sworkSheet.getCell('G16').value = tableData.mechanicalMaterialsAndProcessingCosts_Remarks || ''; // 備注 sworkSheet.mergeCells(`G16:L16`); // 機(jī)械采購成本 sworkSheet.addRow(); sworkSheet.getCell('A17').value = 3; sworkSheet.mergeCells(`B17:C17`); sworkSheet.getCell('B17').value = '機(jī)械采購成本'; sworkSheet.getCell('D17').value = '/'; // 小時數(shù) sworkSheet.getCell('E17').value = '/'; // 費(fèi)率 sworkSheet.getCell('F17').value = tableData.mechanicalPurchaseCost_AfterMarkup || ''; // 價(jià)格 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 = '/'; // 小時數(shù) sworkSheet.getCell('E18').value = '/'; // 費(fèi)率 sworkSheet.getCell('F18').value = ''; // 價(jià)格 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 = '/'; // 小時數(shù) sworkSheet.getCell('E19').value = '/'; // 費(fèi)率 sworkSheet.getCell('F19').value = tableData.electricalpurchaseCost_AfterMarkup || ''; // 價(jià)格 sworkSheet.getCell('G19').value = tableData.electricalpurchaseCost_Remarks || ''; // 備注 sworkSheet.mergeCells(`G19:L19`); // 機(jī)械設(shè)計(jì)費(fèi) sworkSheet.addRow(); sworkSheet.getCell('A20').value = 6; sworkSheet.mergeCells(`B20:C20`); sworkSheet.getCell('B20').value = '機(jī)械設(shè)計(jì)費(fèi)'; sworkSheet.getCell('D20').value = tableData.mechanicalDesignFee_Hours || ''; // 小時數(shù) sworkSheet.getCell('E20').value = tableData.mechanicalDesignFee_PerHourRate || ''; // 費(fèi)率 sworkSheet.getCell('F20').value = tableData.mechanicalDesignFee_TotalCost || ''; // 價(jià)格 sworkSheet.getCell('G20').value = tableData.mechanicalDesignFee_Remarks || ''; // 備注 sworkSheet.mergeCells(`G20:L20`); // 電氣設(shè)計(jì)費(fèi) sworkSheet.addRow(); sworkSheet.getCell('A21').value = 7; sworkSheet.mergeCells(`B21:C21`); sworkSheet.getCell('B21').value = '電氣設(shè)計(jì)費(fèi)'; sworkSheet.getCell('D21').value = tableData.electricalDesignFee_Hours || ''; // 小時數(shù) sworkSheet.getCell('E21').value = tableData.electricalDesignFee_PerHourRate || ''; // 費(fèi)率 sworkSheet.getCell('F21').value = tableData.electricalDesignFee_TotalCost || ''; // 價(jià)格 sworkSheet.getCell('G21').value = tableData.electricalDesignFee_Remarks || ''; // 備注 sworkSheet.mergeCells(`G21:L21`); // 軟件編程及開發(fā) sworkSheet.addRow(); sworkSheet.getCell('A22').value = 8; sworkSheet.mergeCells(`B22:C22`); sworkSheet.getCell('B22').value = '軟件編程及開發(fā)'; sworkSheet.getCell('D22').value = tableData.softwareProgramming_Hours || ''; // 小時數(shù) sworkSheet.getCell('E22').value = tableData.softwareProgramming_PerHourRate || ''; // 費(fèi)率 sworkSheet.getCell('F22').value = tableData.softwareProgramming_TotalCost || ''; // 價(jià)格 sworkSheet.getCell('G22').value = tableData.softwareProgramming_Remarks || ''; // 備注 sworkSheet.mergeCells(`G22:L22`); // 機(jī)器人調(diào)試 sworkSheet.addRow(); sworkSheet.getCell('A23').value = 9; sworkSheet.mergeCells(`B23:C23`); sworkSheet.getCell('B23').value = '機(jī)器人調(diào)試'; sworkSheet.getCell('D23').value = tableData.robotDebugging_Hours || ''; // 小時數(shù) sworkSheet.getCell('E23').value = tableData.robotDebugging_PerHourRate || ''; // 費(fèi)率 sworkSheet.getCell('F23').value = tableData.robotDebugging_TotalCost || ''; // 價(jià)格 sworkSheet.getCell('G23').value = tableData.robotDebugging_Remarks || ''; // 備注 sworkSheet.mergeCells(`G23:L23`); // 項(xiàng)目經(jīng)理費(fèi)用 sworkSheet.addRow(); sworkSheet.getCell('A24').value = 10; sworkSheet.mergeCells(`B24:C24`); sworkSheet.getCell('B24').value = '項(xiàng)目經(jīng)理費(fèi)用'; sworkSheet.getCell('D24').value = tableData.projectManagerFee_Hours || ''; // 小時數(shù) sworkSheet.getCell('E24').value = tableData.projectManagerFee_PerHourRate || ''; // 費(fèi)率 sworkSheet.getCell('F24').value = tableData.projectManagerFee_TotalCost || ''; // 價(jià)格 sworkSheet.getCell('G24').value = tableData.projectManagerFee_Remarks || ''; // 備注 sworkSheet.mergeCells(`G24:L24`); // 機(jī)械安裝調(diào)試費(fèi)用 sworkSheet.addRow(); sworkSheet.getCell('A25').value = 11; sworkSheet.mergeCells(`B25:C25`); sworkSheet.getCell('B25').value = '機(jī)械安裝調(diào)試費(fèi)用'; sworkSheet.getCell('D25').value = tableData.mechanicalInstallationDebugging_Hours || ''; // 小時數(shù) sworkSheet.getCell('E25').value = tableData.mechanicalInstallationDebugging_PerHourRate || ''; // 費(fèi)率 sworkSheet.getCell('F25').value = tableData.mechanicalInstallationDebugging_TotalCost || ''; // 價(jià)格 sworkSheet.getCell('G25').value = tableData.mechanicalInstallationDebugging_Remarks || ''; // 備注 sworkSheet.mergeCells(`G25:L25`); // 電氣安裝調(diào)試費(fèi)用 sworkSheet.addRow(); sworkSheet.getCell('A26').value = 12; sworkSheet.mergeCells(`B26:C26`); sworkSheet.getCell('B26').value = '電氣安裝調(diào)試費(fèi)用'; sworkSheet.getCell('D26').value = tableData.electricalInstallationDebugging_Hours || ''; // 小時數(shù) sworkSheet.getCell('E26').value = tableData.electricalInstallationDebugging_PerHourRate || ''; // 費(fèi)率 sworkSheet.getCell('F26').value = tableData.electricalInstallationDebugging_TotalCost || ''; // 價(jià)格 sworkSheet.getCell('G26').value = tableData.electricalInstallationDebugging_Remarks || ''; // 備注 sworkSheet.mergeCells(`G26:L26`); // 現(xiàn)場調(diào)試服務(wù)費(fèi) sworkSheet.addRow(); sworkSheet.getCell('A27').value = 13; sworkSheet.mergeCells(`B27:C27`); sworkSheet.getCell('B27').value = '現(xiàn)場調(diào)試服務(wù)費(fèi)'; sworkSheet.getCell('D27').value = tableData.onSiteDebuggingService_Hours || ''; // 小時數(shù) sworkSheet.getCell('E27').value = tableData.onSiteDebuggingService_PerHourRate || ''; // 費(fèi)率 sworkSheet.getCell('F27').value = tableData.onSiteDebuggingService_TotalCost || ''; // 價(jià)格 sworkSheet.getCell('G27').value = tableData.onSiteDebuggingService_Remarks || ''; // 備注 sworkSheet.mergeCells(`G27:L27`); // 售后服務(wù)費(fèi) sworkSheet.addRow(); sworkSheet.getCell('A28').value = 14; sworkSheet.mergeCells(`B28:C28`); sworkSheet.getCell('B28').value = '售后服務(wù)費(fèi)'; sworkSheet.getCell('D28').value = tableData.afterSalesService_Hours || ''; // 小時數(shù) sworkSheet.getCell('E28').value = tableData.afterSalesService_PerHourRate || ''; // 費(fèi)率 sworkSheet.getCell('F28').value = tableData.afterSalesService_TotalCost || ''; // 價(jià)格 sworkSheet.getCell('G28').value = tableData.afterSalesService_Remarks || ''; // 備注 sworkSheet.mergeCells(`G28:L28`); // 包裝及運(yùn)輸費(fèi)用 sworkSheet.addRow(); sworkSheet.getCell('A29').value = 15; sworkSheet.mergeCells(`B29:C29`); sworkSheet.getCell('B29').value = '包裝及運(yùn)輸費(fèi)用'; sworkSheet.getCell('D29').value = '/'; // 小時數(shù) sworkSheet.getCell('E29').value = '/'; // 費(fèi)率 sworkSheet.getCell('F29').value = tableData.shippingPackagingCost_AfterMarkup || ''; // 價(jià)格 sworkSheet.getCell('G29').value = tableData.shippingPackagingCost_Remarks || ''; // 備注 sworkSheet.mergeCells(`G29:L29`); // 差旅費(fèi) sworkSheet.addRow(); sworkSheet.getCell('A30').value = 16; sworkSheet.mergeCells(`B30:C30`); sworkSheet.getCell('B30').value = '差旅費(fèi)'; sworkSheet.getCell('D30').value = '/'; // 小時數(shù) sworkSheet.getCell('E30').value = '/'; // 費(fèi)率 sworkSheet.getCell('F30').value = tableData.travelAndAccommodationCost_AfterMarkup || ''; // 價(jià)格 sworkSheet.getCell('G30').value = tableData.travelAndAccommodationCost_Remarks || ''; // 備注 sworkSheet.mergeCells(`G30:L30`); // 資料費(fèi) sworkSheet.addRow(); sworkSheet.getCell('A31').value = 17; sworkSheet.mergeCells(`B31:C31`); sworkSheet.getCell('B31').value = '資料費(fèi)'; sworkSheet.getCell('D31').value = '/'; // 小時數(shù) sworkSheet.getCell('E31').value = '/'; // 費(fèi)率 sworkSheet.getCell('F31').value = tableData.documentCost_AfterMarkup || ''; // 價(jià)格 sworkSheet.getCell('G31').value = tableData.documentCost_Remarks || ''; // 備注 sworkSheet.mergeCells(`G31:L31`); // 成本合計(jì)(小結(jié)) sworkSheet.addRow(); sworkSheet.getCell('A32').value = 18; sworkSheet.mergeCells(`B32:C32`); sworkSheet.getCell('B32').value = '成本合計(jì)(小結(jié))'; sworkSheet.getCell('D32').value = '/'; // 小時數(shù) sworkSheet.getCell('E32').value = '/'; // 費(fèi)率 sworkSheet.getCell('F32').value = tableData.totalCost || ''; // 價(jià)格 sworkSheet.getCell('G32').value = ''; // 備注 sworkSheet.mergeCells(`G32:L32`); // 管理費(fèi) sworkSheet.addRow(); sworkSheet.getCell('A33').value = 19; sworkSheet.mergeCells(`B33:C33`); sworkSheet.getCell('B33').value = '管理費(fèi)'; sworkSheet.getCell('D33').value = '/'; // 小時數(shù) sworkSheet.getCell('E33').value = '/'; // 費(fèi)率 sworkSheet.getCell('F33').value = tableData.managementFee || ''; // 價(jià)格 sworkSheet.getCell('G33').value = ''; // 備注 sworkSheet.mergeCells(`G33:L33`); // 財(cái)務(wù)費(fèi) sworkSheet.addRow(); sworkSheet.getCell('A34').value = 20; sworkSheet.mergeCells(`B34:C34`); sworkSheet.getCell('B34').value = '財(cái)務(wù)費(fèi)'; sworkSheet.getCell('D34').value = '/'; // 小時數(shù) sworkSheet.getCell('E34').value = '/'; // 費(fèi)率 sworkSheet.getCell('F34').value = tableData.financialFee || ''; // 價(jià)格 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 = '/'; // 小時數(shù) sworkSheet.getCell('E35').value = '/'; // 費(fèi)率 sworkSheet.getCell('F35').value = tableData.profit || ''; // 價(jià)格 sworkSheet.getCell('G35').value = ''; // 備注 sworkSheet.mergeCells(`G35:L35`); // 價(jià)格合計(jì)(未稅) sworkSheet.addRow(); sworkSheet.getCell('A36').value = 22; sworkSheet.mergeCells(`B36:C36`); sworkSheet.getCell('B36').value = '價(jià)格合計(jì)(未稅)'; sworkSheet.getCell('D36').value = '/'; // 小時數(shù) sworkSheet.getCell('E36').value = '/'; // 費(fèi)率 sworkSheet.getCell('F36').value = tableData.totalPriceExcludingTax || ''; // 價(jià)格 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 = '/'; // 小時數(shù) sworkSheet.getCell('E37').value = '/'; // 費(fèi)率 sworkSheet.getCell('F37').value = tableData.valueAddedTax || ''; // 價(jià)格 sworkSheet.getCell('G37').value = ''; // 備注 sworkSheet.mergeCells(`G37:L37`); // 價(jià)格合計(jì)(含稅) sworkSheet.addRow(); sworkSheet.getCell('A38').value = 24; sworkSheet.mergeCells(`B38:C38`); sworkSheet.getCell('B38').value = '價(jià)格合計(jì)(含稅)'; sworkSheet.getCell('D38').value = '/'; // 小時數(shù) sworkSheet.getCell('E38').value = '/'; // 費(fèi)率 sworkSheet.getCell('F38').value = tableData.valueAddedTax || ''; // 價(jià)格 sworkSheet.getCell('G38').value = ''; // 備注 sworkSheet.mergeCells(`G38:L38`); // 數(shù)據(jù)行統(tǒng)一樣式處理 sworkSheet.eachRow((row, rowIndex) => { // 循環(huán)每一行 if (rowIndex >= 14 && rowIndex <= 38) { if (rowIndex === 14) { // 標(biāo)題行 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' } // 設(shè)置背景色 }; } }); } else if (rowIndex >= 20 && rowIndex <= 28) { // 從機(jī)械設(shè)計(jì) 到 售后服務(wù)行 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' } // 設(shè)置背景色 }; } if (cell._address.indexOf('D') > -1 || cell._address.indexOf('E') > -1) { cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: '00B0F0' } // 設(shè)置背景色 }; } }); } 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' } // 設(shè)置背景色 }; } }); } 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' } // 設(shè)置背景色 }; } }); } 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' } // 設(shè)置背景色 }; } }); } 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' } // 設(shè)置背景色 }; } }); } row.height = 17; } }); // 最下方針對報(bào)價(jià)其他說明列 sworkSheet.addRow(); sworkSheet.mergeCells(`A39:C39`); sworkSheet.mergeCells(`D39:L39`); let remarkcell = sworkSheet.getCell('A39'); remarkcell.value = '針對此次報(bào)價(jià)的其他說明:'; remarkcell.font = { size: 12, bold: true }; remarkcell.alignment = { vertical: 'middle', // 垂直居中 horizontal: 'center', // 水平居中 wrapText: true // 自動換行 }; remarkcell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'A9D08E' } // 設(shè)置背景色 }; 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' } // 設(shè)置背景色 }; sworkSheet.getRow(39).height = 20; // 將logo放入第一行 放到最后就行啦(復(fù)用總報(bào)價(jià)) // 前面已經(jīng)加載了 imageid,這里直接用 // 當(dāng)前工作表(當(dāng)前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 } }); // 調(diào)整所有列的寬度 sworkSheet.columns.forEach((column) => { column.width = 17; // 將寬度設(shè)為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' }), '商務(wù)報(bào)價(jià)單導(dǎo)出.xlsx'); }); } else { this.$message(res.msg); } loading.close(); },
到此這篇關(guān)于Vue使用exceljs導(dǎo)出excel文件的詳細(xì)教程的文章就介紹到這了,更多相關(guān)Vue exceljs導(dǎo)出excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue實(shí)現(xiàn)商品分類菜單數(shù)量提示功能
這篇文章主要介紹了Vue實(shí)戰(zhàn)—商品分類菜單數(shù)量提示功能,本文通過項(xiàng)目實(shí)戰(zhàn)給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07Vue3封裝組件完整實(shí)例(帶回調(diào)事件)
Vue.js已成為現(xiàn)代Web開發(fā)中不可或缺的技術(shù)之一,雖然Vue.js的一些基礎(chǔ)概念和語法比較易學(xué),但深入挖掘Vue.js的核心概念和功能需要更多的實(shí)踐,下面這篇文章主要給大家介紹了關(guān)于Vue3封裝組件(帶回調(diào)事件)的相關(guān)資料,需要的朋友可以參考下2023-06-06vue2.0嵌套路由實(shí)現(xiàn)豆瓣電影分頁功能(附demo)
這篇文章主要介紹了vue2.0嵌套路由實(shí)現(xiàn)豆瓣電影分頁功能(附demo),這里整理了詳細(xì)的代碼,有需要的小伙伴可以參考下。2017-03-03前端記錄輸入框的歷史輸入記錄實(shí)現(xiàn)步驟(輸入框數(shù)據(jù)記憶功能)
這篇文章主要介紹了如何使用localStorage來記錄每個輸入框的歷史輸入記錄,并在用戶輸入時動態(tài)更新這些記錄,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-03-03