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

如何用TCPDF生成包含ECharts的PDF?现有方案遇阻求解决

生成含ECharts的PDF可行方案

方案1:ECharts转Base64图片,通过AJAX传给PHP生成PDF

这是兼容性最好的方案,避开TCPDF对复杂HTML/SVG的渲染缺陷:

  • 前端:用ECharts内置的getDataURL方法把图表转成base64格式图片
    // 初始化ECharts实例
    const myChart = echarts.init(document.getElementById('chart-container'));
    myChart.setOption(option); // 传入你的图表配置
    
    // 延迟确保图表渲染完成,根据复杂度调整时长
    setTimeout(() => {
      const chartBase64 = myChart.getDataURL({
        pixelRatio: 2, // 提高图片清晰度
        backgroundColor: '#fff'
      });
      // AJAX传递给PHP后端
      fetch('generate-pdf.php', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: `chart_img=${encodeURIComponent(chartBase64)}`
      }).then(res => res.json()).then(data => {
        window.open(data.pdf_url); // 打开生成的PDF
      });
    }, 500);
    
  • 后端PHP(generate-pdf.php):接收base64并生成PDF
    require_once('tcpdf/tcpdf.php');
    
    // 解析前端传来的base64图片
    $chartBase64 = urldecode($_POST['chart_img']);
    $chartBase64 = str_replace('data:image/png;base64,', '', $chartBase64);
    $chartData = base64_decode($chartBase64);
    
    // 生成临时图片文件
    $tempFile = tempnam(sys_get_temp_dir(), 'echart_') . '.png';
    file_put_contents($tempFile, $chartData);
    
    // 初始化TCPDF并插入图片
    $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
    $pdf->AddPage();
    $pdf->Image($tempFile, 10, 10, 190, 0, 'PNG', '', '', true, 300);
    
    // 输出PDF到服务器,或直接下载(将'F'改为'D')
    $pdfFileName = 'echart_report_' . time() . '.pdf';
    $pdf->Output($pdfFileName, 'F');
    
    // 返回PDF链接给前端
    echo json_encode(['pdf_url' => $pdfFileName]);
    
    // 清理临时文件
    unlink($tempFile);
    

方案2:用无头浏览器渲染完整页面生成PDF

适合需要多图表或复杂页面布局的场景,渲染效果最接近浏览器:

  • 步骤1:编写包含ECharts的HTML页面(chart-page.html)
    <!DOCTYPE html>
    <html>
    <head>
      <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    </head>
    <body>
      <div id="chart-container" style="width: 800px; height: 600px;"></div>
      <script>
        const myChart = echarts.init(document.getElementById('chart-container'));
        myChart.setOption({
          title: { text: 'ECharts 报表' },
          xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] },
          yAxis: { type: 'value' },
          series: [{ type: 'bar', data: [120, 200, 150, 80, 70, 110, 130] }]
        });
        // 标记图表渲染完成
        setTimeout(() => {
          window.__chartReady = true;
        }, 500);
      </script>
    </body>
    </html>
    
  • 步骤2:Node.js脚本(generate-pdf.js)用Puppeteer生成PDF
    const puppeteer = require('puppeteer');
    
    (async () => {
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      await page.goto('file://' + __dirname + '/chart-page.html', { waitUntil: 'networkidle0' });
      // 等待图表渲染完成
      await page.waitForFunction('window.__chartReady === true');
      // 生成PDF
      await page.pdf({
        path: 'echart_report.pdf',
        format: 'A4',
        printBackground: true // 保留背景色和样式
      });
      await browser.close();
    })();
    
  • 步骤3:PHP调用Node脚本(可选)
    // 执行Node脚本生成PDF
    exec('node generate-pdf.js', $output, $exitCode);
    if ($exitCode === 0) {
      // 输出PDF供下载
      header('Content-Type: application/pdf');
      header('Content-Disposition: attachment; filename="echart_report.pdf"');
      readfile('echart_report.pdf');
    } else {
      echo 'PDF生成失败';
    }
    

方案3:优化SSR生成的SVG兼容性(适配原有尝试)

如果坚持用ECharts SSR生成SVG,需处理TCPDF不支持的SVG特性:

  • 前端用ECharts SSR生成SVG字符串,通过AJAX传给PHP
  • PHP用SVG处理库(如SimpleSVG)预处理SVG,移除TCPDF不支持的标签(如<clipPath>)或属性
  • 将预处理后的SVG转成图片,再用TCPDF的Image方法插入;或尝试用TCPDF的ImageSVG方法直接嵌入(注意复杂图表仍可能出现渲染问题)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:57:43