You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 02:46:04