返回

PHP 实现自动打印 PDF 文件及解决方案

php

PHP 实现自动打印 PDF 文件

本文将探讨如何利用 PHP 实现监控指定文件夹并自动打印 PDF 文件,然后将其转移到另一个文件夹。 针对提供的代码无法正常工作的问题,我们将分析可能原因并给出可行的解决方案。

问题分析与排查

提供的代码尝试使用 printer_open()printer_write() 等 PHP 打印函数直接向打印机发送原始数据。这种方法在特定环境下可行,但依赖于打印机驱动和 PHP 配置,容易出现兼容性问题。无法打印的原因可能包括:

  • 打印机路径错误 : \\\\server\printer 路径格式不正确或网络打印机不可访问。
  • 权限不足 : PHP 进程没有访问打印机或文件的权限。
  • 打印机驱动问题 : 打印机驱动不支持 RAW 模式或需要特定配置。
  • 文件损坏 : PDF 文件本身已损坏或格式不正确。
  • PHP 扩展未安装 : php_printer 扩展未启用或未正确安装。

我们将针对以上问题提供更可靠、更通用的解决方案。

解决方案

1. 使用系统命令调用打印程序

此方法通过调用操作系统提供的命令行工具(如 Windows 上的 print 命令或 Linux 上的 lpr 命令)来实现打印。 这是一种更通用且可靠的方式,因为它不直接依赖于 PHP 打印扩展,而是利用操作系统自身的打印功能。

  • 原理 : PHP 通过 shell_exec()exec() 函数执行系统命令,将 PDF 文件路径作为参数传递给打印命令。
  • 优点 : 兼容性好,不依赖特定 PHP 扩展,可控性强。
  • 缺点 : 需要配置打印机驱动和操作系统打印服务。
Windows 平台
  1. 确保打印机已正确安装并配置为默认打印机。

  2. 使用 print 命令打印 PDF 文件:

    <?php
    $pdf_file = 'path/to/your/input/folder/455.pdf';
    $archive_dir = 'path/to/your/archive/folder/';
    $print_command = 'print /d:"' . $printerName . '" "' . $pdf_file . '"';
    
    // 获取默认打印机名称
    $printerName = shell_exec('wmic printer get name,default | findstr TRUE');
    $printerName = trim(str_replace("TRUE", "", $printerName));
    
        if(file_exists($pdf_file)){
             exec($print_command,$output, $return_var);
            if ($return_var == 0){
                //  打印成功,移动文件
                if (rename($pdf_file, $archive_dir . basename($pdf_file))) {
                     echo "文件打印成功并已归档.";
                } else {
                     echo "文件打印成功但归档失败.";
                }
             } else {
                //  打印失败
                 echo "文件打印失败.";
            }
         }   else    {
            echo "文件不存在.";
          }
    ?>
    

    path/to/your/input/folder/ 替换为实际的 PDF 文件存放路径,path/to/your/archive/folder/ 替换为打印后 PDF 文件需要移动到的文件夹路径。

Linux 平台
  1. 确保 CUPS(通用 Unix 打印系统)已安装并运行。

  2. 使用 lpr 命令打印 PDF 文件:

    <?php
    $pdf_file = 'path/to/your/input/folder/455.pdf';
    $archive_dir = 'path/to/your/archive/folder/';
    $print_command = 'lpr ' . $pdf_file;
    if(file_exists($pdf_file)){
        exec($print_command, $output, $return_var);
    if ($return_var == 0) {
        if(rename($pdf_file, $archive_dir . basename($pdf_file))){
            echo "文件打印成功并已归档.";
            } else {
             echo "文件打印成功但归档失败.";
                }
            } else {
              echo "文件打印失败.";
           }
        }   else    {
        echo "文件不存在.";
          }
    ?>
    

    同样,将 path/to/your/input/folder/path/to/your/archive/folder/ 替换为实际的路径。

操作步骤:
  1. 将上述代码保存为 PHP 文件(例如 print_pdf.php)。
  2. 创建输入目录和归档目录。
  3. 将需要打印的 PDF 文件放入输入目录。
  4. 通过命令行或浏览器运行 print_pdf.php 脚本。

2. 使用第三方库 (如 FPDI 和 TCPDF)

此方法使用第三方 PHP 库来解析和渲染 PDF 文件,然后将其发送到打印机。 这种方法灵活度更高,可以实现更复杂的打印需求,例如: 自定义打印设置、合并多个 PDF 文件等。

  • 原理 : FPDI 库用于导入 PDF 文件,TCPDF 库用于生成和打印 PDF 文档。PHP 代码读取 PDF 文件,然后通过 TCPDF 将其发送到打印机。
  • 优点 : 功能强大,可定制性高,支持多种 PDF 格式和打印选项。
  • 缺点 : 需要安装额外的库,配置稍复杂。
示例代码 (使用 FPDI 和 TCPDF):
  1. 安装 Composer 包管理器。

  2. 使用 Composer 安装 FPDI 和 TCPDF:

    composer require setasign/fpdi tcpdf/tcpdf
    
  3. PHP 代码:

    <?php
    
    require_once('vendor/autoload.php');
    
    use setasign\Fpdi\Tcpdf\Fpdi;
    
    $pdf_file = 'path/to/your/input/folder/455.pdf';
    $archive_dir = 'path/to/your/archive/folder/';
    
    if (file_exists($pdf_file)) {
            $pdf = new FPDI();
    
             try {
    
            $pageCount = $pdf->setSourceFile($pdf_file);
              for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
                $templateId = $pdf->importPage($pageNo);
                $pdf->AddPage();
                $pdf->useTemplate($templateId);
                  }
    
             $pdf->AutoPrint(true);
             $pdf->Output($archive_dir . basename($pdf_file), 'F');
    
            unlink($pdf_file);
    
                echo "文件打印成功并已归档.";
    
             } catch (Exception $e) {
                echo "打印失败: " . $e->getMessage();
             }
    
      } else {
          echo "文件不存在.";
      }
    
    ?>
    
操作步骤:
  1. 将上述代码保存为 PHP 文件。
  2. 同样,替换 path/to/your/input/folder/path/to/your/archive/folder/ 为实际路径。
  3. 通过命令行或浏览器运行 PHP 脚本。

文件监控和定时打印

以上代码演示了如何打印单个文件。要实现自动监控文件夹并打印新文件,可以结合使用 PHP 的文件系统函数(如 scandir())和定时任务(如 Linux 上的 cron 或 Windows 上的 “任务计划程序”)。

  1. PHP 脚本 : 扫描输入文件夹,获取新的 PDF 文件列表。对每个新文件,执行上述打印逻辑。打印完成后,将文件移动到归档文件夹。
  2. 定时任务 : 配置定时任务,定期运行 PHP 脚本,实现自动监控和打印。

安全建议

  • 权限控制 : 确保 PHP 进程具有访问输入/输出目录和打印机的最低必要权限,避免安全风险。
  • 输入验证 : 验证 PDF 文件路径和文件名,防止恶意代码注入。
  • 错误处理 : 完善错误处理机制,记录错误日志,及时发现并解决问题。

通过上述解决方案,开发者可以根据实际需求选择合适的方式实现 PHP 自动打印 PDF 文件。建议优先使用系统命令方式,因为它更简单、可靠、通用。 如果需要更高级的打印功能,可以考虑使用第三方库。 同时,务必注意安全性,避免潜在的安全风险。

可能有用的资源:

请根据您的具体环境和需求调整以上代码和方案。