Node.js中如何从Tally导出单张凭证为HTML或直接获取PDF?
问题解决:从Tally获取单张凭证的HTML/PDF(Node.js环境)
Tally本身不支持直接导出单张凭证为PDF,但可以通过调整XML请求参数获取和记账凭证视图一致的HTML,再转成PDF缓冲区;也可以通过定制TDL实现直接生成PDF的需求,具体方案如下:
一、修正XML请求,获取匹配视图的HTML
你当前的XML请求因为类型和报表名称设置错误,导致返回的HTML不符合预期,调整后的请求如下:
<ENVELOPE> <HEADER> <VERSION>1</VERSION> <TALLYREQUEST>EXPORT DATA</TALLYREQUEST> <TYPE>Report</TYPE> <SUBTYPE>Accounting Voucher View</SUBTYPE> </HEADER> <BODY> <DESC> <STATICVARIABLES> <SVEXPORTFORMAT>$$SysName:HTML</SVEXPORTFORMAT> <SVFROMDATE>20240701</SVFROMDATE> <SVTODATE>20240701</SVTODATE> <SVVOUCHERNUMBER>SS/0</SVVOUCHERNUMBER> <SVCURRENTCOMPANY>comp name</SVCURRENTCOMPANY> </STATICVARIABLES> <FETCHLIST> <FETCH>Date</FETCH> <FETCH>VoucherNumber</FETCH> <FETCH>VoucherTypeName</FETCH> <FETCH>PartyName</FETCH> <FETCH>Amount</FETCH> </FETCHLIST> </DESC> </BODY> </ENVELOPE>
关键调整点:
- 把
<TYPE>从Object改为Report,因为要导出的是凭证视图报表,不是单个凭证对象 - 用
<STATICVARIABLES>里的SVFROMDATE/SVTODATE+SVVOUCHERNUMBER精准定位单张凭证,替代原来的<ID>标签 - 确保
<SVEXPORTFORMAT>和<SUBTYPE>与目标视图匹配
这个请求会返回和Tally界面完全一致的记账凭证HTML,包含完整布局和数据。
二、Node.js中把HTML转成PDF缓冲区
拿到HTML后,用puppeteer(渲染效果更稳定)转成PDF缓冲区,再发送给前端下载:
const puppeteer = require('puppeteer'); async function htmlToPdfBuffer(html) { const browser = await puppeteer.launch({ headless: 'new' }); const page = await browser.newPage(); // 等待页面完全加载,确保样式和内容渲染完成 await page.setContent(html, { waitUntil: 'networkidle0' }); const pdfBuffer = await page.pdf({ format: 'A4', printBackground: true, // 保留HTML中的背景样式 margin: { top: '20px', right: '20px', bottom: '20px', left: '20px' } }); await browser.close(); return pdfBuffer; } // 调用示例(假设已拿到Tally返回的HTML) // htmlToPdfBuffer(tallyHtml).then(buffer => { // res.setHeader('Content-Type', 'application/pdf'); // res.setHeader('Content-Disposition', 'attachment; filename="voucher-SS0.pdf"'); // res.send(buffer); // });
三、TDL定制实现直接从Tally生成PDF(可选)
如果想跳过HTML转PDF的步骤,直接让Tally生成PDF,需要编写TDL代码自定义报表:
1. 编写TDL文件(比如SingleVoucher.tdl)
[Report: Single Voucher PDF Export] Use: Accounting Voucher View Filter: VoucherNumber = $$String:SVVOUCHERNUMBER Export Format: PDF Export File: $$Path:Temp\Voucher_$$String:SVVOUCHERNUMBER.pdf
2. 通过XML请求加载TDL到Tally
<ENVELOPE> <HEADER> <VERSION>1</VERSION> <TALLYREQUEST>IMPORT DATA</TALLYREQUEST> <TYPE>TDL</TYPE> </HEADER> <BODY> <TDL> <TDLFILE> <LOAD>SingleVoucher.tdl</LOAD> </TDLFILE> </TDL> </BODY> </ENVELOPE>
3. 触发报表导出并读取PDF文件
发送XML请求执行自定义报表,然后读取Tally生成的PDF文件(注意要确保Node.js服务有权限访问Tally所在服务器的Temp目录)。
内容的提问来源于stack exchange,提问作者Ghosty
相关产品推荐
相关产品推荐

