在Laravel项目开发中,图片转PDF是很常见的需求,不管是用户上传的多张证件照生成归档文件,还是商品图批量输出为宣传册,都需要稳定高效的转换实现。接下来会介绍两种主流的实现方案,并且给出完整的落地步骤。

方案对比
目前Laravel中实现图片转PDF主要有两种主流方案,开发者可以根据自身服务器环境和需求选择:
| 方案 | 依赖组件 | 优势 | 适用场景 |
|---|---|---|---|
| spatie/pdf package | spatie/browsershot、puppeteer | 转换效果好,支持复杂样式,无需额外图像库 | 需要自定义PDF样式、添加水印等场景 |
| Imagick扩展 | PHP Imagick扩展 | 轻量高效,转换速度快,服务器资源占用低 | 仅需简单拼接图片生成PDF的场景 |
方案一:使用spatie/pdf相关包实现
环境准备
首先需要在项目中安装对应的扩展包,同时保证服务器已经安装了Node.js和puppeteer依赖:
# 安装spatie的PDF生成包 composer require spatie/laravel-pdf # 发布配置文件 php artisan vendor:publish --provider="Spatie\LaravelPdf\PdfServiceProvider" # 安装browsershot依赖 composer require spatie/browsershot
实现代码
创建对应的Blade模板用于渲染PDF内容,模板中直接插入需要转换的图片:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图片转PDF</title>
<style>
.img-item {
width: 100%;
margin-bottom: 20px;
}
</style>
</head>
<body>
@foreach($images as $image)
<img src="{{ $image }}" class="img-item" />
@endforeach
</body>
</html>然后在控制器中编写转换逻辑:
<?php
namespace App\Http\Controllers;
use Spatie\LaravelPdf\Facades\Pdf;
use Illuminate\Http\Request;
class ImageToPdfController extends Controller
{
public function convert(Request $request)
{
// 获取上传的图片路径,假设是多图上传
$images = $request->input('images', []);
// 如果没有上传图片,返回错误提示
if (empty($images)) {
return response()->json(['code' => 400, 'msg' => '请上传需要转换的图片']);
}
// 生成PDF
$pdf = Pdf::view('pdf.image_template', ['images' => $images])
->format('a4')
->orientation('portrait')
->name('image_convert_' . time() . '.pdf');
// 可以直接下载或者保存到服务器
// 保存到服务器示例
$savePath = storage_path('app/public/pdfs/' . $pdf->getName());
$pdf->save($savePath);
return response()->json(['code' => 200, 'msg' => '转换成功', 'path' => $savePath]);
}
}方案二:使用Imagick扩展实现
环境准备
首先确保服务器已经安装了ImageMagick和PHP的Imagick扩展,可以通过php -m命令查看是否存在imagick扩展,如果没有则需要先安装对应扩展。
实现代码
Imagick的实现逻辑更轻量,不需要额外的模板渲染,直接操作图像对象即可:
<?php
namespace App\Http\Controllers;
use Imagick;
use Illuminate\Http\Request;
class ImageToPdfController extends Controller
{
public function convertByImagick(Request $request)
{
$images = $request->input('images', []);
if (empty($images)) {
return response()->json(['code' => 400, 'msg' => '请上传需要转换的图片']);
}
try {
$imagick = new Imagick();
// 遍历所有图片,逐个读取
foreach ($images as $imagePath) {
$imagick->readImage($imagePath);
}
// 设置PDF格式
$imagick->setImageFormat('pdf');
// 设置PDF的页面大小,这里设置为A4
$imagick->setPage(595, 842, 0, 0);
// 保存路径
$savePath = storage_path('app/public/pdfs/image_' . time() . '.pdf');
// 写入文件
$imagick->writeImages($savePath, true);
// 清除资源
$imagick->clear();
$imagick->destroy();
return response()->json(['code' => 200, 'msg' => '转换成功', 'path' => $savePath]);
} catch (\Exception $e) {
return response()->json(['code' => 500, 'msg' => '转换失败:' . $e->getMessage()]);
}
}
}注意事项
- 如果使用spatie方案,需要保证服务器可以正常访问puppeteer的依赖,部分云服务器可能需要配置无头浏览器环境
- 使用Imagick方案时,注意图片路径的权限问题,确保PHP进程可以读取到图片文件
- 转换大尺寸图片时,建议先对图片进行压缩处理,避免生成过大的PDF文件影响加载速度
- 如果需要添加水印、页码等额外内容,优先选择spatie方案,通过Blade模板可以灵活自定义样式
常见问题处理
如果遇到转换后的PDF图片模糊的问题,可以在spatie方案中设置更高的渲染分辨率:
$pdf = Pdf::view('pdf.image_template', ['images' => $images])
->format('a4')
->orientation('portrait')
// 设置分辨率为300DPI,提升清晰度
->resolution(300)
->name('high_quality_' . time() . '.pdf');如果是Imagick转换后图片方向错误,可以在读取图片后调用setImageOrientation方法调整方向,比如设置为正常方向:
$imagick->readImage($imagePath); // 设置图片方向为正常 $imagick->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
Laravel图片转PDFspatie_pdfimagickPHP修改时间:2026-06-05 07:58:19