更新报表导出功能

This commit is contained in:
ForeverSmiYng 2026-03-13 18:35:22 +08:00
parent e761558307
commit 7f03559bfd
2 changed files with 137 additions and 10 deletions

View File

@ -644,6 +644,7 @@ async function generateTemplate(data) {
let allAddtional = {}; let allAddtional = {};
let allReserve = {}; let allReserve = {};
let allMajors = {}; let allMajors = {};
let allServiceMajors = new Set();
data.scale?.forEach(sci => { data.scale?.forEach(sci => {
allMajors[sci.major] = { [data.contracts.length]: sci }; allMajors[sci.major] = { [data.contracts.length]: sci };
}); });
@ -999,6 +1000,7 @@ async function generateTemplate(data) {
}; };
}); });
allDet.forEach((m, mindex) => { allDet.forEach((m, mindex) => {
allServiceMajors.add(m.major);
let majorX = majorList[m.major]; 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++;
@ -1762,17 +1764,25 @@ async function generateTemplate(data) {
// 更新编制说明 // 更新编制说明
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
// ctx.font = "12pt 宋体"; // const pageMaxHei = 733;
// const maxTitleWidth = 336;
// const maxTextWidth = 720;
const pageMaxHei = 733;
// 20.25 25.5 33.75 // 20.25 25.5 33.75
const titleHeiDet = { fir: 11.25, els: 22.5 }; const titleHeiDet = { fir: 11.25, els: 22.5 };
const textHeiDet = { fir: 6.75, els: 13.5 }; const textHeiDet = { fir: 6.75, els: 13.5 };
const descSheet = workbook.getWorksheet('编制说明'); const descSheet = workbook.getWorksheet('编制说明');
descSheet.getRow(1).getCell(1).value = data.name; let descRowNum = 1;
let descRowNum = 5; let titleArr = paragraphLineBreakFor1112(data.name, ctx, 0);
descSheet.getRow(descRowNum).getCell(1).value = titleArr[0];
descRowNum++;
if (titleArr.length > 1) {
for (let i = 1; i < titleArr.length; i++) {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = titleArr[i];
});
}
}
descRowNum += 3;
if (data.scale?.length) { if (data.scale?.length) {
let engCosts = data.scale.filter(f => f.major > 6 && majorList[f.major].hasCost); let engCosts = data.scale.filter(f => f.major > 6 && majorList[f.major].hasCost);
if (engCosts.length) { if (engCosts.length) {
@ -1827,8 +1837,18 @@ async function generateTemplate(data) {
otherCosts.forEach(sci => { otherCosts.forEach(sci => {
desc.push(`${majorList[sci.major].name}${Number(sci.cost).toLocaleString()}万元`); desc.push(`${majorList[sci.major].name}${Number(sci.cost).toLocaleString()}万元`);
}); });
descSheet.getRow(descRowNum).getCell(1).value = descSheet.getRow(descRowNum).getCell(1).value + `${desc.join('')}`; let text = descSheet.getRow(descRowNum).getCell(1).value + `${desc.join('')}`;
let textArr = paragraphLineBreakFor1112(text, ctx);
descSheet.getRow(descRowNum).getCell(1).value = textArr[0];
descRowNum++; descRowNum++;
if (textArr.length > 1) {
for (let i = 1; i < textArr.length; i++) {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = textArr[i];
});
}
}
} else { } else {
descSheet.spliceRows(descRowNum, 1); descSheet.spliceRows(descRowNum, 1);
} }
@ -1836,6 +1856,38 @@ async function generateTemplate(data) {
descSheet.spliceRows(descRowNum, 5); descSheet.spliceRows(descRowNum, 5);
descRowNum++; descRowNum++;
} }
descRowNum++;
if (allServiceMajors.size > 0) {
if (allServiceMajors.has(7) || allServiceMajors.has(18) || allServiceMajors.has(28)) {
descSheet.getRow(descRowNum).getCell(1).value = descSheet.getRow(descRowNum).getCell(1).value + '本次委托包括全部工程及费用。';
descRowNum++;
} else {
let majorTexts = [];
let hasOther = false;
allServiceMajors.forEach(mid => {
if (mid > 6) {
majorTexts.push(majorList[mid].name);
} else {
hasOther = true;
}
});
let text = descSheet.getRow(descRowNum).getCell(1).value + '本项目的' + majorTexts.join('、') + (hasOther ? '及其他专项工程。' : '。');
let textArr = paragraphLineBreakFor1112(text, ctx);
descSheet.getRow(descRowNum).getCell(1).value = textArr[0];
descRowNum++;
if (textArr.length > 1) {
for (let i = 1; i < textArr.length; i++) {
cusInsertRowFunc(descRowNum, [descSheet.getRow(descRowNum - 1)], descSheet, (targetRow) => {
descRowNum++;
targetRow.getCell(1).value = textArr[i];
});
}
}
}
} else {
descSheet.getRow(descRowNum).getCell(1).value = descSheet.getRow(descRowNum).getCell(1).value + '×××××。';
}
return workbook; return workbook;
} catch (error) { } catch (error) {
console.log(error) console.log(error)
@ -1843,6 +1895,83 @@ async function generateTemplate(data) {
} }
} }
function paragraphLineBreakFor1112(paragraph, ctx, type = 1) {// 仅适用于内容为11或12号字体的段落
// // number,最后判断是否数字
// const numberNoBreak1 = /\d[\d,]*(?:\.\d+)?$/;
// const numberNoBreak2 = /^[\d,]*\.*\d+/;
// // number&unit
// const numberUnitNoBreak1 = /\d[\d,]*(?:\.\d+)?\s*(?:[a-zA-Z](?:[a-zA-Z\d·/]*[a-zA-Z\d])?)?$/;
// const numberUnitNoBreak2 = /^[\d,]*(?:\.\d+)?\s*[a-zA-Z](?:[a-zA-Z\d·/]*[a-zA-Z\d])?/;
// // 英文单词
// const ewordNoBreak1 = /[a-zA-Z]+$/;
// const ewordNoBreak2 = /^[a-zA-Z]+/;
/*
西
*/
const matchASCIIChar1 = /[\x21-\x7E]+$/;
const matchASCIIChar2 = /^[\x21-\x7E]+/;
/*
1.
2.12
3.12
*/
const forbidLineSta1 = /^[,.。、:;!?)\]\})〕]}〉》」』】〗〙〛”’」』﹂﹄%‰℃°—–~·]/;
const forbidLineSta2 = /[,.。、:;!?)\]\})〕]}〉》」』】〗〙〛”’」』﹂﹄%‰℃°—–~·]$/;
/*
1.()
2.12
*/
const forbidLineEnd = /[¥$€£@([{(〔[{〈《「『【〖〘〚“‘「『﹁﹃—–~·]+$/;
ctx.font = "12pt 宋体";
const maxWidth = type == 1 ? 720 : 336;
const minChar = Math.ceil(maxWidth / 8);
let text = paragraph;
let res = [];
// let enterRows = new Set();
while (ctx.measureText(text).width > maxWidth) {
let t1 = text.slice(0, minChar);
let t1PX = ctx.measureText(t1).width;
while (t1PX > maxWidth) {
let t1MinChar = Math.floor((t1PX - maxWidth) / 16) || 1;
t1 = t1.slice(0, -1 * t1MinChar);
t1PX = ctx.measureText(t1).width;
}
let t2 = text.slice(t1.length);
if (matchASCIIChar1.test(t1) && matchASCIIChar2.test(t2)) {
let strASCII1 = t1.match(matchASCIIChar1)[0];
if (strASCII1.length < t1.length) {
t1 = t1.slice(0, -1 * strASCII1.length);
t2 = text.slice(t1.length);
// enterRows.add(res.length);
}
}
if (forbidLineSta1.test(t2)) {
if (forbidLineSta2.test(t1)) {
t1 = t1.slice(0, -2);
} else {
t1 = t1.slice(0, -1);
}
t2 = text.slice(t1.length);
// enterRows.add(res.length);
}
if (forbidLineEnd.test(t1)) {
let endTrans = t1.match(forbidLineEnd)[0];
t1 = t1.slice(0, -1 * (Math.min(endTrans.length, 2)));
t2 = text.slice(t1.length);
// enterRows.add(res.length);
}
res.push(t1);
text = text.slice(t1.length);
}
res.push(text);
// [...enterRows].forEach(ri => {
// res[ri] = res[ri] + '\n';
// });
return res;
}
// 在指定位置插入行,并按模板行复制样式,可选回调填充值。 // 在指定位置插入行,并按模板行复制样式,可选回调填充值。
function cusInsertRowFunc(insertRowNum, sourceRows, worksheet, RowFun, cellFun) { function cusInsertRowFunc(insertRowNum, sourceRows, worksheet, RowFun, cellFun) {
@ -1968,5 +2097,3 @@ function cloneCellValue(value) {
} }
return value; return value;
} }