更新导出成果报表功能

This commit is contained in:
ForeverSmiYng 2026-03-07 16:25:21 +08:00
parent 303f54bb71
commit 21d3f0379c
5 changed files with 2344 additions and 85 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -548,10 +548,186 @@ export async function exportFile(fileName: string, data: any): Promise<void> {
// 按模板生成最终工作簿:填充封面、目录、各分表及汇总数据。 // 按模板生成最终工作簿:填充封面、目录、各分表及汇总数据。
async function generateTemplate(data) { 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 = {// 附加工作费
ref: { 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,
ref: { 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,
ref: { 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 = {// 预备费
ref: { 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;
try { try {
// 获取模板 // 获取模板
let templateExcel = 'template20260226001test010'; let templateExcel = 'template20260226001test010';
let templateUrl = `https://oa.zwgczx.com/myExcelTemplate/${templateExcel}.xlsx`; let templateUrl = `./public/${templateExcel}.xlsx`;
let buf = await (await fetch(templateUrl)).arrayBuffer(); let buf = await (await fetch(templateUrl)).arrayBuffer();
let workbook = new ExcelJS.Workbook(); let workbook = new ExcelJS.Workbook();
await workbook.xlsx.load(buf); await workbook.xlsx.load(buf);
@ -562,14 +738,20 @@ async function generateTemplate(data) {
let yz01_sheet = workbook.getWorksheet('预总01表'); let yz01_sheet = workbook.getWorksheet('预总01表');
let f01_sheet = workbook.getWorksheet('辅01表'); let f01_sheet = workbook.getWorksheet('辅01表');
let now = new Date(); // 更新封面
let year = now.getFullYear();
let month = now.getMonth() + 1;
let day = now.getDate();
fm_sheet.getRow(2).getCell(1).value = data.name; fm_sheet.getRow(2).getCell(1).value = data.name;
fm_sheet.getRow(8).getCell(4).value = data.writer;
fm_sheet.getRow(9).getCell(4).value = data.reviewer;
fm_sheet.getRow(10).getCell(4).value = data.company;
if (data.date) {
const dateArr = data.date.split('-');
let year = dateArr[0];
let month = Number(dateArr[1]);
let day = Number(dateArr[2]);
fm_sheet.getRow(11).getCell(4).value = `${year}${month}${day}`; fm_sheet.getRow(11).getCell(4).value = `${year}${month}${day}`;
}
// 更新预总01表的列数
let yz01Mod = (data.contracts.length + 1) % 4; let yz01Mod = (data.contracts.length + 1) % 4;
let yz01Num = (data.contracts.length + 1 - yz01Mod) / 4; let yz01Num = (data.contracts.length + 1 - yz01Mod) / 4;
switch (yz01Mod) { switch (yz01Mod) {
@ -597,6 +779,7 @@ async function generateTemplate(data) {
} }
} }
// 更新辅01表的列数
let f01Mod = (data.contracts.length) % 3; let f01Mod = (data.contracts.length) % 3;
let f01Num = (data.contracts.length - f01Mod) / 3; let f01Num = (data.contracts.length - f01Mod) / 3;
switch (f01Mod) { switch (f01Mod) {
@ -644,14 +827,18 @@ async function generateTemplate(data) {
} }
} }
let ml_slotRow = 13; // 按合同段更新目录及相关表
let ml_slotRow = 14;
let ml_number = 1; let ml_number = 1;
let allServices = []; let allServices = [];
let allAddtional = {};
let allReserve = {};
data.contracts.forEach((ci, index) => { data.contracts.forEach((ci, index) => {
ci.method1 = []; ci.method1 = [];
ci.method2 = []; ci.method2 = [];
ci.method3 = []; ci.method3 = [];
ci.method4 = []; ci.method4 = [];
// 按计价方式汇总服务数据对象
ci.services.forEach(si => { ci.services.forEach(si => {
if (si.method1) { if (si.method1) {
ci.method1.push(si.id); ci.method1.push(si.id);
@ -662,7 +849,22 @@ async function generateTemplate(data) {
if (si.method3) ci.method3.push(si.id); if (si.method3) ci.method3.push(si.id);
if (si.method4) ci.method4.push(si.id); if (si.method4) ci.method4.push(si.id);
}); });
const addtionalM4 = [];
const addtionalM5 = [];
if (ci.addtional) {
allAddtional[index] = ci.addtional;
ci.addtional.det.forEach(f => {
if (f.m4) addtionalM4.push(f);
if (f.m5) addtionalM5.push(f);
});
}
if (addtionalM5.length) ci.method5 = { addtional: addtionalM5 };
if (ci.reserve) allReserve[index] = ci.reserve;
const reserveM4 = ci.reserve?.m4;
const reserveM5 = ci.reserve?.m5;
if (reserveM5) ci.method5 = ci.method5 ? Object.assign({ reserve: reserveM5 }, ci.method5) : { reserve: reserveM5 };
// 创建sheet
let ml_sourceRows = [ml_sheet.getRow(6)]; let ml_sourceRows = [ml_sheet.getRow(6)];
let sheet_1 = copyWorksheet(workbook, '预i-1表', `${index + 1}-1表`); let sheet_1 = copyWorksheet(workbook, '预i-1表', `${index + 1}-1表`);
sheet_1.headerFooter.oddHeader = sheet_1.headerFooter.oddHeader.replace(/×××/g, ci.name).replace(/预 i-1 表/g, `${index + 1}-1 表`).replace(/第i合同/g, ci.name); sheet_1.headerFooter.oddHeader = sheet_1.headerFooter.oddHeader.replace(/×××/g, ci.name).replace(/预 i-1 表/g, `${index + 1}-1 表`).replace(/第i合同/g, ci.name);
@ -673,6 +875,7 @@ async function generateTemplate(data) {
let sheet_3; let sheet_3;
let sheet_4; let sheet_4;
let sheet_4_1; let sheet_4_1;
let sheet_5;
if (ci.method1.length || ci.method2.length) { if (ci.method1.length || ci.method2.length) {
ml_sourceRows.push(ml_sheet.getRow(7)); ml_sourceRows.push(ml_sheet.getRow(7));
sheet_2 = copyWorksheet(workbook, '预i-2表', `${index + 1}-2表`); sheet_2 = copyWorksheet(workbook, '预i-2表', `${index + 1}-2表`);
@ -693,19 +896,21 @@ async function generateTemplate(data) {
sheet_3 = copyWorksheet(workbook, '预i-3表', `${index + 1}-3表`); sheet_3 = copyWorksheet(workbook, '预i-3表', `${index + 1}-3表`);
sheet_3.headerFooter.oddHeader = sheet_3.headerFooter.oddHeader.replace(/×××/g, ci.name).replace(/预 i-3 表/g, `${index + 1}-3 表`).replace(/第i合同/g, ci.name); sheet_3.headerFooter.oddHeader = sheet_3.headerFooter.oddHeader.replace(/×××/g, ci.name).replace(/预 i-3 表/g, `${index + 1}-3 表`).replace(/第i合同/g, ci.name);
} }
if (ci.method4.length) { if (ci.method4.length || addtionalM4.length || reserveM4) {
ml_sourceRows.push(ml_sheet.getRow(11)); ml_sourceRows.push(ml_sheet.getRow(11));
ml_sourceRows.push(ml_sheet.getRow(12)); ml_sourceRows.push(ml_sheet.getRow(12));
sheet_4 = copyWorksheet(workbook, '预i-4表', `${index + 1}-4表`); sheet_4 = copyWorksheet(workbook, '预i-4表', `${index + 1}-4表`);
sheet_4.headerFooter.oddHeader = sheet_4.headerFooter.oddHeader.replace(/×××/g, ci.name).replace(/预 i-4 表/g, `${index + 1}-4 表`).replace(/第i合同/g, ci.name); sheet_4.headerFooter.oddHeader = sheet_4.headerFooter.oddHeader.replace(/×××/g, ci.name).replace(/预 i-4 表/g, `${index + 1}-4 表`).replace(/第i合同/g, ci.name);
sheet_4_1 = copyWorksheet(workbook, '预i-4-1表', `${index + 1}-4-1表`); sheet_4_1 = copyWorksheet(workbook, '预i-4-1表', `${index + 1}-4-1表`);
sheet_4_1.headerFooter.oddHeader = sheet_4_1.headerFooter.oddHeader.replace(/×××/g, ci.name).replace(/预 i-4-1 表/g, `${index + 1}-4-1 表`).replace(/第i合同/g, ci.name); sheet_4_1.headerFooter.oddHeader = sheet_4_1.headerFooter.oddHeader.replace(/×××/g, ci.name).replace(/预 i-4-1 表/g, `${index + 1}-4-1 表`).replace(/第i合同/g, ci.name);
let sumObj = ci.method4.reduce((a, b) => { // 更新i-4和i-4-1表的小计行
const m4 = ci.services.find(f => f.id == b)?.method4; let sumArr = ci.method4.map(m => ci.services.find(f => f.id == m)?.method4).concat(addtionalM4.map(m => m.m4));
if (reserveM4) sumArr.push(reserveM4);
let sumObj = sumArr.reduce((a, b) => {
return { return {
person_num: addNumbers(a.person_num, toFiniteNumber(m4?.person_num)), person_num: addNumbers(a.person_num, toFiniteNumber(b?.person_num)),
work_day: addNumbers(a.work_day, toFiniteNumber(m4?.work_day)), work_day: addNumbers(a.work_day, toFiniteNumber(b?.work_day)),
fee: addNumbers(a.fee, toFiniteNumber(m4?.fee)) fee: addNumbers(a.fee, toFiniteNumber(b?.fee))
}; };
}, { person_num: 0, work_day: 0, fee: 0 }); }, { person_num: 0, work_day: 0, fee: 0 });
sheet_4.getRow(3).getCell(4).value = sumObj.person_num; sheet_4.getRow(3).getCell(4).value = sumObj.person_num;
@ -718,7 +923,16 @@ async function generateTemplate(data) {
sheet_4_1.getRow(4).getCell(8).value = sumObj.work_day; sheet_4_1.getRow(4).getCell(8).value = sumObj.work_day;
sheet_4_1.getRow(4).getCell(9).value = sumObj.fee sheet_4_1.getRow(4).getCell(9).value = sumObj.fee
} }
if (ci.method5) {
ml_sourceRows.push(ml_sheet.getRow(13));
sheet_5 = copyWorksheet(workbook, '预i-5表', `${index + 1}-5表`);
sheet_5.headerFooter.oddHeader = sheet_5.headerFooter.oddHeader.replace(/×××/g, ci.name).replace(/预 i-5 表/g, `${index + 1}-5 表`).replace(/第i合同/g, ci.name);
sheet_5.getRow(3).getCell(4).value = '/';
sheet_5.getRow(3).getCell(5).value = '/';
sheet_5.getRow(3).getCell(6).value = (ci.method5.addtional?.reduce((a, b) => a + b.m5.fee, 0) || 0) + (ci.method5.reserve?.fee || 0);
}
// 更新目录的第三部分
cusInsertRowFunc(ml_slotRow, ml_sourceRows, ml_sheet, () => ml_slotRow++, (targetCell, sourceCell, colNumber) => { cusInsertRowFunc(ml_slotRow, ml_sourceRows, ml_sheet, () => ml_slotRow++, (targetCell, sourceCell, colNumber) => {
if (colNumber == 1) { if (colNumber == 1) {
targetCell.value = ml_number++; targetCell.value = ml_number++;
@ -731,12 +945,19 @@ async function generateTemplate(data) {
} }
}); });
// 根据服务更新相关表
let num_2 = 1; let num_2 = 1;
let num_2_1 = 1; let num_2_1 = 1;
let num_2_2 = 1; let num_2_2 = 1;
let num_3 = 1; let num_3 = 1;
let num_4 = 1; let num_4 = 1;
let num_4_1 = 1; let num_4_1 = 1;
let num_5 = 1;
let m1Sum = 0;
let m2Sum = 0;
let m3Sum = 0;
let m4Sum = 0;
let serviceSum = 0;
ci.services.forEach((sobj, sindex) => { ci.services.forEach((sobj, sindex) => {
let allServicesX = allServices.find(s => s.id == sobj.id); let allServicesX = allServices.find(s => s.id == sobj.id);
if (allServicesX) { if (allServicesX) {
@ -749,31 +970,34 @@ async function generateTemplate(data) {
}, },
}); });
} }
let serviceX = getServiceDictItemById(sobj.id) || { code: '', name: '' }; let serviceX = serviceList[sobj.id];
cusInsertRowFunc(4 + sindex, [sheet_1.getRow(3)], sheet_1, (targetRow) => { cusInsertRowFunc(4 + sindex, [sheet_1.getRow(3)], sheet_1, (targetRow) => {
targetRow.getCell(1).value = sindex + 1; targetRow.getCell(1).value = sindex + 1;
targetRow.getCell(2).value = serviceX.code; targetRow.getCell(2).value = serviceX.code;
targetRow.getCell(3).value = serviceX.name; targetRow.getCell(3).value = serviceX.name;
targetRow.getCell(4).value = sobj.method1 ? sobj.method1.fee : ''; if (sobj.method1) {
targetRow.getCell(5).value = sobj.method2 ? sobj.method2.fee : ''; targetRow.getCell(4).value = sobj.method1.fee;
targetRow.getCell(6).value = sobj.method3 ? sobj.method3.fee : ''; m1Sum += sobj.method1.fee;
targetRow.getCell(7).value = sobj.method4 ? sobj.method4.fee : ''; }
if (sobj.method2) {
targetRow.getCell(5).value = sobj.method2.fee;
m2Sum += sobj.method2.fee;
}
if (sobj.method3) {
targetRow.getCell(6).value = sobj.method3.fee;
m3Sum += sobj.method3.fee;
}
if (sobj.method4) {
targetRow.getCell(7).value = sobj.method4.fee;
m4Sum += sobj.method4.fee;
}
targetRow.getCell(8).value = sobj.fee; targetRow.getCell(8).value = sobj.fee;
serviceSum += sobj.fee;
}); });
if (sobj.method1 || sobj.method2) { if (sobj.method1 || sobj.method2) {
let det1 = sobj.method1 ? sobj.method1.det.map(m => m.major) : []; let det1 = sobj.method1 ? sobj.method1.det.map(m => m.major) : [];
let det2 = sobj.method2 ? sobj.method2.det.map(m => m.major) : []; let det2 = sobj.method2 ? sobj.method2.det.map(m => m.major) : [];
const majorOrderMap = new Map(getMajorDictEntries().map((entry, idx) => [entry.id, idx])); let allDet = [...(new Set([...det1, ...det2]))].sort((a, b) => a - b).map(m => {
let allDet = [...(new Set([...det1, ...det2]))].sort((a, b) => {
const aId = String(a);
const bId = String(b);
const ao = majorOrderMap.get(aId) ?? majorOrderMap.get(getMajorIdAliasMap().get(aId) || '');
const bo = majorOrderMap.get(bId) ?? majorOrderMap.get(getMajorIdAliasMap().get(bId) || '');
if (ao != null && bo != null) return ao - bo;
if (ao != null) return -1;
if (bo != null) return 1;
return aId.localeCompare(bId);
}).map(m => {
return { return {
major: m, major: m,
mth1: det1.includes(m) ? sobj.method1.det[det1.indexOf(m)] : null, mth1: det1.includes(m) ? sobj.method1.det[det1.indexOf(m)] : null,
@ -787,9 +1011,11 @@ async function generateTemplate(data) {
targetRow.getCell(3).value = serviceX.name; targetRow.getCell(3).value = serviceX.name;
targetRow.getCell(4).value = '/'; targetRow.getCell(4).value = '/';
targetRow.getCell(5).value = '/'; targetRow.getCell(5).value = '/';
targetRow.getCell(6).value = '/';
targetRow.getCell(7).value = '/';
if (sobj.method1) { if (sobj.method1) {
targetRow.getCell(6).value = sobj.method1.basicFee; targetRow.getCell(8).value = sobj.method1.basicFee;
targetRow.getCell(7).value = sobj.method1.fee; targetRow.getCell(9).value = sobj.method1.fee;
cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => { cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => {
targetRow.getCell(1).value = num_2_1++; targetRow.getCell(1).value = num_2_1++;
targetRow.getCell(2).value = serviceX.code; targetRow.getCell(2).value = serviceX.code;
@ -803,8 +1029,8 @@ async function generateTemplate(data) {
}); });
} }
if (sobj.method2) { if (sobj.method2) {
targetRow.getCell(8).value = sobj.method2.basicFee; targetRow.getCell(10).value = sobj.method2.basicFee;
targetRow.getCell(9).value = sobj.method2.fee; targetRow.getCell(11).value = sobj.method2.fee;
cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => { cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => {
targetRow.getCell(1).value = num_2_2++; targetRow.getCell(1).value = num_2_2++;
targetRow.getCell(2).value = serviceX.code; targetRow.getCell(2).value = serviceX.code;
@ -819,7 +1045,7 @@ async function generateTemplate(data) {
} }
}); });
allDet.forEach((m, mindex) => { allDet.forEach((m, mindex) => {
let majorX = getMajorDictItemById(m.major) || { name: '' }; let majorX = majorList[m.major];
cusInsertRowFunc(4 + num_2, [sheet_2.getRow(4)], sheet_2, (targetRow) => { cusInsertRowFunc(4 + num_2, [sheet_2.getRow(4)], sheet_2, (targetRow) => {
targetRow.getCell(1).value = num_2++; targetRow.getCell(1).value = num_2++;
targetRow.getCell(2).value = serviceX.code + '-' + (mindex + 1); targetRow.getCell(2).value = serviceX.code + '-' + (mindex + 1);
@ -827,10 +1053,12 @@ async function generateTemplate(data) {
if (m.mth1) { if (m.mth1) {
targetRow.getCell(4).value = m.mth1.serviceCoe; targetRow.getCell(4).value = m.mth1.serviceCoe;
targetRow.getCell(5).value = m.mth1.majorCoe; targetRow.getCell(5).value = m.mth1.majorCoe;
targetRow.getCell(6).value = m.mth1.basicFee; targetRow.getCell(6).value = m.mth1.processCoe;
targetRow.getCell(7).value = m.mth1.fee; targetRow.getCell(7).value = m.mth1.proportion;
targetRow.getCell(8).value = 0; targetRow.getCell(8).value = m.mth1.basicFee;
targetRow.getCell(9).value = 0; targetRow.getCell(9).value = m.mth1.fee;
targetRow.getCell(10).value = 0;
targetRow.getCell(11).value = 0;
cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => { cusInsertRowFunc(4 + num_2_1, [sheet_2_1.getRow(4)], sheet_2_1, (targetRow) => {
targetRow.getCell(1).value = num_2_1++; targetRow.getCell(1).value = num_2_1++;
targetRow.getCell(2).value = serviceX.code + '-' + (mindex + 1); targetRow.getCell(2).value = serviceX.code + '-' + (mindex + 1);
@ -845,10 +1073,12 @@ async function generateTemplate(data) {
} else { } else {
targetRow.getCell(4).value = m.mth2.serviceCoe; targetRow.getCell(4).value = m.mth2.serviceCoe;
targetRow.getCell(5).value = m.mth2.majorCoe; targetRow.getCell(5).value = m.mth2.majorCoe;
targetRow.getCell(6).value = 0; targetRow.getCell(6).value = m.mth2.processCoe;
targetRow.getCell(7).value = 0; targetRow.getCell(7).value = m.mth2.proportion;
targetRow.getCell(8).value = m.mth2.basicFee; targetRow.getCell(8).value = 0;
targetRow.getCell(9).value = m.mth2.fee; targetRow.getCell(9).value = 0;
targetRow.getCell(10).value = m.mth2.basicFee;
targetRow.getCell(11).value = m.mth2.fee;
cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => { cusInsertRowFunc(4 + num_2_2, [sheet_2_2.getRow(4)], sheet_2_2, (targetRow) => {
targetRow.getCell(1).value = num_2_2++; targetRow.getCell(1).value = num_2_2++;
targetRow.getCell(2).value = serviceX.code + '-' + (mindex + 1); targetRow.getCell(2).value = serviceX.code + '-' + (mindex + 1);
@ -928,19 +1158,64 @@ async function generateTemplate(data) {
}); });
} }
}); });
let endRows = 1;
cusInsertRowFunc(ci.services.length + 3 + endRows, [sheet_1.getRow(3)], sheet_1, (targetRow) => {
targetRow.getCell(1).value = ci.services.length + endRows;
targetRow.getCell(2).value = '';
targetRow.getCell(3).value = '小计';
targetRow.getCell(4).value = numberFormatter(m1Sum, 2);
targetRow.getCell(5).value = numberFormatter(m2Sum, 2);
targetRow.getCell(6).value = numberFormatter(m3Sum, 2);
targetRow.getCell(7).value = numberFormatter(m4Sum, 2);
targetRow.getCell(8).value = numberFormatter(serviceSum, 2);
});
if (ci.addtional) {
endRows++;
cusInsertRowFunc(ci.services.length + 3 + endRows, [sheet_1.getRow(3)], sheet_1, (targetRow) => {
targetRow.getCell(1).value = ci.services.length + endRows;
targetRow.getCell(2).value = ci.addtional.ref;
targetRow.getCell(3).value = ci.addtional.name;
targetRow.getCell(4).value = '';
targetRow.getCell(5).value = '';
targetRow.getCell(6).value = '';
targetRow.getCell(7).value = '';
targetRow.getCell(8).value = ci.addtional.fee;
});
ci.addtional.det.forEach((addobj, addindex) => {
endRows++;
cusInsertRowFunc(ci.services.length + 3 + endRows, [sheet_1.getRow(3)], sheet_1, (targetRow) => {
targetRow.getCell(1).value = ci.services.length + endRows;
targetRow.getCell(2).value = addobj.ref;
targetRow.getCell(3).value = addobj.name;
let tmpArr = [];
if (addobj.m0) tmpArr.push(`按上述小计的${addobj.m0.coe}计得${addobj.m0.fee}`);
if (addobj.m4) tmpArr.push(`按工时法计得${addobj.m4.fee}`);
if (addobj.m5) tmpArr.push(`按数量单价计得${addobj.m5.fee}`);
targetRow.getCell(4).value = tmpArr.join(';');
targetRow.getCell(8).value = addobj.fee;
});
});
}
sheet_1.spliceRows(3, 1);
sheet_1.getRow(ci.services.length + endRows + 3).getCell(1).value = ci.services.length + endRows + 1;
sheet_1.getRow(ci.services.length + endRows + 3).getCell(8).value = ci.fee;
sheet_1.mergeCells(2 + ci.services.length + endRows + 2, 2, 2 + ci.services.length + endRows + 2, 8);
sheet_1.getRow(2 + ci.services.length + endRows + 2).height = 100;
sheet_1.getRow(2 + ci.services.length + endRows + 2).getCell(2).border.right = { style: 'thin' };
for (let i = 1; i <= endRows; i++) {
sheet_1.mergeCells(ci.services.length + 3 + i, 4, ci.services.length + 3 + i, 7);
if (sheet_1.getRow(ci.services.length + 3 + i).getCell(4).style.alignment) {
sheet_1.getRow(ci.services.length + 3 + i).getCell(4).style.alignment.horizontal = 'center';
sheet_1.getRow(ci.services.length + 3 + i).getCell(4).style.alignment.wrapText = true;
if (i != 1 && i != endRows) sheet_1.getRow(ci.services.length + 3 + i).getCell(9).style.font.size = 22;
}
}
}); });
const serviceOrderMap = new Map(getServiceDictEntries().map((entry, index) => [entry.id, index])); allServices.sort((a, b) => a.id - b.id);
allServices.sort((a, b) => {
const ao = serviceOrderMap.get(String(a.id));
const bo = serviceOrderMap.get(String(b.id));
if (ao != null && bo != null) return ao - bo;
if (ao != null) return -1;
if (bo != null) return 1;
return String(a.id).localeCompare(String(b.id));
});
allServices.forEach((s, sindex) => { allServices.forEach((s, sindex) => {
const serviceX = getServiceDictItemById(s.id) || { code: '', name: '' }; const serviceX = serviceList[s.id];
cusInsertRowFunc(3 + sindex, [yz01_sheet.getRow(2)], yz01_sheet, (targetRow) => { cusInsertRowFunc(3 + sindex, [yz01_sheet.getRow(2)], yz01_sheet, (targetRow) => {
let siSum = 0; let siSum = 0;
for (let i = 0; i < yz01Num; i++) { for (let i = 0; i < yz01Num; i++) {
@ -986,35 +1261,174 @@ async function generateTemplate(data) {
} }
}); });
}); });
let endRows = 0;
if (Object.keys(allAddtional).length) {
endRows++;
let firstNum = Object.keys(allAddtional)[0];
cusInsertRowFunc(3 + allServices.length, [yz01_sheet.getRow(2)], yz01_sheet, (targetRow) => {
let siSum = 0;
for (let i = 0; i < yz01Num; i++) {
targetRow.getCell(i * 7 + 1).value = allServices.length + 1;
targetRow.getCell(i * 7 + 2).value = allAddtional[firstNum].ref;
targetRow.getCell(i * 7 + 3).value = allAddtional[firstNum].name;
targetRow.getCell(i * 7 + 4).value = allAddtional[i * 4]?.fee;
targetRow.getCell(i * 7 + 5).value = allAddtional[i * 4 + 1]?.fee;
targetRow.getCell(i * 7 + 6).value = allAddtional[i * 4 + 2]?.fee;
siSum = addNumbers(
siSum,
toFiniteNumber(allAddtional[i * 4]?.fee),
toFiniteNumber(allAddtional[i * 4 + 1]?.fee),
toFiniteNumber(allAddtional[i * 4 + 2]?.fee)
);
if (i == yz01Num - 1 && yz01Mod == 0) {
targetRow.getCell(i * 7 + 7).value = numberFormatter(siSum, 2);
} else {
targetRow.getCell(i * 7 + 7).value = allAddtional[i * 4 + 3]?.fee;
siSum = addNumbers(siSum, toFiniteNumber(allAddtional[i * 4 + 3]?.fee));
}
}
if (yz01Mod) {
targetRow.getCell(yz01Num * 7 + 1).value = allServices.length + 1;
targetRow.getCell(yz01Num * 7 + 2).value = allAddtional[firstNum].ref;
targetRow.getCell(yz01Num * 7 + 3).value = allAddtional[firstNum].name;
if (yz01Mod == 1) {
targetRow.getCell(yz01Num * 7 + 4).value = numberFormatter(siSum, 2);
} else if (yz01Mod == 2) {
targetRow.getCell(yz01Num * 7 + 4).value = allAddtional[yz01Num * 4]?.fee;
siSum = addNumbers(siSum, toFiniteNumber(allAddtional[yz01Num * 4]?.fee));
targetRow.getCell(yz01Num * 7 + 5).value = numberFormatter(siSum, 2);
} else {
targetRow.getCell(yz01Num * 7 + 4).value = allAddtional[yz01Num * 4]?.fee;
targetRow.getCell(yz01Num * 7 + 5).value = allAddtional[yz01Num * 4 + 1]?.fee;
siSum = addNumbers(
siSum,
toFiniteNumber(allAddtional[yz01Num * 4]?.fee),
toFiniteNumber(allAddtional[yz01Num * 4 + 1]?.fee)
);
targetRow.getCell(yz01Num * 7 + 6).value = numberFormatter(siSum, 2);
}
}
});
}
if (Object.keys(allReserve).length) {
endRows++;
let firstNum = Object.keys(allReserve)[0];
cusInsertRowFunc(3 + allServices.length + endRows - 1, [yz01_sheet.getRow(2)], yz01_sheet, (targetRow) => {
let siSum = 0;
for (let i = 0; i < yz01Num; i++) {
targetRow.getCell(i * 7 + 1).value = allServices.length + endRows;
targetRow.getCell(i * 7 + 2).value = allReserve[firstNum].ref;
targetRow.getCell(i * 7 + 3).value = allReserve[firstNum].name;
targetRow.getCell(i * 7 + 4).value = allReserve[i * 4]?.fee;
targetRow.getCell(i * 7 + 5).value = allReserve[i * 4 + 1]?.fee;
targetRow.getCell(i * 7 + 6).value = allReserve[i * 4 + 2]?.fee;
siSum = addNumbers(
siSum,
toFiniteNumber(allReserve[i * 4]?.fee),
toFiniteNumber(allReserve[i * 4 + 1]?.fee),
toFiniteNumber(allReserve[i * 4 + 2]?.fee)
);
if (i == yz01Num - 1 && yz01Mod == 0) {
targetRow.getCell(i * 7 + 7).value = numberFormatter(siSum, 2);
} else {
targetRow.getCell(i * 7 + 7).value = allReserve[i * 4 + 3]?.fee;
siSum = addNumbers(siSum, toFiniteNumber(allReserve[i * 4 + 3]?.fee));
}
}
if (yz01Mod) {
targetRow.getCell(yz01Num * 7 + 1).value = allServices.length + endRows;
targetRow.getCell(yz01Num * 7 + 2).value = allReserve[firstNum].ref;
targetRow.getCell(yz01Num * 7 + 3).value = allReserve[firstNum].name;
if (yz01Mod == 1) {
targetRow.getCell(yz01Num * 7 + 4).value = numberFormatter(siSum, 2);
} else if (yz01Mod == 2) {
targetRow.getCell(yz01Num * 7 + 4).value = allReserve[yz01Num * 4]?.fee;
siSum = addNumbers(siSum, toFiniteNumber(allReserve[yz01Num * 4]?.fee));
targetRow.getCell(yz01Num * 7 + 5).value = numberFormatter(siSum, 2);
} else {
targetRow.getCell(yz01Num * 7 + 4).value = allReserve[yz01Num * 4]?.fee;
targetRow.getCell(yz01Num * 7 + 5).value = allReserve[yz01Num * 4 + 1]?.fee;
siSum = addNumbers(
siSum,
toFiniteNumber(allReserve[yz01Num * 4]?.fee),
toFiniteNumber(allReserve[yz01Num * 4 + 1]?.fee)
);
targetRow.getCell(yz01Num * 7 + 6).value = numberFormatter(siSum, 2);
}
}
});
}
const yz01SumRow = yz01_sheet.getRow(allServices.length + endRows + 3);
for (let i = 0; i < yz01Num; i++) {
yz01SumRow.getCell(i * 7 + 1).value = allServices.length + endRows + 1;
yz01SumRow.getCell(i * 7 + 4).value = data.contracts[i * 4]?.fee;
yz01SumRow.getCell(i * 7 + 5).value = data.contracts[i * 4 + 1]?.fee;
yz01SumRow.getCell(i * 7 + 6).value = data.contracts[i * 4 + 2]?.fee;
if (i == yz01Num - 1 && yz01Mod == 0) {
yz01SumRow.getCell(i * 7 + 7).value = numberFormatter(data.fee, 2);
} else {
yz01SumRow.getCell(i * 7 + 7).value = data.contracts[i * 4 + 3]?.fee;
}
}
if (yz01Mod) {
yz01SumRow.getCell(yz01Num * 7 + 1).value = allServices.length + endRows + 1;
if (yz01Mod == 1) {
yz01SumRow.getCell(yz01Num * 7 + 4).value = numberFormatter(data.fee, 2);
} else if (yz01Mod == 2) {
yz01SumRow.getCell(yz01Num * 7 + 4).value = data.contracts[yz01Num * 4]?.fee;
yz01SumRow.getCell(yz01Num * 7 + 5).value = numberFormatter(data.fee, 2);
} else {
yz01SumRow.getCell(yz01Num * 7 + 4).value = data.contracts[yz01Num * 4]?.fee;
yz01SumRow.getCell(yz01Num * 7 + 5).value = data.contracts[yz01Num * 4 + 1]?.fee;
yz01SumRow.getCell(yz01Num * 7 + 6).value = numberFormatter(data.fee, 2);
}
}
ml_sheet.spliceRows(6, 6); ml_sheet.spliceRows(6, 7);
ml_sheet.spliceRows(6, 1); ml_sheet.spliceRows(6, 1);
yz01_sheet.spliceRows(2, 1);
// 合并说明 // 合并说明
let yz01_lastCol;
if (yz01Num) { if (yz01Num) {
for (let i = 0; i < yz01Num; i++) { for (let i = 0; i < yz01Num; i++) {
yz01_sheet.getRow(1).getCell(i * 7 + 4).value = `${data.contracts[i * 4].name}预算\n(元)`; yz01_sheet.getRow(1).getCell(i * 7 + 4).value = `${data.contracts[i * 4].name}预算(元)`;
yz01_sheet.getRow(1).getCell(i * 7 + 4).value = `${data.contracts[i * 4 + 1].name}预算\n(元)`; yz01_sheet.getRow(1).getCell(i * 7 + 4 + 1).value = `${data.contracts[i * 4 + 1].name}预算(元)`;
yz01_sheet.getRow(1).getCell(i * 7 + 4).value = `${data.contracts[i * 4 + 2].name}预算\n(元)`; yz01_sheet.getRow(1).getCell(i * 7 + 4 + 2).value = `${data.contracts[i * 4 + 2].name}预算(元)`;
if (i == yz01Num - 1 && yz01Mod == 0) { if (i == yz01Num - 1 && yz01Mod == 0) {
yz01_sheet.getRow(1).getCell(i * 7 + 4).value = `预算小计\n(元)`; yz01_sheet.getRow(1).getCell(i * 7 + 4 + 3).value = `预算小计(元)`;
yz01_lastCol = i * 7 + 4;
} else { } else {
yz01_sheet.getRow(1).getCell(i * 7 + 4).value = `${data.contracts[i * 4 + 3].name}预算\n(元)`; yz01_sheet.getRow(1).getCell(i * 7 + 4 + 3).value = `${data.contracts[i * 4 + 3].name}预算(元)`;
} }
yz01_sheet.mergeCells(6, i * 7 + 2, 6, i * 7 + 7); yz01_sheet.mergeCells(allServices.length + endRows + 3, i * 7 + 2, allServices.length + endRows + 3, i * 7 + 7);
yz01_sheet.getRow(allServices.length + endRows + 3).getCell(i * 7 + 2).border.right = { style: 'thin' };
} }
} }
if (yz01Mod) { if (yz01Mod) {
for (let i = 0; i < yz01Mod; i++) { for (let i = 0; i < yz01Mod; i++) {
if (i == yz01Mod - 1) { if (i == yz01Mod - 1) {
yz01_sheet.getRow(1).getCell(yz01Num * 7 + 4 + i).value = `预算小计\n(元)`; yz01_sheet.getRow(1).getCell(yz01Num * 7 + 4 + i).value = `预算小计(元)`;
yz01_lastCol = yz01Num * 7 + 4 + i;
} else { } else {
yz01_sheet.getRow(1).getCell(yz01Num * 7 + 4 + i).value = `${data.contracts[yz01Num * 4 + i].name}预算\n(元)`; yz01_sheet.getRow(1).getCell(yz01Num * 7 + 4 + i).value = `${data.contracts[yz01Num * 4 + i].name}预算(元)`;
} }
} }
yz01_sheet.mergeCells(6, yz01Num * 7 + 2, 6, yz01Num * 7 + 3 + yz01Mod); yz01_sheet.mergeCells(allServices.length + endRows + 3, yz01Num * 7 + 2, allServices.length + endRows + 3, yz01Num * 7 + 3 + yz01Mod);
yz01_sheet.getRow(allServices.length + endRows + 3).getCell(yz01Num * 7 + 2).border.right = { style: 'thin' };
} }
ml_sheet.mergeCells(ml_slotRow - 7, 1, ml_slotRow - 7, 4); yz01_sheet.getRow(allServices.length + endRows + 3).height = 100;
// for (let i = 1; i <= allServices.length + endRows + 3; i++) {
// yz01_sheet.getRow(i).getCell(yz01_lastCol + 1).value = ' ';
// if (yz01_sheet.getRow(i).getCell(yz01_lastCol + 1).style.font) {
// yz01_sheet.getRow(i).getCell(yz01_lastCol + 1).style.font.size = i == 1 ? 22 : 20;
// } else {
// yz01_sheet.getRow(i).getCell(yz01_lastCol + 1).style = { font: { size: i == 1 ? 22 : 20 } };
// // }
// // }
// yz01_sheet.pageSetup.printArea = `A1:${yz01_sheet.getRow(allServices.length + endRows + 3).getCell(yz01_lastCol)._address}`;
ml_sheet.mergeCells(ml_slotRow - 8, 1, ml_slotRow - 8, 4);
workbook.removeWorksheet('预i-1表'); workbook.removeWorksheet('预i-1表');
workbook.removeWorksheet('预i-2表'); workbook.removeWorksheet('预i-2表');
@ -1023,9 +1437,10 @@ async function generateTemplate(data) {
workbook.removeWorksheet('预i-3表'); workbook.removeWorksheet('预i-3表');
workbook.removeWorksheet('预i-4表'); workbook.removeWorksheet('预i-4表');
workbook.removeWorksheet('预i-4-1表'); workbook.removeWorksheet('预i-4-1表');
workbook.getWorksheet('辅01表').orderNo = ml_number + 2 + 10; workbook.removeWorksheet('预i-5表');
workbook.getWorksheet('辅02表').orderNo = ml_number + 3 + 10; workbook.getWorksheet('辅01表').orderNo = ml_number + 2 + 11;
workbook.getWorksheet('辅03表').orderNo = ml_number + 4 + 10; workbook.getWorksheet('辅02表').orderNo = ml_number + 3 + 11;
workbook.getWorksheet('辅03表').orderNo = ml_number + 4 + 11;
workbook._worksheets.forEach(sheet => { workbook._worksheets.forEach(sheet => {
if (sheet) { if (sheet) {
@ -1063,7 +1478,7 @@ function cusInsertRowFunc(insertRowNum, sourceRows, worksheet, RowFun, cellFun)
// targetCell.value = cell.value; // 复制内容 // targetCell.value = cell.value; // 复制内容
// 复制样式 // 复制样式
if (cell.style) { if (cell.style) {
targetCell.style = { ...cell.style }; targetCell.style = JSON.parse(JSON.stringify(cell.style));
} }
if (cellFun) { if (cellFun) {
@ -1082,16 +1497,14 @@ function copyWorksheet(workbook, sourceName, targetName) {
if (!source) throw new Error("Source sheet not found"); if (!source) throw new Error("Source sheet not found");
const target = workbook.addWorksheet(targetName, { const target = workbook.addWorksheet(targetName, {
properties: { ...source.properties }, properties: JSON.parse(JSON.stringify(source.properties || {})),
pageSetup: { ...source.pageSetup }, pageSetup: JSON.parse(JSON.stringify(source.pageSetup || {})),
views: source.views ? JSON.parse(JSON.stringify(source.views)) : [], views: source.views ? JSON.parse(JSON.stringify(source.views || {})) : [],
}); });
/* 复制页眉页脚(关键补充) */ /* 复制页眉页脚(关键补充) */
if (source.headerFooter) { if (source.headerFooter) {
target.headerFooter = JSON.parse( target.headerFooter = JSON.parse(JSON.stringify(source.headerFooter));
JSON.stringify(source.headerFooter)
);
} }
/* 复制合并单元格 */ /* 复制合并单元格 */