
本文详解如何使用 fabric.js 将 canvas 中的图形、文本、图片等对象导出为高质量 pdf 文件,涵盖客户端 json 序列化、服务端(php)pdf 生成及常见避坑指南。
本文详解如何使用 fabric.js 将 canvas 中的图形、文本、图片等对象导出为高质量 pdf 文件,涵盖客户端 json 序列化、服务端(php)pdf 生成及常见避坑指南。
Fabric.js 提供了完整的序列化与反序列化能力,可将画布状态导出为标准 JSON,再通过服务端或客户端方案生成 PDF。推荐采用“前端导出 JSON → 后端渲染 PDF”的混合方案,兼顾兼容性、样式保真度与服务器可控性。
✅ 正确导出 Fabric 画布为 JSON
Fabric.js 原生支持 toJSON() 方法,无需额外插件即可完整导出所有对象及其属性(含位置、缩放、滤镜、文本样式、SVG 路径等):
// 获取当前画布完整状态(含所有对象)
const canvasData = canvas.toJSON(['selectable', 'evented', 'name']); // 可选:自定义保留字段
// 发送至 PHP 后端
fetch('/export-to-pdf.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ canvas: canvasData })
});⚠️ 注意:
toJSON()默认不包含selectable、evented等交互属性,如需保留(例如用于后续编辑),应显式传入字段名数组(如上例),否则后端还原时可能丢失行为配置。
✅ PHP 后端生成 PDF(推荐使用 TCPDF 或 Dompdf)
以 TCPDF 为例(轻量、支持 SVG 渲染、兼容 Fabric 导出的 SVG 路径):
// export-to-pdf.php
require_once('tcpdf/tcpdf.php');
$data = json_decode(file_get_contents('php://input'), true);
$canvasJson = $data['canvas'] ?? [];
// 创建 TCPDF 实例(A4 纵向,mm 单位)
$pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->addPage();
// 将 Fabric JSON 转为 SVG 字符串(可借助 fabricjs-server 或自定义转换器)
// 简化示例:若已预渲染为 SVG(见下文建议),直接嵌入
$svgContent = generateSvgFromFabricJson($canvasJson); // 自定义函数,详见说明
// 使用 TCPDF 内置 SVG 支持渲染(需启用 SVG 解析)
$pdf->writeHTMLCell(0, 0, '', '', '<svg xmlns="http://www.w3.org/2000/svg" width="595" height="842">' . $svgContent . '</svg>', 0, 1, 0, true, '', true);
// 输出 PDF(浏览器下载)
$pdf->Output('fabric-export.pdf', 'D');? 提示:Fabric 官方 Demo Import PDF 展示了反向流程(PDF → Fabric),但其核心逻辑——即利用
fabric.loadSVGFromString()和toSVG()方法——同样适用于导出。更可靠的做法是:
- 前端调用
canvas.toSVG()生成 SVG 字符串(保真度高,支持渐变/阴影/文字路径);- 直接 POST SVG 到 PHP,用 TCPDF 的
ImageSVG()或writeHTML()渲染,避免 JSON → 对象 → SVG 的多层转换误差。
✅ 推荐优化路径(零依赖、高保真)
// 前端一步到位:导出为 SVG(含 viewBox 适配 A4)
const svg = canvas.toSVG({
width: 595, // A4 宽度(mm → px 按 96dpi ≈ 595px)
height: 842, // A4 高度
suppressPreamble: true
});
// 发送 SVG 字符串(非 JSON!更简洁、更稳定)
fetch('/render-pdf.php', {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
body: svg
});后端只需解析该 SVG 并嵌入 PDF,大幅降低数据失真风险。
? 总结与注意事项
- ❌ 避免混淆:Fabric 画布本身不是 HTML
<canvas></canvas>的原始绘图内容,而是 Fabric 对象模型,因此不能用toDataURL()直接截图(会丢失矢量精度、缩放失真、模糊文字); - ✅ 优先选择
toSVG()+ 服务端 SVG 渲染,兼顾质量、性能与跨平台一致性; - ✅ 若必须用 JSON 流程,请确保后端有完整 Fabric-like 渲染引擎(如 Node.js + fabricjs-server),PHP 原生不支持 Fabric 运行时;
- ? 参考权威资源:Fabric.js 官方 Demos 中的 “Export” 类示例均基于
toJSON()/toSVG(),切勿在标题中误加 “HTML” —— Fabric 画布是 JS 对象模型,与 HTML Canvas API 有本质区别。



















