PHP 将 Word 文档转换为 PDF

在Python中,将Word文档转换为PDF有多种方法。

选择合适的方法

  • 如果你在Windows环境下工作,推荐使用python-docxpywin32,或者docx2pdf
  • 如果你需要跨平台支持,推荐使用unoconvpypandoc

PHP 中的 exec() 函数用于执行外部程序。

方法一:使用 pythondocx2pdf(仅限Windows,实测有效)

docx2pdf是一个简单的库,可以将Word文档转换为PDF,但它仅限于Windows环境。

  1. 安装docx2pdf

    sh复制

    复制pip install docx2pdf
    
  2. 示例代码

    Python复制

    复制import os
    from docx2pdf import convert
    
    def word_to_pdf(input_file, output_file):
        # 确保输入文件存在
        if not os.path.exists(input_file):
            raise FileNotFoundError(f"文件 {input_file} 不存在")
    
        # 转换文档
        try:
            convert(input_file, output_file)
            print(f"转换成功: {output_file}")
        except Exception as e:
            print(f"转换失败: {e}")
    
    # 使用示例
    input_file = 'example.docx'
    output_file = 'example.pdf'
    word_to_pdf(input_file, output_file)
    
  3. PHP 调用

    复制exec ( string $command , array &$output = ? , int &$return_var = ? ) : string
    

    $command:要执行的命令。

    $output:如果提供了这个参数,执行的命令的输出将被写入这个数组,每行输出作为一个元素。

    $return_var:如果提供了这个参数,执行命令的返回状态将被写入这个变量。返回状态为 0 表示成功,非 0 表示出错。

    • 示例。

      复制exec("ls -l", $output, $return_var);
      if ($return_var === 0) {
          foreach ($output as $line) {
              echo $line . "<br>";
          }
      } else {
          echo "命令执行失败,返回状态:" . $return_var;
      }
      

      在这个例子中,exec() 函数执行了 Linux 系统中的 ls -l 命令,用于列出当前目录下的文件和文件夹的详细信息。执行结果被存储在 $output 数组中,每行输出作为一个元素。同时,命令的返回状态存储在 $return_var 中。如果命令执行成功($return_var 为 0),则遍历 $output 数组并输出每一行内容;如果命令执行失败,则输出错误信息。

      • 执行系统命令并获取结果

        复制<?php
        
        // 获取系统当前时间
        exec("date", $output, $return_var);
        if ($return_var === 0) {
            echo "当前时间:" . implode(" ", $output);
        } else {
            echo "获取时间失败,返回状态:" . $return_var;
        }
        
        ?>
        

        这里执行了 date 命令来获取系统当前时间。由于 date 命令的输出可能包含多个部分(如星期、日期、时间等),所以使用 implode() 函数将 $output 数组中的元素连接成一个字符串来输出完整的时间信息。

      • 进阶。

        test.py

        复制print("{'test': True, 'resule': '123'}")
        

        main.php

        复制<?php
        
        exec("python3 test.py", $excelJsonList, $returnVar);
        // 输出内容数组转字符串
        $excelJsonString = implode("\n", $excelJsonList);
        
        // 将json字符串转为字典变量
        $excelJson = json_decode($excelJsonString, true);
        
        ?>
        
  4. 解决 Word 转 PDF 文件时图片位置改变和字体格式改变的问题。

    打开 Word 文件,选择 文件 -> 另存为 -> 浏览

    另存为 弹窗中,选择 保存类型:PDF(*.pdf) ,下方变更 针对以下格式优化 有关内容;

    选择新出现的 选项 按钮,在 选项 弹窗中,设置 PDF 选项 ,勾选 符合 PDF/A ,确定即可。

  5. 解决 Word 转 PDF 文件时卡顿时间长的问题

    在 Windows 设置 -> 设备 -> 打印机和扫描仪 中,取消勾选 让 Windows 管理默认打印机 ,选择 Microsoft Print to PDF -> 打开队列 -> 打印机 -> 设置为默认打印机

  6. 注意事项

    • 安全性

      使用 exec() 函数时,一定要注意安全性。因为如果命令字符串来自用户输入,可能会被恶意利用。例如,如果用户输入的命令中包含删除文件的命令,那么可能会导致系统文件被删除。所以,如果命令中包含用户输入的数据,一定要进行严格的过滤和验证。可以使用 escapeshellarg()escapeshellcmd() 函数来对输入进行转义。

      示例:

      复制<?php
      $user_input = "some_command";
      $safe_input = escapeshellcmd($user_input);
      exec($safe_input, $output, $return_var);
      ?>
      
    • 环境差异

      不同的操作系统对命令的支持不同。例如,ls 命令在 Linux 和 macOS 系统中有效,但在 Windows 系统中则需要使用 dir 命令来列出目录内容。所以在编写跨平台的代码时,要注意根据不同的操作系统执行不同的命令。

    • 资源占用

      执行外部命令可能会占用一定的系统资源。如果执行的命令非常复杂或者需要处理大量的数据,可能会导致服务器性能下降。在使用 exec() 函数时,要合理控制命令的执行频率和复杂度,避免对服务器造成过大的压力。

其他方法

方法二:使用 python python-docxpywin32(仅限Windows)

如果你在Windows环境下工作,可以使用python-docx库来读取Word文档,并使用pywin32库调用Word的COM接口进行转换。

  1. 安装必要的库

    sh复制

    复制pip install python-docx pywin32
    
  2. 示例代码

    Python复制

    复制import os
    import comtypes.client
    
    def word_to_pdf(input_file, output_file):
        # 确保输入文件存在
        if not os.path.exists(input_file):
            raise FileNotFoundError(f"文件 {input_file} 不存在")
    
        # 创建Word应用实例
        word = comtypes.client.CreateObject('Word.Application')
        word.Visible = False
    
        try:
            # 打开文档
            doc = word.Documents.Open(input_file)
            # 保存为PDF
            doc.SaveAs(output_file, FileFormat=17)  # 17 表示PDF格式
        except Exception as e:
            print(f"转换失败: {e}")
        finally:
            # 关闭文档和Word应用
            doc.Close()
            word.Quit()
    
    # 使用示例
    input_file = 'example.docx'
    output_file = 'example.pdf'
    word_to_pdf(input_file, output_file)
    

方法三:使用unoconv(跨平台,exe)

unoconv 是一个基于LibreOffice的命令行工具,可以将多种格式的文档转换为其他格式,包括Word到PDF。它可以在Windows、Linux和macOS上运行。

  1. 安装unoconv

    • Windows:下载并安装LibreOffice,然后安装unoconv

    • Linux:使用包管理器安装unoconv

      sh复制

      复制sudo apt-get install unoconv  # Ubuntu/Debian
      sudo yum install unoconv  # CentOS
      
    • macOS:使用Homebrew安装unoconv

      sh复制

      复制brew install unoconv
      
  2. 示例代码

    Python复制

    复制import subprocess
    
    def word_to_pdf(input_file, output_file):
        # 确保输入文件存在
        if not os.path.exists(input_file):
            raise FileNotFoundError(f"文件 {input_file} 不存在")
    
        # 调用unoconv命令
        try:
            subprocess.run(['unoconv', '-f', 'pdf', '-o', output_file, input_file], check=True)
        except subprocess.CalledProcessError as e:
            print(f"转换失败: {e}")
    
    # 使用示例
    input_file = 'example.docx'
    output_file = 'example.pdf'
    word_to_pdf(input_file, output_file)
    

方法四:使用pypandoc(跨平台,exe+python)

pandoc是一个功能强大的文档转换工具,也非常庞大。

pypandoc是其Python接口。pandoc可以将多种格式的文档转换为其他格式,包括Word到PDF。

  1. 安装pandoc

    • Windows:下载并安装Pandoc。

    • Linux:使用包管理器安装Pandoc。

      sh复制

      复制sudo apt-get install pandoc  # Ubuntu/Debian
      sudo yum install pandoc  # CentOS
      
    • macOS:使用Homebrew安装Pandoc。

      sh复制

      复制brew install pandoc
      
  2. 安装pypandoc

    sh复制

    复制pip install pypandoc
    
  3. 示例代码

    Python复制

    复制import os
    import pypandoc
    
    def word_to_pdf(input_file, output_file):
        # 确保输入文件存在
        if not os.path.exists(input_file):
            raise FileNotFoundError(f"文件 {input_file} 不存在")
    
        # 转换文档
        try:
            output = pypandoc.convert_file(input_file, 'pdf', outputfile=output_file)
            print(f"转换成功: {output_file}")
        except Exception as e:
            print(f"转换失败: {e}")
    
    # 使用示例
    input_file = 'example.docx'
    output_file = 'example.pdf'
    word_to_pdf(input_file, output_file)
    

方法五:使用Microsoft Office COM组件

确保安装Microsoft Office 确保你的Windows服务器上已安装Microsoft Office。

要确保安装的Office版本支持COM自动化,并且已启用,可以按照以下步骤操作:

  1. 检查Office版本

    确保安装的Office版本支持COM自动化。通常,Office 2007及以上版本都支持此功能。可以通过以下步骤检查Office版本:

    • 打开任意一个Office应用程序(如Word或Excel)。

      点击“文件”菜单,选择“账户”或“帮助”选项。

      查看显示的版本信息,确保版本号为2007或更高。

  2. 启用COM自动化

    确保COM自动化功能已启用。可以通过以下步骤检查和启用COM自动化:

    • 打开任意一个Office应用程序(如Word或Excel)。

      点击“文件”菜单,选择“选项”。

      在“选项”对话框中,选择“信任中心”。

      点击“信任中心设置”按钮。

      在“信任中心”对话框中,选择“宏设置”。

      确保“启用所有宏”选项被选中,并且“信任对VBA项目对象模型的访问”选项也被选中。

  3. 检查注册表设置

    确保注册表中有关COM自动化的设置正确。可以通过以下步骤检查注册表设置:

    打开“运行”对话框(按Win + R键),输入regedit,然后按回车键。

    导航到以下注册表路径:

    • 对于Excel:

      复制HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\Addins\
      
    • 对于Word:

      复制HKEY_CURRENT_USER\Software\Microsoft\Office\Word\Addins\
      

    确保每个COM Add-in的子键中包含正确的ProgID,并且加载行为设置正确。

  4. 通过用户界面管理COM Add-ins

    可以通过Office应用程序的用户界面管理COM Add-ins:

    • 打开任意一个Office应用程序(如Word或Excel)。

      点击“文件”菜单,选择“选项”。

      在“选项”对话框中,选择“加载项”。

      在“管理”下拉菜单中,选择“COM加载项”,然后点击“转到”。

      在“COM加载项”对话框中,确保所有需要的COM加载项都已选中。

  5. 使用命令行注册Office应用程序

    如果需要,可以使用命令行注册Office应用程序,确保COM自动化功能正常工作:

    • 打开命令提示符(以管理员身份)。

      导航到Office应用程序的安装目录。例如,对于Excel 2016,路径可能是:

      复制C:\Program Files\Microsoft Office\root\Office16\
      
    • 运行以下命令注册Excel:

      复制excel.exe /regserver
      
    • 同样,可以注册Word:

      复制winword.exe /regserver
      

    这将确保Office应用程序的COM自动化功能被正确注册。

    通过以上步骤,可以确保安装的Office版本支持COM自动化,并且已启用。如果在操作过程中遇到任何问题,可以参考Microsoft官方文档或联系技术支持。

  6. 编写PHP脚本

    复制$sourceFile = 'path/to/your/word/file.docx';
    $targetFile = 'path/to/save/your/pdf/file.pdf';
    
    // 创建Word应用程序实例
    $word = new COM("Word.Application") or die("无法创建Word实例");
    
    // 打开文档
    $word->Documents->Open($sourceFile);
    
    // 转换为PDF
    $word->ActiveDocument->ExportAsFixedFormat($targetFile, 17, false, 0, 0, 0, 0, 7, true, true, 2, true, true, false);
    
    // 关闭文档
    $word->ActiveDocument->Close(false);
    
    // 退出Word应用程序
    $word->Quit();
    
    echo "转换成功:$targetFile";
    

如果路径中包含中文名,可能会报错使用URL编码

将文件路径进行URL编码,然后再传递给COM对象。以下是一个示例代码:

复制$inputFile = 'C:\\路径\\包含中文\\文件名.docx';
$encodedPath = urlencode($inputFile);

$com = new COM("Word.Application");
$com->Documents->Open($encodedPath);
$com->Quit();

方法六、使用OpenOffice和PHP扩展

  1. 安装OpenOffice:从官网下载并安装OpenOffice,需确保安装了JDK并配置了JRE环境变量。

  2. 配置组件服务:按Win+R快捷键进入运行菜单,输入Dcomcnfg打开组件服务,依次进入“组件服务”->“计算机”->“我的电脑”->“DCOM配置”->“OpenOffice Service Manager”,右键打开属性面板,选择安全选项卡,分别在“启动和激活权限”和“访问权限”上勾选自定义,添加Everyone的权限。再选择标识选项卡,勾选“交互式用户”,保存设置后退出。

  3. 后台运行软件:安装完成后,启动一次确认软件可以正常运行,再打开命令行,切换到安装目录cd C:\Program Files\OpenOffice 4\program,运行命令soffice -headless-accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard,使软件在后台运行。

  4. 配置PHP扩展:如果是PHP5.4以前的版本,需在php.ini里把com.allow_dcom = true打开;如果是PHP5.4之后的版本,则要在php.ini里增加一行扩展extension = php_com_dotnet.dll,重启Apache或IIS服务器。

  5. 实现文件转换:使用PDFConverter类进行转换,示例代码如下:

    php复制

    复制$arr = array('doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx');
    $converter = new PDFConverter();
    foreach ($arr as $ext) {
        $source = __DIR__ . '/office/test.' . $ext;
        $export = __DIR__ . '/pdf/test.' . $ext . '.pdf';
        $converter->execute($source, $export);
        echo '<p>' . $ext . ' Done</p>';
    }
    

方法七、使用PHPWord和Dompdf库

  1. 安装所需库:通过Composer安装PHPWord和Dompdf库,命令如下:

    php复制

    复制composer require phpoffice/phpword
    composer require dompdf/dompdf
    
  2. 编写转换代码

    php复制

    复制require_once 'vendor/autoload.php';//引入
    
    $demoDoc = 'demo.docx';//模板docx文件
    $doc = new \PhpOffice\PhpWord\TemplateProcessor($demoDoc);
    $username = '名字';
    $phone = '130123456789';
    $age = '32岁';
    $doc->setValue('username',$username);
    $doc->setValue('phone',$phone);
    $doc->setValue('age',$age);
    $newDoc = $phone.'.docx';//生成的word文件
    $doc->saveAs($newDoc);//保存
    
    $newPdf = $phone.'.pdf';//生成pdf文件
    \PhpOffice\PhpWord\Settings::setPdfRendererName(\PhpOffice\PhpWord\Settings::PDF_RENDERER_DOMPDF);
    \PhpOffice\PhpWord\Settings::setPdfRendererPath('.');
    $pdf = \PhpOffice\PhpWord\IOFactory::load($newDoc);
    $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($pdf, 'PDF');
    $html = $xmlWriter->getContent();//获取word内容到HTML
    $xmlWriter->save($newPdf, 'PDF');//保存PDF文件
    header('location:'.$newPdf);//网页显示PDF
    

    但需要注意,此方法可能会出现中文乱码问题,需下载字体并安装,如将微软雅黑字体文件下载后放到D盘,再通过Dompdf的工具包中的load_font.php文件来加载字体。

    • 手动安装PHPWord(可选)

    • 从GitHub下载PHPOffice\PHPWord包和PHPOffice\Common包。

      解压包并将内容放到你的机器上。

      在PHP脚本中引用相关文件:

      复制require_once 'path/to/PHPWord/src/PhpWord/Autoloader.php';
      \PhpOffice\PhpWord\Autoloader::register();
      require_once 'path/to/PhpOffice/Common/src/Common/Autoloader.php';
      \PhpOffice\Common\Autoloader::register();
      

      这样也可以完成PHPWord的安装。

    • 注意事项

      确保PHP版本满足PHPWord和MPDF的要求,PHPWord需要PHP 7.1+,MPDF建议使用PHP 7.4或更高版本。

      安装过程中如果出现依赖项错误,需确保系统已安装所有必需的PHP扩展,并且Composer版本是最新的。

方法八、使用mPDF库

  1. 安装mPDF库:通过Composer安装,命令为composer require mpdf/mpdf

  2. 编写转换代码

    php复制

    复制require_once('vendor/autoload.php');
    // 初始化mPDF
    $mpdf = new \Mpdf\Mpdf();
    // 设置PDF文档的编码
    $mpdf->setUTF8(true);
    // 设置Word文件的路径
    $wordPath = 'example.docx';
    // 载入Word文件内容
    $wordContent = file_get_contents($wordPath);
    // 将Word内容转换为PDF
    $mpdf->WriteHTML($wordContent);
    // 设置PDF文档的输出路径
    $mpdfPath = 'example.pdf';
    // 生成PDF文件
    $mpdf->Output($mpdfPath, 'F');
    

方法九、使用PHPWord和MPDF库

  1. 安装所需库:通过Composer安装PHPWord和MPDF库,命令如下:

    php复制

    复制composer require phpoffice/phpword
    composer require mpdf/mpdf
    
  2. 编写转换代码

    复制namespace common;
    use PhpOffice\PhpWord\PhpWord;
    use PhpOffice\PhpWord\IOFactory;
    use PhpOffice\PhpWord\Settings;
    use common\PDF;
    
    class Office
    {
        public function wordToPdf($wordPath = '',$fileName = 'output')
        {
            $basePath = sprintf('%spublic/upload/pdf/%s',ROOT_PATH,date('Ymd'));
            $path = sprintf('%s/%s.pdf',$basePath,$fileName);
            if (!file_exists($basePath)) {
                mkdir($basePath, 0755, true);
            }
            $phpWord = new PhpWord();
            Settings::setPdfRendererPath(sprintf('%svendor/mpdf/mpdf',ROOT_PATH));
            Settings::setPdfRendererName('MPDF');
            $wordReader = IOFactory::createReader('Word2007');
            $phpWord = $wordReader->load($wordPath);
            $xmlWriter = IOFactory::createWriter($phpWord, 'PDF');
            $xmlWriter->save($path);
            if(file_exists($path)){
                $pdf = new PDF();
                $pngs = $pdf->pdfToPng($path);
                if(count($pngs) > 0){
                    unlink($path);
                    return $pngs;
                }
                return [];
            }else{
                return [];
            }
        }
    }
    

方法十:使用第三方API服务

  1. 选择第三方API服务 例如使用Smallpdf API,首先获取API密钥。

  2. 编写PHP脚本

    php复制

    复制$sourceFile = 'path/to/your/word/file.docx';
    $targetFile = 'path/to/save/your/pdf/file.pdf';
    $apiKey = 'YOUR_API_KEY';
    
    // 构建请求URL
    $url = "https://api.smallpdf.com/v1/convert/to/pdf?apikey=$apiKey";
    
    // 初始化cURL会话
    $ch = curl_init($url);
    
    // 设置文件上传选项
    $postData = [
        'file' => new CURLFile($sourceFile)
    ];
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
    
    // 执行请求
    $response = curl_exec($ch);
    curl_close($ch);
    
    // 保存PDF文件
    file_put_contents($targetFile, $response);
    
    echo "转换成功:$targetFile";
    

有关说明

1. Composer 安装 PHP 依赖库

在Windows下安装PHPWord和MPDF库,可以通过Composer来完成,以下是具体步骤:

  1. 安装Composer
  • 下载Composer-Setup.exe。

    运行安装程序,勾选开发者模式,选择安装位置以及对应的php.exe路径。

    根据提示完成安装,安装完成后会在指定目录下生成三个文件。

  1. 使用Composer安装PHPWord

    打开命令提示符窗口,输入以下命令查找所有PHPWord版本:

    复制composer show --all phpoffice/phpword
    

    选择所需版本进行下载,例如下载0.18.0版本,输入命令:

    复制composer require phpoffice/phpword 0.18.0
    

    或者直接安装最新稳定版本:

    复制composer require phpoffice/phpword
    

    Composer会自动创建JSON文件夹,并写入所需文件。

  2. 下载完成后,将vendor文件夹复制到你的PHP项目中,在使用PHPWord时,需引用autoload.php文件:

    php复制

    复制require./vendor/autoload.php’;
    

    此时PHPWord就可以正常使用了。

2. Composer 下载报错

2.1 The zip extension and unzip/7z

复制Failed to download phpoffice/math from dist: The zip extension and unzip/7z commands are both missing, skipping.
The php.ini used by your command-line PHP is: D:\Program\Tools\php-8.4.2\php.ini
    Now trying to download from source

根据你提供的错误信息,问题在于Composer在尝试下载phpoffice/math时,发现系统中缺少zip扩展和unzip/7z命令。以下是如何解决这个问题的步骤:

  • 启用PHP的zip扩展

    找到你的php.ini文件。根据你的错误信息,php.ini文件位于D:\Program\Tools\php-8.4.2\php.ini

    打开php.ini文件,使用文本编辑器(如Notepad++或VS Code)。

    搜索;extension=zip,去掉前面的分号,将其改为extension=zip

    保存并关闭php.ini文件。

  • 安装unzip或7z命令(可选)

    虽然启用zip扩展通常足以解决问题,但你也可以安装unzip或7z命令来提供额外的保障。

    下载并安装7-Zip:访问7-Zip官网,下载并安装7-Zip。

    确保7-Zip的安装路径(例如C:\Program Files\7-Zip)被添加到系统的环境变量中。这样,命令行工具就可以识别7z命令。

  • 重启Web服务器

    如果你使用的是Apache或Nginx等Web服务器,需要重启服务器以使配置生效。例如,如果你使用的是XAMPP,可以通过XAMPP控制面板重启Apache服务器。

  • 验证安装

    打开命令提示符(CMD)。

    输入以下命令,检查zip扩展是否已启用:

    复制php -m
    

    如果列表中包含zip,则表示扩展已成功启用。

    输入以下命令,检查Composer是否可以正常工作:

    复制composer self-update
    
  • 重新运行Composer命令

    现在,你可以重新运行之前的Composer命令,尝试下载phpoffice/math

    复制composer require phpoffice/math
    

2.2 https://repo.packagist.org could not be fully loaded

复制https://repo.packagist.org could not be fully loaded (curl error 28 while downloading https://repo.packagist.org/packages.json: SSL connection timeout), package information was loaded from the local cache and may be out of date

Composer在尝试从https://repo.packagist.org下载packages.json文件时遇到了SSL连接超时的问题(curl error 28)。这通常是由于网络连接问题或服务器响应缓慢导致的。

  • 检查网络连接

    确保你的网络连接是稳定的。你可以尝试访问其他网站或使用其他网络工具(如ping或traceroute)来检查网络连接是否正常。

  • 使用国内镜像源

    由于https://repo.packagist.org是国外的服务器,网络连接可能会不稳定。你可以尝试切换到国内镜像源,如阿里云或腾讯云镜像源。以下是如何设置国内镜像源的步骤:

    • 使用阿里云镜像源。

      打开命令提示符(CMD)。

      输入以下命令,将Composer的默认源切换为阿里云镜像源:

      复制composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
      
    • 使用腾讯云镜像源

      打开命令提示符(CMD)。

      输入以下命令,将Composer的默认源切换为腾讯云镜像源:

      复制composer config -g repo.packagist composer https://mirrors.cloud.tencent.com/composer/
      
      
      
    • 检查Composer配置

      确保Composer的配置是正确的。你可以使用以下命令查看当前的配置:

      复制composer config -g --list
      

      这将列出全局的Composer配置,包括当前使用的镜像源。

  • 临时使用镜像源

    如果你只想在当前项目中临时使用某个镜像源,可以在安装库时指定镜像源,例如:

    复制composer config repo.packagist composer https://mirrors.aliyun.com/composer/
    composer require phpoffice/math
    

参考

作者:Yogile

出处:https://www.cnblogs.com/Yogile/p/18679908

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Yogile  阅读(94)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题