本文目录导读:

- 方案一:前端图表库 + 导出图片(最推荐,最灵活)
- 方案二:纯后端生成(PHP + 无头浏览器)
- 方案三:使用PHP的GD库 / ImageMagick(不推荐用于复杂图表)
- 方案四:利用现成的报告引擎(适合复杂报告)
- 总结:如何选择?
在PHP项目中实现图表导出,通常有后端生成图片和前端导出两种主流方案,由于PHP本身不擅长直接绘图(虽然可以用GD库,但实现复杂且不美观),实际开发中主要依赖以下四种方式:
前端图表库 + 导出图片(最推荐,最灵活)
这是目前最主流的方式,前端使用 ECharts、Highcharts 或 Chart.js 渲染图表,然后利用浏览器API将图表转换为图片。
工作流程:
- 后端(PHP):提供图表数据(JSON/API)。
- 前端:接收数据,使用 ECharts 渲染图表。
- 前端:用户点击导出,使用
canvas.toDataURL()生成 Base64 图片。 - 传输:将 Base64 图片通过 AJAX 发送到后端 PHP 保存或下载。
核心代码示例(前端):
// 导出 ECharts 图表
document.getElementById('exportBtn').addEventListener('click', function() {
var chart = echarts.getInstanceByDom(document.getElementById('main'));
// 生成 base64 图片 (png)
var imgBase64 = chart.getDataURL({
type: 'png', // 或 'jpeg'
pixelRatio: 2, // 高清导出
backgroundColor: '#fff'
});
// 方式1: 直接下载 (前端)
var link = document.createElement('a');
link.href = imgBase64;
link.download = 'chart.png';
link.click();
// 方式2: 发给 PHP 后端保存/处理
fetch('/save-chart.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ image: imgBase64, filename: 'chart.png' })
}).then(res => res.json()).then(data => console.log(data));
});
后端接收并保存(PHP):
<?php
// save-chart.php
$data = json_decode(file_get_contents('php://input'), true);
$imageData = $data['image']; // 格式如 "data:image/png;base64,iVBORw0KGgo..."
// 过滤掉 data:image/png;base64, 前缀
$imageData = explode(',', $imageData);
$imageData = $imageData[1] ?? '';
// 解码并保存
$image = base64_decode($imageData);
$filename = 'exported_' . time() . '.png';
file_put_contents($filename, $image);
echo json_encode(['success' => true, 'file' => $filename]);
优点:
- 图表美观:前端库渲染能力强(动画、交互、3D)。
- 开发简单:无需在PHP中写复杂绘图逻辑。
- 交互性好:用户可预览再导出。
缺点:
- 依赖浏览器环境(不能完全在纯后端CLI脚本中导出)。
- 对复杂后端自动化场景(如定时生成报告)不够直接。
纯后端生成(PHP + 无头浏览器)
适用于需要后端自动生成图表图片(如邮件报告、定时任务)的场景。
方案A:PHP调用 PhantomJS(已停产)/ Puppeteer(Node.js)
常见做法是 PHP 通过 exec() 或 shell_exec() 调用 Node.js 脚本,使用 Puppeteer 打开一个渲染了 ECharts 的 HTML 文件并截图。
工作流程:
- 局部安装 Node.js + Puppeteer。
- PHP 创建一个临时的 HTML 文件,内嵌 ECharts 和你的数据。
- PHP 执行
node generateChart.js temp.html output.png。 - Node.js 脚本用 Puppeteer 打开 HTML,等待图表渲染完毕,截图保存为 PNG。
PHP 调用代码:
<?php
function generateChartImage($dataJson, $outputPath) {
// 1. 生成临时 HTML
$htmlTemplate = '<!DOCTYPE html><html><head><script src="echarts.min.js"></script></head><body><div id="main" style="width:800px;height:600px;"></div><script>var data = ' . $dataJson . '; var chart = echarts.init(document.getElementById("main")); chart.setOption({...your chart config using data});</script></body></html>';
file_put_contents('temp_chart.html', $htmlTemplate);
// 2. 调用 Node.js 脚本截图
$command = "node screenshot.js temp_chart.html $outputPath 2>&1";
$output = shell_exec($command);
// 清理临时文件
unlink('temp_chart.html');
return $output;
}
Node.js (screenshot.js):
const puppeteer = require('puppeteer');
const args = process.argv.slice(2);
const htmlFile = args[0];
const outputPath = args[1];
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('file://' + __dirname + '/' + htmlFile);
// 等待图表渲染(关键)
await page.waitForTimeout(2000);
await page.screenshot({ path: outputPath, fullPage: false });
await browser.close();
})();
方案B:使用 图表库服务端渲染包 有一些库可以脱离浏览器渲染图表,
- jsPDF + html2canvas:类似方案一,但用 Node.js 服务端模拟。
- Vega-Lite / Apache ECharts 的 Node.js 版本:官方有
echarts/echarts-for-ssr。npm install echarts
可以直接在 Node.js 里生成 SVG 字符串,然后转 PNG。
优点: 完全自动化,无浏览器界面要求。 缺点: 需要额外安装 Node.js 环境;Puppeteer 内存占用较大;截图质量依赖于等待时间。
使用PHP的GD库 / ImageMagick(不推荐用于复杂图表)
适合极简单的柱状图、折线图(如服务端监控面板)。
<?php // 使用 GD 库画一个简单的柱状图(非常繁琐) $width = 600; $height = 400; $image = imagecreatetruecolor($width, $height); // ... 需要手动计算坐标、画线、画矩形、写文字 ... // 对于饼图、雷达图等复杂图形,GD库几乎不可用
优点: PHP自带,无需额外组件。 缺点: 开发量大、效果差、不支持交互、不支持复杂图表(如散点图、地图、3D图)。
利用现成的报告引擎(适合复杂报告)
如果在做统计报告、PDF报表,可以考虑以下PHP库:
- KoolReport:PHP 报表框架,内置
\koolreport\export\Excel、\koolreport\export\PDF,支持将渲染的图表直接输出为图片嵌入文档。 - PhpSpreadsheet + Chart:虽然主要用于Excel,但可以在Excel单元格中嵌入图表并导出为图片格式。
如何选择?
| 应用场景 | 推荐方案 |
|---|---|
| Web端用户手动导出 | 前端库导出Base64图(最快、最稳、最漂亮) |
| 后端定时任务/自动生成报表 | Puppeteer截图(效果好,需Node环境)或 ECharts SSR方案(更轻量) |
| 只需简单柱状图/线图 | GD库(如果不想装Node环境) |
| 生成PDF/Excel报告 | KoolReport / PhpSpreadsheet |
最佳实践建议: 如果项目面向用户(如后台管理),强烈使用方案一,前端工程师维护图表样式,后端 PHP 只需接收 Base64 字符串并保存即可,职责清晰,性能最好。