diff --git a/public/template20260226001test010.xlsx b/public/template20260226001test010.xlsx index 4f6ca05..e986e96 100644 Binary files a/public/template20260226001test010.xlsx and b/public/template20260226001test010.xlsx differ diff --git a/src/sql.ts b/src/sql.ts index 339e59d..9d24351 100644 --- a/src/sql.ts +++ b/src/sql.ts @@ -2,6 +2,7 @@ import { addNumbers, roundTo, toDecimal } from '@/lib/decimal' import { formatThousands } from '@/lib/numberFormat' import ExcelJS from "ExcelJS"; +import { number } from 'motion-v/es'; // 统一数字千分位格式化,默认保留 2 位小数。 const numberFormatter = (value: unknown, fractionDigits = 2) => formatThousands(value, fractionDigits) @@ -151,8 +152,7 @@ export const expertList = { 7: { code: 'C9-3-2', name: '一级造价工程师且具备高级工程师资格', maxPrice: 2000, minPrice: 1800, defPrice: 1900, manageCoe: 2.05 }, }; -export const additionalWorkList -=['人员驻场服务及其他附加工作','咨询服务协调工作'] +export const additionalWorkList = ['人员驻场服务及其他附加工作', '咨询服务协调工作']; let costScaleCal = [ { code: 'C1-1', staLine: 0, endLine: 100, basic: { staPrice: 0, rate: 0.01 }, optional: { staPrice: 0, rate: 0.002 } }, @@ -552,182 +552,7 @@ export async function exportFile(fileName: string, data: any): Promise { // 按模板生成最终工作簿:填充封面、目录、各分表及汇总数据。 async function generateTemplate(data) { // const downTextTmp = { richText: [{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: '常规' }, { font: { charset: 134, color: { theme: 1 }, italic: true, name: 'Calibri', size: 10, vertAlign: 'subscript' }, text: '下标' }] }; - - data.contracts[0].addtional = {// 附加工作费 - code: { richText: [{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' }, { font: { charset: 134, color: { theme: 1 }, italic: true, name: 'Calibri', size: 10, vertAlign: 'subscript' }, text: 'C' }] }, - name: '附加工作', - fee: 10000, - det: [ - { - id: 0, - code: { richText: [{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' }, { font: { charset: 134, color: { theme: 1 }, italic: true, name: 'Calibri', size: 10, vertAlign: 'subscript' }, text: 'F' }] }, - name: '人员驻场服务及其他附加工作', - fee: 10000, - m4: { - person_num: 10, - work_day: 3, - fee: 10000, - det: [ - { - expert: 0, - price: 100000, - person_num: 10, - work_day: 3, - fee: 100000, - remark: '',// 用户输入的说明 - }, - { - expert: 1, - price: 100000, - person_num: 10, - work_day: 3, - fee: 100000, - remark: '',// 用户输入的说明 - }, - ], - }, - m5: {//数量单价 - fee: 10000, - det: [ - { - name: '×××项', - unit: '项', - amount: 10, - price: 100000, - fee: 100000, - remark: '',// 用户输入的说明 - }, - { - name: '×××项', - unit: '项', - amount: 10, - price: 100000, - fee: 100000, - remark: '',// 用户输入的说明 - }, - ], - }, - }, - { - id: 1, - code: { richText: [{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'C' }, { font: { charset: 134, color: { theme: 1 }, italic: true, name: 'Calibri', size: 10, vertAlign: 'subscript' }, text: 'X' }] }, - name: '咨询服务协调工作', - fee: 10000, - m0: { //费率计取 - - coe: 0.03,//费率 - fee: 10000, - }, - m4: { //工时法 - person_num: 10, - work_day: 3, - fee: 10000, - det: [ - { - expert: 0, - price: 100000, - person_num: 10, - work_day: 3, - fee: 100000, - remark: '',// 用户输入的说明 - }, - { - expert: 1, - price: 100000, - person_num: 10, - work_day: 3, - fee: 100000, - remark: '',// 用户输入的说明 - }, - ], - }, - m5: { - fee: 10000, - det: [ - { - name: '×××项', - unit: '项', - amount: 10, - price: 100000, - fee: 100000, - remark: '',// 用户输入的说明 - }, - { - name: '×××项', - unit: '项', - amount: 10, - price: 100000, - fee: 100000, - remark: '',// 用户输入的说明 - }, - ], - }, - }, - ] - }; - data.contracts[0].reserve = {// 预备费 - code: { richText: [{ font: { charset: 134, color: { theme: 1 }, italic: true, name: '宋体', size: 10 }, text: 'Y' }, { font: { charset: 134, color: { theme: 1 }, italic: true, name: 'Calibri', size: 10, vertAlign: 'subscript' }, text: 'B' }] }, - name: '预备费', - fee: 10000, - m0: { - coe: 0.03, - fee: 10000, - }, - m4: { - person_num: 10, - work_day: 3, - fee: 10000, - det: [ - { - expert: 0, - price: 100000, - person_num: 10, - work_day: 3, - fee: 100000, - remark: '',// 用户输入的说明 - }, - { - expert: 1, - price: 100000, - person_num: 10, - work_day: 3, - fee: 100000, - remark: '',// 用户输入的说明 - }, - ], - }, - m5: { - fee: 10000, - det: [ - { - name: '×××项', - unit: '项', - amount: 10, - price: 100000, - fee: 100000, - remark: '',// 用户输入的说明 - }, - { - name: '×××项', - unit: '项', - amount: 10, - price: 100000, - fee: 100000, - remark: '',// 用户输入的说明 - }, - ], - } - }; - data.contracts[1].addtional = null; - data.contracts[1].reserve = null; - data.contracts[2].addtional = null; - data.contracts[2].reserve = null; - data.contracts[3].addtional = null; - data.contracts[3].reserve = null; - data.contracts[4].addtional = null; - data.contracts[4].reserve = null; - // data.contracts[5].addtional = null; - // data.contracts[5].reserve = null; + console.log(data) try { // 获取模板 let templateExcel = 'template20260226001test010'; @@ -1780,7 +1605,7 @@ async function generateTemplate(data) { } } let num_f01 = 1; - Object.keys(allMajors).sort((a, b) => majorList[a].order - majorList[b].order).forEach(majorid => { + Object.keys(allMajors).sort((a, b) => (a < 0 ? a : majorList[a].order) - (b < 0 ? b : majorList[b].order)).forEach(majorid => { let scaleX = allMajors[majorid]; let code; let name; @@ -1843,7 +1668,7 @@ async function generateTemplate(data) { }); f01_sheet.spliceRows(3, 1); // f01_sheet.getRow(2).height = 27; - f01_sheet.orderNo = ml_number + 2 + 11; + f01_sheet.orderNo = ml_number + 2 + 12; } else { workbook.removeWorksheet('辅01表'); } @@ -1864,14 +1689,14 @@ async function generateTemplate(data) { }); }); f02_sheet.spliceRows(2, 1); - f02_sheet.orderNo = ml_number + 3 + 11; + f02_sheet.orderNo = ml_number + 3 + 12; } else { workbook.removeWorksheet('辅02表'); } if (data.majorCoes?.length) { let f03_sheet = workbook.getWorksheet('辅03表'); let num_f03 = 1; - data.majorCoes.sort((a, b) => majorList[a.majorid].order - majorList[b.majorid].order).forEach(mcoei => { + data.majorCoes.sort((a, b) => (a < 0 ? a : majorList[a.majorid].order) - (b < 0 ? b : majorList[b.majorid].order)).forEach(mcoei => { let majorCoeX = majorList[mcoei.majorid]; cusInsertRowFunc(2 + num_f03, [f03_sheet.getRow(2)], f03_sheet, (targetRow) => { targetRow.getCell(1).value = num_f03++; @@ -1883,7 +1708,7 @@ async function generateTemplate(data) { }); }); f03_sheet.spliceRows(2, 1); - f03_sheet.orderNo = ml_number + 4 + 11; + f03_sheet.orderNo = ml_number + 4 + 12; } else { workbook.removeWorksheet('辅03表'); } @@ -1898,6 +1723,85 @@ async function generateTemplate(data) { window.workbook = workbook; + // 更新编制说明 + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + // ctx.font = "12pt 宋体"; + // const maxTitleWidth = 336; + // const maxTextWidth = 720; + const pageMaxHei = 733; + // 20.25 25.5 33.75 + const titleHeiDet = { fir: 11.25, els: 22.5 }; + const textHeiDet = { fir: 6.75, els: 13.5 }; + + const descSheet = workbook.getWorksheet('编制说明'); + descSheet.getRow(1).getCell(1).value = data.name; + let descRowNum = 5; + if (data.scale?.length) { + let engCosts = data.scale.filter(f => f.major > 6 && majorList[f.major].hasCost); + if (engCosts.length) { + descRowNum++; + let copyRowNum = descRowNum; + engCosts.forEach((sci, scindex) => { + descRowNum++; + cusInsertRowFunc(descRowNum, [descSheet.getRow(copyRowNum)], descSheet, (targetRow) => { + targetRow.getCell(1).value = ` ${scindex + 1}.${majorList[sci.major].name}${Number(sci.cost).toLocaleString()}万元${scindex == engCosts.length - 1 ? '。' : ';'}`; + }); + }); + descSheet.spliceRows(copyRowNum, 1); + } else { + descSheet.spliceRows(descRowNum, 2); + descSheet.getRow(descRowNum).getCell(1).value = ' (二)本项目征地拆迁费包括:'; + descSheet.getRow(descRowNum + 2).getCell(1).value = ' (三)其他费用包括:'; + } + let zcScales = data.scale.filter(f => [1, 2, 3].includes(f.major)); + if (zcScales.length) { + descRowNum++; + let copyRowNum = descRowNum; + zcScales.forEach((sci, scindex) => { + descRowNum++; + cusInsertRowFunc(descRowNum, [descSheet.getRow(copyRowNum)], descSheet, (targetRow) => { + switch (sci.major) { + case 1: + let desc1 = []; + if (sci.area) desc1.push(`征地总面积约${Number(sci.area).toLocaleString()}亩`); + if (sci.cost) desc1.push(`征地补偿费用${Number(sci.cost).toLocaleString()}万元`); + targetRow.getCell(1).value = ` ${scindex + 1}.征地情况:${desc1.join(',')}。`; + break; + case 2: + let desc2 = []; + if (sci.area) desc2.push(`拆迁总面积约${Number(sci.area).toLocaleString()}亩`); + if (sci.cost) desc2.push(`拆迁补偿费用${Number(sci.cost).toLocaleString()}万元`); + targetRow.getCell(1).value = ` ${scindex + 1}.拆迁补偿情况:${desc2.join(',')}。`; + break; + case 3: + targetRow.getCell(1).value = ` ${scindex + 1}.迁改工程情况:费用${Number(sci.cost).toLocaleString()}万元。`; + break; + } + }); + }); + descSheet.spliceRows(copyRowNum, 1); + } else { + descSheet.spliceRows(descRowNum, 2); + descSheet.getRow(descRowNum).getCell(1).value = engCosts.length ? ' (三)其他费用包括:' : ' (二)其他费用包括:'; + } + let otherCosts = data.scale.filter(f => [4, 5, 6].includes(f.major)); + if (otherCosts.length) { + let desc = []; + otherCosts.forEach(sci => { + desc.push(`${majorList[sci.major].name}${Number(sci.cost).toLocaleString()}万元`); + }); + descSheet.getRow(descRowNum).getCell(1).value = descSheet.getRow(descRowNum).getCell(1).value + `${desc.join(',')}。`; + descRowNum++; + } else { + descSheet.spliceRows(descRowNum, 1); + } + } else { + descSheet.spliceRows(descRowNum, 5); + descRowNum++; + } + console.log(descRowNum); + return workbook; } catch (error) { console.log(error)