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

Node.js环境使用jsPDF的html方法报ReferenceError: document未定义

Node.js环境使用jsPDF生成PDF报错ReferenceError: document is not defined的解决办法

问题描述

在Node.js环境中使用jsPDF的html()方法从HTML模板生成PDF时,触发以下错误:

ReferenceError: document is not defined

相关代码:

generatePdf(formEntryId: string, customerId: string): ArrayBuffer {
    const template = this.templateService.getTemplate('testPdf')
    const doc = new jsPDF()
    doc.html(template, {
       callback: function (doc) {
       doc.save('testFile.pdf')
    }
  })
  return doc.output('arraybuffer')
}

错误原因

jsPDF的html()方法内部依赖浏览器环境的document对象解析、渲染HTML内容,但Node.js作为服务端运行环境不存在浏览器DOM对象,因此触发该错误。同时原代码存在异步问题:doc.html()是异步操作,直接在其后返回doc.output()会得到未完成渲染的空白PDF。

解决方案

方案一:使用Puppeteer(推荐,支持复杂HTML/CSS)

Puppeteer是无头Chrome工具,可完整模拟浏览器环境渲染HTML,生成的PDF兼容性和还原度更高。

  1. 安装依赖:
npm install puppeteer
  1. 修改代码(改为异步函数):
async function generatePdf(formEntryId: string, customerId: string): Promise<ArrayBuffer> {
    const template = this.templateService.getTemplate('testPdf');
    // 启动无头浏览器
    const browser = await puppeteer.launch({ headless: 'new' });
    const page = await browser.newPage();
    // 加载HTML模板
    await page.setContent(template);
    // 生成PDF,开启背景渲染确保样式完整
    const pdfBuffer = await page.pdf({ 
        format: 'A4',
        printBackground: true
    });
    await browser.close();
    // 转换为ArrayBuffer返回
    return pdfBuffer.buffer as ArrayBuffer;
}

方案二:使用jsdom模拟DOM环境(适合简单HTML)

通过jsdom模拟浏览器DOM环境,配合canvas库让jsPDF可解析HTML。

  1. 安装依赖:
npm install jsdom jspdf canvas
  1. 修改代码:
import jsPDF from 'jspdf';
import { JSDOM } from 'jsdom';
import canvas from 'canvas';

// 注入模拟的浏览器环境
const dom = new JSDOM('');
global.document = dom.window.document;
global.window = dom.window as any;
global.HTMLCanvasElement = canvas.HTMLCanvasElement;

async function generatePdf(formEntryId: string, customerId: string): Promise<ArrayBuffer> {
    const template = this.templateService.getTemplate('testPdf');
    const doc = new jsPDF();
    // 等待HTML渲染完成
    await doc.html(template);
    // 生成并返回ArrayBuffer
    return doc.output('arraybuffer');
}

注意事项

  • Node.js环境中无法直接使用doc.save()触发浏览器下载,需将PDF的Buffer/ArrayBuffer返回给前端,由前端处理下载逻辑。
  • 若HTML模板包含外部资源(如CSS、图片),需确保资源可被Puppeteer或jsdom访问(本地资源用绝对路径,远程资源确保网络可达)。

内容的提问来源于stack exchange,提问作者user2450639

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:27:32