Windows服务器安装office2010实现word转pdf(PHP)

打开COM扩展

打开php.ini文件,在文件最后添加:

extension=com_dotnet

查看php.ini中的disable_classes确保com类没有被禁用:

disable_classes =

重启php,查看phpinfo,看到以下信息则说明开启成功:

安装office2010

安装过程省略。

配置office组件服务

按 win+R 快捷键进入运行菜单,输入 Dcomcnfg
找到: [组件服务] —— [计算机]—— [我的电脑] —— [DCOM配置] —— [Microsoft Word 97-2003文档],右键设置属性,设置“标识”为:下列用户,点击“浏览”选择你当前登录的账户并输入密码,如下图:

注:如果找不到Microsoft Word程序,这主要是64位系统的问题,word是32位的组件,所以在正常的系统组件服务里是看不到的。可以通过在运行里面输入comexp.msc -32来打开32位的组件服务,在里就能看到word组件了。

设置权限

将上一步的账户添加到自定义里面,并开启所有权限:

添加受信任位置

打开某些受保护的word文档时,word会提示:检测到此文件存在一个问题。为帮助保护您的计算机,不能打开此文件。
遇到该问题时,可以通过设置“受信任位置”来解决。
点击左上角的“文件”->“选项”:

点击“信任中心”->“信任中心设置”:

在“受信任位置”中点击“添加新位置”,将文件上传位置添加进去即可:

PHP代码

PHP代码如下:

$wordInPath = __DIR__ ."/2.docx";          //要转换的word文档的路径
$pdfOutPath = __DIR__ ."/2.pdf";           //要输出的pdf的路径
word2pdf($wordInPath,$pdfOutPath);
function word2pdf($wordPath,$pdfPath)
{
    //生成临时文件
    $tmpfile = tempnam( sys_get_temp_dir(), "TMP" );
    copy($wordPath,$tmpfile);

    $word = new COM("Word.Application") or die ("Could not initialise Object.");
    // set it to 1 to see the MS Word window (the actual opening of the document)
    $word->Visible = 0;
    // recommend to set to 0, disables alerts like "Do you want MS Word to be the default .. etc"
    $word->DisplayAlerts = 0;
    // open the word 2007-2013 document
    $word->Documents->Open($tmpfile);
    // save it as word 2003
    // convert word 2007-2013 to PDF
    //判断要生成的文件名是否存在
    if(file_exists($pdfPath)) {
        //存在就删除
        unlink ($pdfPath);
    }
    $word->ActiveDocument->ExportAsFixedFormat($pdfPath, 17, false, 0, 0, 0, 0, 7, true, true, 2, true, true, false);
    // quit the Word process
    $word->ActiveDocument->Close(0);
    $word->Quit(false);
    // clean up
    unset($word);
}

封装好的类:

class Dcs
{
    private $downloadUrl;
    private $outputPath;
    private $error;

    public function setDownloadUrl($url)
    {
        $this->downloadUrl = $url;
    }

    public function setOutputPath($path)
    {
        $this->outputPath = $path;
        if(!is_dir($path)) @mkdir($path,0777,true);
    }

    public function getError()
    {
        return $this->error;
    }

    function convert()
    {
        $result = $this->remoteFileExists($this->downloadUrl);
        if ($result === false) {
            $this->error = '下载文件失败';
            return false;
        }
        $content = $this->curlGet($this->downloadUrl);
        if($content===false) return false;
        $tmpfile = tempnam( $this->outputPath, "TMP" );
        file_put_contents($tmpfile,$content);
        $pdfName = time() . mt_rand(1000, 9999) . '.pdf';
        $pdfPath = $this->outputPath . '/'.$pdfName;
        $this->word2pdf($tmpfile,$pdfPath);
        return $pdfPath;
    }

    private function word2pdf($wordPath,$pdfPath)
    {
        $word = new \COM("Word.Application") or die ("Could not initialise Object.");
        $word->Visible = 0;
        $word->DisplayAlerts = 0;
        $word->Documents->Open($wordPath);
        if(file_exists($pdfPath)) {
            unlink ($pdfPath);
        }
        $word->ActiveDocument->ExportAsFixedFormat($pdfPath, 17, false, 0, 0, 0, 0, 7, true, true, 2, true, true, false);
        $word->ActiveDocument->Close(0);
        $word->Quit(false);
        unset($word);
    }

    private function getWordContent($wordPath)
    {
        $word = new \COM("Word.Application") or die ("Could not initialise Object.");
        $word->Visible = 0;
        $word->DisplayAlerts = 0;
        $word->Documents->Open($wordPath);
        $text= $word->ActiveDocument->content->Text;
        $word->ActiveDocument->Close(0);
        $word->Quit(false);
        unset($word);
        $text = iconv('gbk','utf-8',$text);
        return $text;
    }

    private function curlGet($url = '', $options = array())
    {
//        return file_get_contents($url);
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);//返回response头部信息
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        if (!empty($options)) {
            curl_setopt_array($ch, $options);
        }
        //https请求 不验证证书和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        if($data === false)
        {
            $this->error = 'Curl error: ' . curl_error($ch);
            return false;
        }
        curl_close($ch);
        return $data;
    }

    private function remoteFileExists($url){
        return (bool)preg_match('~HTTP/1\.\d\s+200\s+OK~', @current(get_headers($url)));
    }

}

//使用类
define('WEBROOT', realpath(__DIR__));
$downloadUrl = $_POST['downloadUrl'];
$data['result'] = 1;
if(empty($downloadUrl)) {
    $data['message'] = '缺少参数:downloadUrl';
    echo json_encode($data, JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES);exit();
}
$dcs = new Dcs();
$dcs->setOutputPath(WEBROOT.'/output/'.date('Y').'/'.date('m'));
$dcs->setDownloadUrl($downloadUrl);
$result = $dcs->convert();
if($result===false){
    $data['message'] = $dcs->getError();
    echo json_encode($data, JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES);exit();
}
$result = str_replace(WEBROOT,'',$result);
$result = str_replace("\\",'/',$result);
$data['result'] = 0;
$data['data'][] = 'http://xxx/dcs/onlinefile/'.$result;
$data['message'] = '转换成功';
$data['type'] = 3;
echo json_encode($data, JSON_UNESCAPED_UNICODE + JSON_UNESCAPED_SLASHES);exit();

更多office的api

https://docs.microsoft.com/zh-cn/office/vba/api/word.document.exportasfixedformat

使用WPS

有的文件用word打不开,用wps却可以,同时wps具有免费的优点,也可以考虑使用wps来实现。

安装wps

有的wps版本(例如个人版)不包含com组件,我安装的是专业版:
https://www.ghxi.com/wps2019zfb.html

配置wps组件服务

配置方法跟office一样,这里不再赘述。

PHP代码

调用方式跟office也一模一样,只是new COM时传入的名称不同:

new COM("KWPS.Application")

注意:wps 8.0前的接口名称为:WPS.Application
9.0之后的版本接口名称:

控件名 name
WPS文字 KWPS.Aplication
WPS的Excel KET.Application
WPS的演示文档 KWPP.Application

发表评论

邮箱地址不会被公开。 必填项已用*标注