PHP项目PDF页码如何批量添加生成

wen PHP项目 33

本文目录导读:

PHP项目PDF页码如何批量添加生成

  1. 方法一:使用FPDI + TCPDF(推荐)
  2. 方法二:使用MPDF库
  3. 方法三:使用命令行工具(适用于Bulk处理)
  4. 方法四:基于目录的批量处理类
  5. 安装依赖
  6. 推荐方案

我来为您介绍PHP项目中批量添加PDF页码的几种方法:

使用FPDI + TCPDF(推荐)

<?php
require_once('tcpdf/tcpdf.php');
require_once('fpdi/fpdi.php');
class PDFMerger extends FPDI {
    function addPageNumbers($sourceFile, $outputFile) {
        // 获取原PDF页数
        $pageCount = $this->setSourceFile($sourceFile);
        // 遍历每一页
        for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
            $templateId = $this->importPage($pageNo);
            $size = $this->getTemplateSize($templateId);
            // 创建新页面
            $this->AddPage($size['orientation'], array($size['width'], $size['height']));
            $this->useTemplate($templateId);
            // 设置页码样式
            $this->SetFont('helvetica', 'B', 10);
            $this->SetTextColor(0, 0, 0);
            // 在页面底部添加页码
            $pageNumText = "第 {$pageNo} 页 / 共 {$pageCount} 页";
            $this->SetY(-20);
            $this->SetX(0);
            $this->Cell(0, 10, $pageNumText, 0, 0, 'C');
        }
        // 输出文件
        $this->Output($outputFile, 'F');
    }
    // 批量处理PDF文件
    function batchAddPageNumbers($inputDir, $outputDir) {
        // 创建输出目录
        if (!is_dir($outputDir)) {
            mkdir($outputDir, 0777, true);
        }
        // 扫描PDF文件
        $files = glob($inputDir . '/*.pdf');
        foreach ($files as $file) {
            $filename = basename($file);
            $outputFile = $outputDir . '/numbered_' . $filename;
            echo "处理: {$filename}\n";
            // 重置FPDI
            $this->setSourceFile($file);
            $this->addPageNumbers($file, $outputFile);
            echo "已完成: {$outputFile}\n";
        }
    }
}
// 使用示例
$pdf = new PDFMerger();
$pdf->batchAddPageNumbers('./input', './output');

使用MPDF库

<?php
require_once __DIR__ . '/vendor/autoload.php';
use Mpdf\Mpdf;
class BatchPDFPageNumber {
    private $mpdf;
    public function __construct() {
        $this->mpdf = new Mpdf([
            'tempDir' => __DIR__ . '/tmp'
        ]);
    }
    public function addPageNumbers($inputFile, $outputFile) {
        // 读取源PDF
        $pageCount = $this->mpdf->setSourceFile($inputFile);
        for ($i = 1; $i <= $pageCount; $i++) {
            // 导入页面
            $templateId = $this->mpdf->importPage($i);
            $this->mpdf->AddPage();
            $this->mpdf->useTemplate($templateId);
            // 添加页码
            $this->mpdf->SetY(-15);
            $this->mpdf->SetFont('Arial', 'B', 9);
            $this->mpdf->Cell(0, 10, "Page {$i} of {$pageCount}", 0, 0, 'C');
        }
        // 保存输出
        $this->mpdf->Output($outputFile, 'F');
    }
    public function batchProcess($inputDir, $outputDir) {
        if (!is_dir($outputDir)) {
            mkdir($outputDir, 0777, true);
        }
        $pdfFiles = glob($inputDir . '/*.pdf');
        foreach ($pdfFiles as $pdfFile) {
            $filename = basename($pdfFile);
            $outputPath = $outputDir . '/numbered_' . $filename;
            echo "处理: {$filename}...\n";
            // 重置MPDF实例
            $this->mpdf = new Mpdf(['tempDir' => __DIR__ . '/tmp']);
            $this->addPageNumbers($pdfFile, $outputPath);
            echo "完成: {$outputPath}\n";
        }
    }
}
// 使用示例
$processor = new BatchPDFPageNumber();
$processor->batchProcess('./input_pdfs', './output_pdfs');

使用命令行工具(适用于Bulk处理)

<?php
class PDFBatchProcessor {
    // 使用Ghostscript添加页码
    public function gsAddPageNumbers($inputDir, $outputDir, $prefix = 'numbered_') {
        if (!is_dir($outputDir)) {
            mkdir($outputDir, 0777, true);
        }
        $files = glob($inputDir . '/*.pdf');
        foreach ($files as $file) {
            $filename = basename($file, '.pdf');
            $outputFile = $outputDir . '/' . $prefix . $filename . '.pdf';
            // Ghostscript命令添加页码
            $command = "gs -q -dBATCH -dNOPAUSE -sDEVICE=pdfwrite ";
            $command .= "-sOutputFile={$outputFile} ";
            $command .= "-c \"<< /PageNumFont /Helvetica /PageNumSize 10 ";
            $command .= "/PageNumPos (bottom center) /StartPage 1 >> setpagedevice\" ";
            $command .= "-f {$file}";
            exec($command, $output, $returnCode);
            if ($returnCode === 0) {
                echo "成功处理: {$filename}\n";
            } else {
                echo "处理失败: {$filename}\n";
            }
        }
    }
    // 使用PDFtk添加页码(需要安装PDFtk)
    public function pdftkAddPageNumbers($inputDir, $outputDir) {
        if (!is_dir($outputDir)) {
            mkdir($outputDir, 0777, true);
        }
        $files = glob($inputDir . '/*.pdf');
        $stampFile = __DIR__ . '/page_number_stamp.pdf';
        // 创建页码水印PDF(需要提前创建)
        foreach ($files as $file) {
            $filename = basename($file);
            $outputFile = $outputDir . '/numbered_' . $filename;
            // 使用PDFtk添加水印
            $command = "pdftk {$file} stamp {$stampFile} output {$outputFile}";
            exec($command, $output, $returnCode);
            if ($returnCode === 0) {
                echo "处理完成: {$filename}\n";
            }
        }
    }
}
// 使用示例
$processor = new PDFBatchProcessor();
$processor->gsAddPageNumbers('./input', './output');

基于目录的批量处理类

<?php
class AdvancedBatchPDFNumberer {
    private $options = [
        'font' => 'helvetica',
        'size' => 10,
        'style' => 'B',
        'position' => 'bottom', // bottom/top
        'align' => 'center',    // left/center/right
        'format' => '第 {current} 页 / 共 {total} 页',
        'margin_bottom' => 20
    ];
    public function __construct($options = []) {
        $this->options = array_merge($this->options, $options);
    }
    public function processDirectory($inputDir, $outputDir, $recursive = false) {
        if (!is_dir($outputDir)) {
            mkdir($outputDir, 0777, true);
        }
        $files = $recursive ? 
            $this->getAllPDFFiles($inputDir) : 
            glob($inputDir . '/*.pdf');
        $results = [];
        foreach ($files as $file) {
            $relativePath = str_replace($inputDir, '', $file);
            $outputPath = $outputDir . '/' . ltrim($relativePath, '/');
            // 创建输出目录
            $outputDirPath = dirname($outputPath);
            if (!is_dir($outputDirPath)) {
                mkdir($outputDirPath, 0777, true);
            }
            try {
                $this->addPageNumbersToFile($file, $outputPath);
                $results[] = [
                    'file' => $file,
                    'status' => 'success',
                    'output' => $outputPath
                ];
            } catch (Exception $e) {
                $results[] = [
                    'file' => $file,
                    'status' => 'error',
                    'message' => $e->getMessage()
                ];
            }
        }
        return $results;
    }
    private function getAllPDFFiles($dir) {
        $files = [];
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dir)
        );
        foreach ($iterator as $file) {
            if ($file->isFile() && $file->getExtension() === 'pdf') {
                $files[] = $file->getPathname();
            }
        }
        return $files;
    }
    private function addPageNumbersToFile($inputFile, $outputFile) {
        // 使用FPDI实现(需要提前安装)
        require_once('fpdi/fpdi.php');
        $pdf = new FPDI();
        $pageCount = $pdf->setSourceFile($inputFile);
        for ($page = 1; $page <= $pageCount; $page++) {
            $templateId = $pdf->importPage($page);
            $size = $pdf->getTemplateSize($templateId);
            $pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
            $pdf->useTemplate($templateId);
            // 页码文本
            $pageText = str_replace(
                ['{current}', '{total}'],
                [$page, $pageCount],
                $this->options['format']
            );
            // 设置字体
            $pdf->SetFont(
                $this->options['font'],
                $this->options['style'],
                $this->options['size']
            );
            // 计算位置
            $y = ($this->options['position'] === 'bottom') ? 
                ($size['height'] - $this->options['margin_bottom']) : 
                $this->options['margin_bottom'];
            $pdf->SetY($y);
            $pdf->SetX(0);
            $pdf->Cell(0, 10, $pageText, 0, 0, $this->options['align']);
        }
        $pdf->Output($outputFile, 'F');
    }
}
// 使用示例
$numberer = new AdvancedBatchPDFNumberer([
    'format' => '第 {current} 页',
    'position' => 'bottom',
    'align' => 'center'
]);
$results = $numberer->processDirectory('./input', './output', true);
// 显示结果
foreach ($results as $result) {
    if ($result['status'] === 'success') {
        echo "✓ {$result['file']} -> {$result['output']}\n";
    } else {
        echo "✗ {$result['file']}: {$result['message']}\n";
    }
}

安装依赖

使用Composer安装必要的库:

# FPDI + TCPDF
composer require setasign/fpdi
composer require tecnickcom/tcpdf
# 或者使用MPDF
composer require mpdf/mpdf
# 或者安装系统工具
# Ubuntu/Debian
sudo apt-get install pdftk ghostscript
# macOS
brew install pdftk gs

推荐方案

  1. 小规模批量处理(<100个文件):使用FPDI + TCPDF
  2. 大规模批量处理(>1000个文件):使用Ghostscript命令行
  3. 需要复杂排版:使用MPDF库

选择最适合您项目需求的方案即可。

抱歉,评论功能暂时关闭!