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

Laravel中无需Imagick为上传PDF每页添加条形码方案问询

替代Imagick的Laravel PDF每页添加条形码方案

原方案问题分析

  • 依赖系统级软件Imagick/Ghostscript,部署成本高
  • 转图片再转回PDF的流程效率低,大PDF(60+页)易触发超时
  • 中间生成大量临时图片,占用额外磁盘资源

替代方案:纯PHP PDF操作(FPDI+TCPDF)

核心思路:直接导入原PDF的每一页,在PDF层面叠加条形码,无需图片转换,配合Laravel队列异步处理避免超时。

步骤1:安装依赖

composer require setasign/fpdi-tcpdf  # 用于导入并编辑已有PDF
composer require picqer/php-barcode-generator  # 生成条形码

步骤2:创建队列任务(异步处理大PDF)

创建app/Jobs/AddBarcodeToPdf.php,负责核心的条码添加逻辑:

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use setasign\Fpdi\Tcpdf\Fpdi;
use Picqer\Barcode\BarcodeGeneratorPNG;
use Illuminate\Support\Facades\Storage;

class AddBarcodeToPdf implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $attachmentId;

    public function __construct($attachmentId)
    {
        $this->attachmentId = $attachmentId;
    }

    public function handle()
    {
        $model = \App\Models\Attachment::findOrFail($this->attachmentId);
        $originalPdfPath = storage_path('app/3pagerpdf/pdf/' . $model->pdf_file_name_in_datebase);
        $outputFileName = time() . '_barcode_' . $model->pdf_file_name_in_datebase;
        $outputPdfPath = storage_path('app/3pagerpdf/modified/' . $outputFileName);

        // 初始化PDF编辑器
        $pdf = new Fpdi();
        $totalPages = $pdf->setSourceFile($originalPdfPath);

        // 条形码生成器
        $barcodeGenerator = new BarcodeGeneratorPNG();

        // 遍历每一页添加条码
        for ($pageNum = 1; $pageNum <= $totalPages; $pageNum++) {
            // 导入原PDF页面
            $templateId = $pdf->importPage($pageNum);
            $pageSize = $pdf->getTemplateSize($templateId);
            
            // 创建新页面(与原页面尺寸一致)
            $pdf->AddPage($pageSize['orientation'], [$pageSize['width'], $pageSize['height']]);
            $pdf->useTemplate($templateId);

            // 生成每页唯一的条码数据(可自定义规则)
            $barcodeData = "DOC-{$model->id}-PAGE-{$pageNum}";
            $barcodeImageContent = $barcodeGenerator->getBarcode($barcodeData, $barcodeGenerator::TYPE_CODE_128);
            
            // 临时保存条码图片
            $tempBarcodePath = storage_path('app/temp/barcode_' . $pageNum . '.png');
            Storage::put('temp/barcode_' . $pageNum . '.png', $barcodeImageContent);

            // 设置条码位置:右下角,边距10px(可调整)
            $xPos = $pageSize['width'] - 100; // 条码宽度约100px
            $yPos = $pageSize['height'] - 50; // 条码高度约50px

            // 将条码添加到PDF页面
            $pdf->Image($tempBarcodePath, $xPos, $yPos, 90); // 宽度90px,高度自适应

            // 清理临时文件
            Storage::delete('temp/barcode_' . $pageNum . '.png');
        }

        // 保存处理后的PDF
        $pdf->Output($outputPdfPath, 'F');

        // 更新数据库记录
        $model->modified_pdf_path = "3pagerpdf/modified/{$outputFileName}";
        $model->save();
    }
}

步骤3:修改上传接口,触发异步任务

public function uploadPdf(Request $request)
{
    $model = new \App\Models\Attachment();
    if ($request->hasFile('pdf_file_from_request')) {
        // 建议清理旧文件而非删除整个目录
        $pdfFile = $request->file('pdf_file_from_request');
        $fileName = time() . '.' . $pdfFile->getClientOriginalName();
        Storage::putFileAs('3pagerpdf/pdf', $pdfFile, $fileName);
        
        $model->pdf_file_name_in_datebase = $fileName;
        $model->save();

        // 触发队列任务,异步处理条码添加
        \App\Jobs\AddBarcodeToPdf::dispatch($model->id);

        flash()->addSuccess('PDF上传成功,条码处理已启动,请稍后查看结果。');
        return back();
    }

    flash()->addError('未选择PDF文件');
    return back();
}

方案优势

  • 无系统依赖:仅需PHP Composer包,无需安装Imagick/Ghostscript
  • 高效处理:直接操作PDF页面,避免图片转换的性能损耗,60+页PDF处理速度提升明显
  • 避免超时:用Laravel队列异步处理,脱离HTTP请求超时限制
  • 资源友好:无大量临时图片文件,磁盘占用低

注意事项

  • 确保storage/app/3pagerpdf/modified和storage/app/temp目录存在且有写入权限
  • 根据需求调整条码的位置、大小、类型(支持CODE_128、EAN-13等多种格式)
  • 配置Laravel队列驱动(如Database、Redis),并启动队列监听:php artisan queue:work
  • 可在队列任务中添加错误捕获和重试逻辑,提升稳定性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 19:10:39