电话
400 9058 355
JavaScript 无原生 PDF 生成 API,需依赖 jsPDF(适合文字/简单图形)或 pdf-lib(适合修改现有 PDF);浏览器中通过 Blob + URL.createObjectURL 预览,复杂场景应交由后端如 puppeteer 处理。
JavaScript 本身没有原生 API 生成 PDF,必须依赖第三方库;浏览器环境无法直接写文件系统,所有“生成 PDF”实际是生成二进制 Blob 并触发下载或嵌入预览。
jsPDF 生成基础 PDF 文档jsPDF 是最轻量、兼容性最好的选择,适合文字+简单图形场景。注意它不解析 HTML,html() 方法需配合 html2canvas 才能转 DOM,且性能差、样式支持有限。
npm install jspdf(ESM)或通过 CDN 加载 https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js
const doc = new jspdf.jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' });
doc.text('Hello World', 20, 30);
doc.save('document.pdf');(会触发浏览器下载)const blob = doc.output('blob');
pdf-lib 修改已有 PDF 或插入动态内容pdf-lib 不渲染页面,只操作 PDF 结构,适合填表、签名、合并、加水印等后端或前端高级操作。它不能从零画图,但可加载现有 PDF 并修改字段、插入图像、追加页。
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const form = pdfDoc.getForm(); const field = form.getTextField('name'); field.setText('Alice');
pdfDoc.embedPng() 或 embedJpg()):const image = await pdfDoc.embedPng(pngBytes); page.drawImage(image, { x: 50, y: 50, width: 100 });
const bytes = await pdfDoc.save();(返回 Uint8Array)直接用 URL.createObjectURL() 创建临时 URL,再交由

或 渲染。不要用 window.open(),部分浏览器会拦截。
pdfBytes 是 Uint8Array 或 Blob:const blob = new Blob([pdfBytes], { type: 'application/pdf' }); const url = URL.createObjectURL(blob);
document.getElementById('pdf-viewer').src = url;(对应 )URL.revokeObjectURL(url);(尤其在频繁生成时)iframe 中的 PDF 渲染有缓存 bug,可加时间戳参数绕过:url + '?t=' + Date.now()
前端生成 PDF 在复杂排版、中文字体、页眉页脚、分页控制上非常脆弱。真正稳定的做法是把数据发给后端,用 Node.js 的 pdfmake、puppeteer(渲染 HTML 为 PDF)或 Python 的 weasyprint 处理。
puppeteer 最接近“所见即所得”:await page.goto('data:text/html,' + encodeURIComponent(html), { waitUntil: 'networkidle0' }); const pdf = await page.pdf({ format: 'A4' });
puppeteer 需显式指定字体路径;pdfmake 需提前注册 ttf 字体对象PDF 生成不是“调一个函数就完事”的事情,字体嵌入、分页逻辑、表单交互、打印适配这些环节,任何一个没对齐都会导致用户打不开或内容错位。别迷信“纯前端一键生成”,先想清楚你到底要的是“能看就行的快照”,还是“能归档签字的正式文档”。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...