From adef7b5af2e7581dc4a63f7e4789a2f2615738d8 Mon Sep 17 00:00:00 2001 From: a273825743 Date: Sat, 16 May 2026 12:48:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0Excel=E8=AE=B0=E8=B4=A6?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=94=9F=E6=88=90=E8=84=9A=E6=9C=AC=E5=92=8C?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E5=85=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package.json | 1 + .../public/templates/财务记账导入模板.xlsx | Bin 0 -> 30656 bytes backend/scripts/generate-excel-template.js | 292 ++++++++++++++++++ .../public/templates/财务记账导入模板.xlsx | Bin 0 -> 30656 bytes frontend/src/pages/admin/ExcelImport.tsx | 6 +- 5 files changed, 298 insertions(+), 1 deletion(-) create mode 100644 backend/public/templates/财务记账导入模板.xlsx create mode 100644 backend/scripts/generate-excel-template.js create mode 100644 frontend/public/templates/财务记账导入模板.xlsx diff --git a/backend/package.json b/backend/package.json index 5798675..5f0cf6a 100644 --- a/backend/package.json +++ b/backend/package.json @@ -12,6 +12,7 @@ "cors": "^2.8.6", "cos-nodejs-sdk-v5": "^2.15.4", "dotenv": "^16.6.1", + "exceljs": "^4.4.0", "express": "^4.18.2", "express-validator": "^7.3.1", "jsonwebtoken": "^9.0.3", diff --git a/backend/public/templates/财务记账导入模板.xlsx b/backend/public/templates/财务记账导入模板.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..308a655c7392035ffbf0039a6c91eff66934aed7 GIT binary patch literal 30656 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 r.name); + + const categoryResult = await db.query('SELECT * FROM expense_categories WHERE is_active = true ORDER BY category_level1, sort_order'); + const categories = categoryResult.rows; + + const incomeCategories = categories.filter(c => c.category_level1 === 'income').map(c => c.label); + const projectCategories = categories.filter(c => c.category_level1 === 'project').map(c => c.label); + const companyCategories = categories.filter(c => c.category_level1 === 'company').map(c => c.label); + + // ========== Sheet2: 项目名称列表 ========== + const sheet2 = workbook.addWorksheet('项目列表', { + properties: { tabColor: { argb: '4472C4' } } + }); + + sheet2.getColumn(1).width = 40; + sheet2.getCell('A1').value = '项目名称'; + sheet2.getCell('A1').font = { bold: true, size: 12, color: { argb: 'FFFFFF' } }; + sheet2.getCell('A1').fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: '4472C4' } }; + sheet2.getCell('A1').alignment = { horizontal: 'center' }; + + projectNames.forEach((name, i) => { + const cell = sheet2.getCell(`A${i + 2}`); + cell.value = name; + cell.border = { bottom: { style: 'thin', color: { argb: 'D9D9D9' } } }; + }); + + sheet2.getCell('C1').value = '收支类型'; + sheet2.getCell('C1').font = { bold: true }; + ['收入', '支出'].forEach((v, i) => { sheet2.getCell(`C${i + 2}`).value = v; }); + + sheet2.getCell('D1').value = '一级分类'; + sheet2.getCell('D1').font = { bold: true }; + ['收入', '项目支出', '公司支出'].forEach((v, i) => { sheet2.getCell(`D${i + 2}`).value = v; }); + + sheet2.getCell('F1').value = '收入分类'; + sheet2.getCell('F1').font = { bold: true }; + incomeCategories.forEach((v, i) => { sheet2.getCell(`F${i + 2}`).value = v; }); + + sheet2.getCell('G1').value = '项目支出分类'; + sheet2.getCell('G1').font = { bold: true }; + projectCategories.forEach((v, i) => { sheet2.getCell(`G${i + 2}`).value = v; }); + + sheet2.getCell('H1').value = '公司支出分类'; + sheet2.getCell('H1').font = { bold: true }; + companyCategories.forEach((v, i) => { sheet2.getCell(`H${i + 2}`).value = v; }); + + sheet2.getCell('J1').value = '币种'; + sheet2.getCell('J1').font = { bold: true }; + ['CNY', 'LAK', 'USD', 'THB'].forEach((v, i) => { sheet2.getCell(`J${i + 2}`).value = v; }); + + sheet2.getCell('K1').value = '对方类型'; + sheet2.getCell('K1').font = { bold: true }; + ['供应商', '分包商', '客户', '员工', '物流公司', '股东', '其他'].forEach((v, i) => { sheet2.getCell(`K${i + 2}`).value = v; }); + + const projectListEnd = Math.max(projectNames.length + 1, 2); + const categoryListEnd = Math.max(incomeCategories.length, projectCategories.length, companyCategories.length) + 1; + + // ========== Sheet1: 记账主表 ========== + const sheet1 = workbook.addWorksheet('财务记账', { + properties: { tabColor: { argb: '52C41A' } } + }); + + const headers = [ + { key: 'date', header: '日期', width: 13 }, + { key: 'txn_type', header: '收支类型', width: 11 }, + { key: 'level1', header: '一级分类', width: 11 }, + { key: 'level2', header: '二级分类', width: 14 }, + { key: 'project', header: '项目名称', width: 35 }, + { key: 'amount', header: '金额', width: 14 }, + { key: 'currency', header: '币种', width: 8 }, + { key: 'rate', header: '汇率', width: 10 }, + { key: 'amount_cny', header: '等效人民币', width: 14 }, + { key: 'counterparty', header: '对方名称', width: 18 }, + { key: 'counterparty_type', header: '对方类型', width: 10 }, + { key: 'user', header: '人员姓名', width: 10 }, + { key: 'desc', header: '描述', width: 30 }, + { key: 'voucher', header: '凭证编号', width: 14 }, + ]; + + sheet1.columns = headers; + + const headerRow = sheet1.getRow(1); + headerRow.height = 28; + headerRow.eachCell((cell) => { + cell.font = { bold: true, size: 11, color: { argb: 'FFFFFF' } }; + cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: '4472C4' } }; + cell.alignment = { horizontal: 'center', vertical: 'middle' }; + cell.border = { + top: { style: 'thin' }, bottom: { style: 'thin' }, + left: { style: 'thin' }, right: { style: 'thin' } + }; + }); + + sheet1.views = [{ state: 'frozen', ySplit: 1 }]; + + const dataRows = 500; + for (let i = 2; i <= dataRows + 1; i++) { + const row = sheet1.getRow(i); + + // I列: 等效人民币 = 金额 × 汇率(自动计算) + const cnyCell = row.getCell(9); + cnyCell.value = { formula: `F${i}*H${i}` }; + cnyCell.numFmt = '#,##0.00'; + cnyCell.protection = { locked: true }; + + // 金额列格式 + row.getCell(6).numFmt = '#,##0.00'; + // 汇率列格式 + row.getCell(8).numFmt = '0.000000'; + + // 日期列格式 + row.getCell(1).numFmt = 'YYYY-MM-DD'; + + // 交替行背景色 + if (i % 2 === 0) { + row.eachCell({ includeEmpty: true }, (cell) => { + cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'F2F7FB' } }; + }); + } + + // 边框 + row.eachCell({ includeEmpty: true }, (cell) => { + cell.border = { + bottom: { style: 'thin', color: { argb: 'D9D9D9' } }, + vertical: { style: 'thin', color: { argb: 'D9D9D9' } } + }; + }); + } + + // 数据验证 - 收支类型 + sheet1.getDataValidator = function() {}; + for (let i = 2; i <= dataRows + 1; i++) { + // B列: 收支类型 + sheet1.getCell(`B${i}`).dataValidation = { + type: 'list', + allowBlank: true, + formulae: ['"收入,支出"'], + showErrorMessage: true, + errorTitle: '输入错误', + error: '请从下拉列表中选择:收入 或 支出' + }; + + // C列: 一级分类 + sheet1.getCell(`C${i}`).dataValidation = { + type: 'list', + allowBlank: true, + formulae: ['"收入,项目支出,公司支出"'], + showErrorMessage: true, + errorTitle: '输入错误', + error: '请从下拉列表中选择' + }; + + // D列: 二级分类(收入+项目+公司 全部列出,用户根据一级分类选择对应的) + const allCategories = [...incomeCategories, ...projectCategories, ...companyCategories]; + const catStr = allCategories.join(','); + sheet1.getCell(`D${i}`).dataValidation = { + type: 'list', + allowBlank: true, + formulae: [`"${catStr}"`], + showErrorMessage: true, + errorTitle: '输入错误', + error: '请从下拉列表中选择二级分类' + }; + + // E列: 项目名称(从Sheet2引用) + sheet1.getCell(`E${i}`).dataValidation = { + type: 'list', + allowBlank: true, + formulae: [`项目列表!$A$2:$A$${projectListEnd}`], + showErrorMessage: true, + errorTitle: '输入错误', + error: '请从下拉列表中选择项目名称' + }; + + // G列: 币种 + sheet1.getCell(`G${i}`).dataValidation = { + type: 'list', + allowBlank: true, + formulae: ['"CNY,LAK,USD,THB"'], + showErrorMessage: true, + errorTitle: '输入错误', + error: '请选择币种:CNY / LAK / USD / THB' + }; + + // K列: 对方类型 + sheet1.getCell(`K${i}`).dataValidation = { + type: 'list', + allowBlank: true, + formulae: ['"供应商,分包商,客户,员工,物流公司,股东,其他"'], + showErrorMessage: true, + errorTitle: '输入错误', + error: '请从下拉列表中选择对方类型' + }; + + // H列: 汇率 - CNY时自动填1 + // A列: 日期验证 + sheet1.getCell(`A${i}`).dataValidation = { + type: 'date', + allowBlank: true, + operator: 'greaterThan', + formulae: [new Date(2020, 0, 1)], + showErrorMessage: true, + errorTitle: '日期格式错误', + error: '请输入有效日期,格式:YYYY-MM-DD' + }; + } + + // 示例数据(第2行) + const exampleRow = sheet1.getRow(2); + exampleRow.getCell(1).value = new Date(2026, 2, 15); + exampleRow.getCell(2).value = '支出'; + exampleRow.getCell(3).value = '项目支出'; + exampleRow.getCell(4).value = '材料采购'; + exampleRow.getCell(5).value = projectNames[0] || ''; + exampleRow.getCell(6).value = 150000; + exampleRow.getCell(7).value = 'CNY'; + exampleRow.getCell(8).value = 1; + exampleRow.getCell(10).value = '云南XX电力器材有限公司'; + exampleRow.getCell(11).value = '供应商'; + exampleRow.getCell(13).value = '采购190×12m电杆50根'; + + // 示例数据(第3行) + const exampleRow2 = sheet1.getRow(3); + exampleRow2.getCell(1).value = new Date(2026, 2, 20); + exampleRow2.getCell(2).value = '支出'; + exampleRow2.getCell(3).value = '项目支出'; + exampleRow2.getCell(4).value = '食宿费用'; + exampleRow2.getCell(5).value = projectNames[0] || ''; + exampleRow2.getCell(6).value = 100000; + exampleRow2.getCell(7).value = 'LAK'; + exampleRow2.getCell(8).value = 0.0003; + exampleRow2.getCell(10).value = 'XX招待所'; + exampleRow2.getCell(11).value = '其他'; + exampleRow2.getCell(12).value = '李四'; + exampleRow2.getCell(13).value = '3月驻现场住宿费'; + + // 示例数据(第4行) + const exampleRow3 = sheet1.getRow(4); + exampleRow3.getCell(1).value = new Date(2026, 1, 20); + exampleRow3.getCell(2).value = '收入'; + exampleRow3.getCell(3).value = '收入'; + exampleRow3.getCell(4).value = '项目合同收款'; + exampleRow3.getCell(5).value = projectNames[0] || ''; + exampleRow3.getCell(6).value = 300000; + exampleRow3.getCell(7).value = 'CNY'; + exampleRow3.getCell(8).value = 1; + exampleRow3.getCell(10).value = '老挝国家电力公司'; + exampleRow3.getCell(11).value = '客户'; + exampleRow3.getCell(13).value = '合同首付款30%'; + + // 保护工作表(锁定I列公式) + sheet1.protect('', { + selectLockedCells: true, + selectUnlockedCells: true, + formatCells: true, + formatColumns: true, + formatRows: true, + insertRows: true, + insertColumns: false, + deleteRows: false, + deleteColumns: false, + sort: true, + autoFilter: true, + }); + + // 设置可编辑列的单元格为未锁定 + for (let i = 2; i <= dataRows + 1; i++) { + [1,2,3,4,5,6,7,8,10,11,12,13,14].forEach(col => { + sheet1.getRow(i).getCell(col).protection = { locked: false }; + }); + } + + const outputPath = path.join(__dirname, '..', 'public', 'templates', '财务记账导入模板.xlsx'); + const fs = require('fs'); + fs.mkdirSync(path.dirname(outputPath), { recursive: true }); + + await workbook.xlsx.writeFile(outputPath); + console.log('✅ Excel模板已生成:', outputPath); + return outputPath; +} + +generateTemplate().then(() => process.exit(0)).catch(e => { console.error(e); process.exit(1); }); diff --git a/frontend/public/templates/财务记账导入模板.xlsx b/frontend/public/templates/财务记账导入模板.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..308a655c7392035ffbf0039a6c91eff66934aed7 GIT binary patch literal 30656 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 { + + + + {parsedData.length > 0 && ( <>