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

如何将Fabric Canvas对象导出为PDF?含PHP方案及导出JSON问题求助

Fabric.js Canvas导出JSON及转PDF解决方案

一、先搞定Fabric.js导出JSON的问题

首先得确认你的Fabric Canvas实例是正常初始化的,比如:

const canvas = new fabric.Canvas('你的canvas元素ID');

导出JSON其实很简单,用Fabric自带的方法就行:

// 导出包含所有元素完整信息的JSON
const fullJson = JSON.stringify(canvas.toJSON());
// 要是想精简体积,用这个导出无冗余数据的版本
const datalessJson = JSON.stringify(canvas.toDatalessJSON());

要是导出失败,先排查这几个坑:

  • 有没有正确创建Canvas实例?别让变量被覆盖或者没初始化就调用方法
  • 画布里的图片是不是跨域的?如果是,加载图片时要设置crossOrigin: 'anonymous',不然会因为安全限制导出失败
  • 试试换个稳定版的Fabric.js,比如v5.x,某些旧版本可能有导出bug

二、PHP转PDF的实现流程

拿到JSON后,通过后端转PDF可以这么做:

  1. 把JSON传给PHP后端
    用AJAX提交就行,比如:
    fetch('/convert-pdf.php', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: fullJson
    });
    
  2. PHP端解析并生成PDF
    推荐用TCPDF或者FPDF,这里拿TCPDF举例子:
    • 先解析前端传过来的JSON:
      $fabricData = json_decode(file_get_contents('php://input'), true);
      
    • 初始化PDF实例:
      require_once('tcpdf/tcpdf.php');
      $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
      $pdf->AddPage();
      
    • 遍历Fabric的元素,逐个画到PDF里:
      Fabric的JSON里每个元素都有type字段(比如rect、text、image),对应不同的绘制逻辑:
      foreach ($fabricData['objects'] as $obj) {
        switch ($obj['type']) {
          case 'rect':
            // 绘制矩形
            $pdf->Rect($obj['left'], $obj['top'], $obj['width'], $obj['height'], 'F', '', $obj['fill']);
            break;
          case 'text':
            // 绘制文字,注意颜色和字号转换
            $pdf->SetFont('dejavusans', '', $obj['fontSize']);
            $rgb = hexdec(substr($obj['fill'],1,2)).','.hexdec(substr($obj['fill'],3,2)).','.hexdec(substr($obj['fill'],5,2));
            $pdf->SetTextColor(...explode(',', $rgb));
            $pdf->Text($obj['left'], $obj['top'], $obj['text']);
            break;
          case 'image':
            // 处理图片:把base64转成临时文件再插入
            $imgBase64 = str_replace('data:image/png;base64,', '', $obj['src']);
            $imgContent = base64_decode($imgBase64);
            $tempPath = tempnam(sys_get_temp_dir(), 'fabric_img');
            file_put_contents($tempPath, $imgContent);
            $pdf->Image($tempPath, $obj['left'], $obj['top'], $obj['width'], $obj['height']);
            unlink($tempPath); // 用完删掉临时文件
            break;
          // 其他元素类型比如circle、path,照着上面的逻辑扩展就行
        }
      }
      
    • 最后输出下载PDF:
      $pdf->Output('canvas-export.pdf', 'D');
      

三、前端直接转PDF的替代方案

要是不想折腾后端,直接用html2canvas+jsPDF在前端搞定也可以:

// 先装依赖:npm install jspdf html2canvas
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';

// 把Canvas转成图片再生成PDF
html2canvas(document.getElementById('你的canvas元素ID')).then(canvas => {
  const imgData = canvas.toDataURL('image/png');
  const pdf = new jsPDF('p', 'mm', 'a4');
  const imgWidth = 210; // A4宽度
  const imgHeight = (canvas.height * imgWidth) / canvas.width;
  let remainingHeight = imgHeight;
  let yPosition = 0;

  // 第一页
  pdf.addImage(imgData, 'PNG', 0, yPosition, imgWidth, imgHeight);
  remainingHeight -= 297; // A4高度

  // 长图分页处理
  while (remainingHeight >= 0) {
    yPosition = remainingHeight - imgHeight;
    pdf.addPage();
    pdf.addImage(imgData, 'PNG', 0, yPosition, imgWidth, imgHeight);
    remainingHeight -= 297;
  }

  pdf.save('canvas-export.pdf');
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 04:57:33