如何在Laravel开发的网页中添加可供用户下载的PDF文件
Laravel实现PDF文档访客下载功能流程
1. 静态PDF资源准备
- 提前将需要供下载的PDF文件上传到项目的
storage/app/public/downloads目录(没有downloads目录可以手动新建) - 执行命令
php artisan storage:link,将storage的公开目录映射到项目public目录下,生成可公开访问的软链接 - 确认storage目录权限设置为755,保证web服务运行用户有文件读取权限
2. 路由定义
根据你的业务需求选择对应路由方案:
公开无限制下载路由
在routes/web.php中添加如下代码:
Route::get('/download/pdf/{filename}', function (string $filename) { // 路径校验,防止恶意遍历读取其他文件 $filePath = storage_path('app/public/downloads/' . $filename); if (!file_exists($filePath)) { abort(404, '请求的PDF资源不存在'); } // 返回下载响应,第二个参数为用户下载时显示的文件名 return response()->download($filePath, $filename, [ 'Content-Type' => 'application/pdf' ]); })->name('pdf.download');
带权限校验的下载路由
如果需要登录、付费等条件才能下载,给路由加上对应中间件即可:
Route::get('/download/pdf/{filename}', function (string $filename) { // 上方文件校验、响应逻辑不变 })->middleware('auth') // 这里加你需要的权限中间件 ->name('pdf.download');
3. 前端页面添加入口
在需要展示下载按钮的Blade模板中添加下载链接:
- 支持用户选择预览或下载的版本:
<a href="{{ route('pdf.download', ['filename' => '你的文档名称.pdf']) }}" target="_blank" class="你的按钮样式类"> 下载PDF文档 </a>
- 点击直接触发下载,不打开预览的版本:
<a href="{{ route('pdf.download', ['filename' => '你的文档名称.pdf']) }}" download class="你的按钮样式类"> 直接下载PDF文档 </a>
4. 动态生成PDF下载方案(非提前上传场景)
如果需要根据业务数据实时生成PDF提供下载,可以使用laravel-dompdf扩展实现:
- 安装扩展:执行命令
composer require barryvdh/laravel-dompdf - 新建PDF内容模板:在
resources/views/pdf目录下新建template.blade.php,编写PDF的内容结构(支持Blade语法渲染变量) - 路由代码示例:
use Barryvdh\DomPDF\Facade\Pdf; Route::get('/download/generate-pdf', function () { // 传入PDF需要的业务数据 $data = [ 'title' => '动态PDF文档', 'content' => '这里是PDF的具体内容' ]; $pdf = Pdf::loadView('pdf.template', $data); // 直接触发下载 return $pdf->download('动态生成的文档.pdf'); })->name('pdf.generate.download');
前端入口调用逻辑和静态PDF的方式一致。
常见问题修复
- 中文文件名下载乱码:在返回下载响应时对文件名做编码处理,修改响应代码为:
return response()->download($filePath, rawurlencode($filename), [ 'Content-Type' => 'application/pdf' ]);
- 软链接生效但无法访问文件:检查
storage/app/public/downloads目录的权限是否正确,确认web运行用户(www-data、nginx等)有该目录的读取权限。
内容的提问来源于stack exchange,提问作者Aicha Nana
相关产品推荐
相关产品推荐

