批量导出与打印

工资条 · 对账单 · 凭证批量生成
工资条批量生成
对账单批量生成
凭证批量打印
${htmlContent}`; const blob=new Blob(['\ufeff'+doc],{type:'application/msword'}); const url=URL.createObjectURL(blob);const a=document.createElement('a');a.href=url;a.download=filename+'.doc';a.click();URL.revokeObjectURL(url); } // ===== Salary Slip ===== let salaryData=[],salaryCols=[],selectedSalaryCols=[]; function loadSalary(){ const file=fileState['salaryFile'];if(!file){alert('请上传工资表');return} readXlsx(file,(err,data)=>{ if(err){alert('解析失败');return} salaryCols=data[0].map(c=>String(c||'')); salaryData=data.slice(1).filter(r=>r.some(c=>c!=='')); selectedSalaryCols=[...salaryCols]; // default template columns const defaults=['姓名','部门','基本工资','岗位工资','绩效奖金','加班工资','应发工资','社保','公积金','个税','实发工资']; selectedSalaryCols=salaryCols.filter(c=>defaults.some(d=>c.includes(d)||d.includes(c))); if(selectedSalaryCols.length===0)selectedSalaryCols=salaryCols.slice(0,Math.min(6,salaryCols.length)); renderSalaryCols(); g('salaryStats').innerHTML=`${salaryCols.length} 列${salaryData.length} 条记录`; g('salaryStatsArea').classList.add('show'); }); } function renderSalaryCols(){ const box=g('salaryColCheckbox');if(!box)return; box.innerHTML=salaryCols.map(c=>``).join(''); } function toggleCol(col){ if(selectedSalaryCols.includes(col))selectedSalaryCols=selectedSalaryCols.filter(c=>c!==col); else selectedSalaryCols.push(col); renderSalaryCols(); } function selectAllCols(){selectedSalaryCols=[...salaryCols];renderSalaryCols()} function selectDefaultCols(){ const defaults=['姓名','部门','基本工资','岗位工资','绩效奖金','加班工资','应发工资','社保','公积金','个税','实发工资']; selectedSalaryCols=salaryCols.filter(c=>defaults.some(d=>c.includes(d)||d.includes(c))); if(selectedSalaryCols.length===0)selectedSalaryCols=salaryCols.slice(0,Math.min(6,salaryCols.length)); renderSalaryCols(); } function previewSalary(){ if(salaryData.length===0){alert('请先加载工资表');return} const company=g('salaryCompany').value||'XX有限公司',month=g('salaryMonth').value||'2025年1月'; let html='
共生成 '+salaryData.length+' 张工资条
'; salaryData.forEach((row,i)=>{ let slip=`
${company}
${month} 工资条
`; slip+=''; selectedSalaryCols.forEach(col=>{ const colIdx=salaryCols.indexOf(col),val=colIdx>=0?row[colIdx]:''; slip+=``; }); slip+='
${col}${val}
'; html+=slip; }); g('salaryPreview').innerHTML=html; g('salaryPreviewArea').classList.add('show'); g('exportSalaryRow').style.display='flex'; } function exportSalaryAll(){ if(salaryData.length===0)return; const company=g('salaryCompany').value||'XX有限公司',month=g('salaryMonth').value||'2025年1月'; let doc=''; salaryData.forEach((row,i)=>{ doc+=`

${company}

${month} 工资条

`; doc+=''; selectedSalaryCols.forEach(col=>{ const colIdx=salaryCols.indexOf(col),val=colIdx>=0?row[colIdx]:''; doc+=``; }); doc+='
${col}${val}

如有疑问请咨询人力资源部

'; }); downloadDocx(doc,`工资条_${month}`); } function printSalaryAll(){window.print()} function exportSalarySingle(i){ const company=g('salaryCompany').value||'XX有限公司',month=g('salaryMonth').value||'2025年1月'; const row=salaryData[i]; let doc=`

${company}

${month} 工资条

`; selectedSalaryCols.forEach(col=>{ const ci=salaryCols.indexOf(col),val=ci>=0?row[ci]:''; doc+=``; }); doc+='
${col}${val}

如有疑问请咨询人力资源部

'; downloadDocx(doc,`工资条_${row[salaryCols.indexOf('姓名')]||'员工'+(i+1)}`); } // ===== Statement ===== let statementData=[],statementCols=[]; let stmtTemplate='
对账单
客户:{客户名称}对账期间:{期间}

项目金额
期初余额{期初余额}
本期应收{本期应收}
本期已收{本期已收}
期末余额{期末余额}

制表日期:{日期}
'; function loadStatement(){ const file=fileState['stmtFile'];if(!file){alert('请上传数据文件');return} readXlsx(file,(err,data)=>{ if(err){alert('解析失败');return} statementCols=data[0].map(c=>String(c||'')); statementData=data.slice(1).filter(r=>r.some(c=>c!=='')); g('stmtStats').innerHTML=`${statementData.length} 条记录`; g('stmtStatsArea').classList.add('show'); }); } function generateStatements(){ if(statementData.length===0){alert('请先加载数据');return} const tmpl=g('stmtTemplate').value||stmtTemplate; const period=g('stmtPeriod').value||'2025年1月'; const date=new Date().toISOString().split('T')[0]; let html='
共生成 '+statementData.length+' 份对账单
'; const sheets=[]; statementData.forEach((row,i)=>{ let content=tmpl; // Replace placeholders statementCols.forEach(col=>{ const ci=statementCols.indexOf(col),val=ci>=0?String(row[ci]||''):''; content=content.replace(new RegExp(`\\{${col}\\}`,'g'),val); }); content=content.replace(/\{期间\}/g,period).replace(/\{日期\}/g,date); sheets.push({name:row[0]||'客户'+(i+1),content}); html+=`
${i+1}
${row[0]||'客户'+(i+1)}${statementCols.slice(1,4).map(c=>row[statementCols.indexOf(c)]).filter(Boolean).join(' | ')}
`; }); g('stmtList').innerHTML=html; g('stmtResultArea').classList.add('show'); g('stmtExportAllRow').style.display='flex'; window._stmtSheets=sheets; } function exportAllStatements(){ if(!window._stmtSheets)return; let doc=''; window._stmtSheets.forEach(s=>{doc+=`
${s.content}
`;}); downloadDocx(doc,'批量对账单'); } function exportSingleStmt(i){ if(!window._stmtSheets)return; downloadDocx(window._stmtSheets[i].content,`对账单_${window._stmtSheets[i].name}`); } // ===== Voucher ===== let voucherData=[],voucherCols=[]; const VOUCHER_TMPL=`
记 账 凭 证
日期:{日期}凭证号:{凭证号}附件:{附件} 张
摘要科目借方金额贷方金额数量单价
{摘要}{科目}{借方金额}{贷方金额}{数量}{单价}
制单人:{制单人}  审核人:{审核人}  记账人:{记账人}
`; function loadVoucher(){ const file=fileState['voucherFile'];if(!file){alert('请上传凭证数据');return} readXlsx(file,(err,data)=>{ if(err){alert('解析失败');return} voucherCols=data[0].map(c=>String(c||'')); voucherData=data.slice(1).filter(r=>r.some(c=>c!=='')); g('vStats').innerHTML=`${voucherData.length} 条凭证`; g('vStatsArea').classList.add('show'); g('vTemplateArea').style.display='block'; }); } function generateVouchers(){ if(voucherData.length===0){alert('请先加载凭证数据');return} const tmpl=g('voucherTemplate').value||VOUCHER_TMPL; const date=new Date().toISOString().split('T')[0]; let html='
共生成 '+voucherData.length+' 张凭证
'; const vouchers=[]; voucherData.forEach((row,i)=>{ let content=tmpl; voucherCols.forEach(col=>{ const ci=voucherCols.indexOf(col),val=ci>=0?String(row[ci]||''):''; content=content.replace(new RegExp(`\\{${col}\\}`,'g'),val); }); content=content.replace(/\{日期\}/g,date); vouchers.push(content); html+=`
${i+1}
${row[0]||'凭证'+(i+1)}${row.slice(1,4).filter(Boolean).join(' | ')}
`; }); g('voucherList').innerHTML=html; g('vResultArea').classList.add('show'); g('vExportAllRow').style.display='flex'; window._vouchers=vouchers; } function exportAllVouchers(){ if(!window._vouchers)return; let doc='';window._vouchers.forEach(v=>doc+=`
${v}
`); downloadDocx(doc,'批量记账凭证'); } function exportSingleVoucher(i){if(window._vouchers)downloadDocx(window._vouchers[i],`记账凭证_${i+1}`)} function printAllVouchers(){window.print()} // Templates const templates={ salary:`

工资条批量生成

上传工资表,选择要显示的列,一键生成所有员工工资条并导出 Word
${makeFileZone('salaryFile','上传工资表(Excel)')}
`, statement:`

对账单批量生成

上传客户数据表,自定义模板,批量生成每户对账单并导出 Word
${makeFileZone('stmtFile','上传客户对账数据(Excel,含客户名称、金额等列)')}
对账单模板(支持 {列名} 占位符)
模板中使用 {列名} 表示 Excel 中的对应列,如 {客户名称}{本期应收}。特殊占位符:{期间}{日期}
`, voucher:`

凭证批量打印

上传凭证数据表,批量生成标准记账凭证格式,支持导出 Word 或直接打印
${makeFileZone('voucherFile','上传凭证数据(Excel,含摘要/科目/金额等列)')}
` }; // Tab switch document.getElementById('tabs').addEventListener('click',e=>{ const tab=e.target.closest('.tab');if(!tab)return; document.querySelectorAll('.tab').forEach(t=>t.classList.remove('active')); tab.classList.add('active'); document.getElementById('mainContent').innerHTML=templates[tab.dataset.panel]; // Reset state fileState.salaryFile=null;fileState.stmtFile=null;fileState.voucherFile=null; salaryData=[];statementData=[];voucherData=[]; }); document.getElementById('mainContent').innerHTML=templates.salary; // Dynamic button show/hide for salary const origPreviewSalary=previewSalary; previewSalary=function(){ origPreviewSalary(); const allBtn=g('exportSalaryAllBtn'),printBtn=g('printAllBtn'); if(allBtn)allBtn.style.display='inline-block'; if(printBtn)printBtn.style.display='inline-block'; }; const origGenStmt=generateStatements; generateStatements=function(){ origGenStmt(); const b=g('stmtExportAllBtn');if(b)b.style.display='inline-block'; }; const origGenV=generateVouchers; generateVouchers=function(){ origGenV(); const eb=g('vExportAllBtn'),pb=g('vPrintAllBtn'); if(eb)eb.style.display='inline-block';if(pb)pb.style.display='inline-block'; }; const origLoadSal=loadSalary; loadSalary=function(){ origLoadSal(); const sel=g('salaryColSelect');if(sel)sel.style.display='block'; };