一、PHP使用openoffice实现office在线转PDF介绍

最近需要在网页上实现预览上传的word文档,之前没有实现过相关功能,搜索了一下网上的资料,完整的教程较少,因此将自己实现的步骤和遇到的问题记录下来,希望能帮到有需要的人

1.目前前端只能实现在线预览pdf格式的文件,可以用pdf.js或者jquery.media.js来实现。
2.要实现其他格式的文件预览,需要在后端进行格式转换。

3.目前我了解到的后端对office文档格式的转换方法有:

a、先转换成swf格式->在转换成pdf格式
b、借用第三方工具,如OpenOffice,LibreOffice等,用php或者java或者c#来实现.

4.我用的是openoffice来实现,下面进行详细介绍windows和linux系统的安装和使用方法。

二、windows server实现步骤

①实现具体步骤

a、首先下载openoffice软件,openoffice下载链接
在这里插入图片描述
下载完成之后双击安装,可以一路next。
b、oppenoffice权限设置
1、cmd 运行 Dcomcnfg->组件服务->计算机->我的电脑->DCOM配置->OpenOffice Service Manager
在这里插入图片描述

2、右键选择属性
在这里插入图片描述
3、进行设置步骤图示
在这里插入图片描述
注:标识设置中选择:交互式用户
在这里插入图片描述
注:Everyone首字母需要大写,检查名称出现下划线即表示成功直接确定即可

c、php环境及配置(开启php中com组件服务)

1: php环境我用的是独立搭建Apache+PHP环境,php版本为5.6.21
2 :具体配置:到php.ini中打开com选项 com.allow_dcom = true
注:PHP 5.4.5后,com/dotnet 模块已经成了单独的扩展,所以需要在PHP.ini中配置extension=php_com_dotnet.dll ,如果PHP VERSION<5.4.5 则不需要。

PHP扩展
在这里插入图片描述

②windows server格式转换代码实现
<?php 
 class office2pdf  
    {  
        private $osm;  
        public function __construct()  
        {  
        	//
            $this->osm = new COM("com.sun.star.ServiceManager")or die ("Please be sure that OpenOffice.org is installed.n");   
        }    
        public function MakePropertyValue($name,$value)  
        {  
            $oStruct = $this->osm->Bridge_GetStruct("com.sun.star.beans.PropertyValue");  
            $oStruct->Name = $name;  
            $oStruct->Value = $value;  
            return $oStruct;  
        }            
        public function transform($input_url, $output_url)  
        {  
            $args = array($this->MakePropertyValue("Hidden",true));  
            $oDesktop = $this->osm->createInstance("com.sun.star.frame.Desktop");  
     $oWriterDoc = $oDesktop->loadComponentFromURL($input_url,"_blank", 0, $args);  
        $export_args = array($this->MakePropertyValue("FilterName","writer_pdf_Export"));  
            $oWriterDoc->storeToURL($output_url,$export_args);  
            $oWriterDoc->close(true);  
            return $this->getPdfPages($output_url);  
        }           
        public function run($input,$output)
        {  
            $input = "file:///" . str_replace("\\","/",$input);  
            $output = "file:///" . str_replace("\\","/",$output);  
            return $this->transform($input, $output);  
        }        
        /** 
         * 获取PDF文件页数的函数获取 
         * 文件应当对当前用户可读(linux下) 
         * @param  [string] $path [文件路径] 
         * @return int 
         */  
        public function getPdfPages($path)  
        {  
            if(!file_exists($path)) return 0;  
            if(!is_readable($path)) return 0;  
            // 打开文件  
            $fp=@fopen($path,"r");  
            if (!$fp)   
            {  
                return 0;  
            }  
            else   
            {  
                $max=0;  
                while(!feof($fp))   
                {  
                    $line = fgets($fp,255);  
                    if (preg_match('/\/Count [0-9]+/', $line, $matches))  
                    {  
                        preg_match('/[0-9]+/',$matches[0], $matches2);  
                        if ($max<$matches2[0]) $max=$matches2[0];  
                    }  
                }  
                fclose($fp);  
                // 返回页数  
                return $max;  
            }  
        }       
    }  
  $con=new office2pdf();
  $con->run("C:\yikesoft\www\openoffice\demo.pptx","C:\yikesoft\www\office2pdf\demo.pdf");
  echo $con->getPdfPages("C:\yikesoft\www\office2pdf\demo.pdf");//获取转换完成pdf文件的页数
    ?>

三、linux系统实现步骤

linux实现具体步骤

服务器操作系统:linux ubuntu18.04.4 Lts
整个实现步骤简要如下:

  • 安装配置OpenOffice、java、jodconverter,实现office文件转pdf
  • 运用jodconverter调用java启动openoffice实现文件转换

必须先卸载LibreOffice:

 1. sudo apt-get remove --purge libreoffice*
 2. sudo apt-get clean
 3. sudo apt-get autoremove

详细步骤如下:

1.安装OpenOffice,同上方下载地址一样,这里就不加链接了
  • 根据自己系统的情况选择下载类型,我选择的是x86_64,DEB格式的安装包 (如果你服务器系统是centos的,那么需要下载RPM安装包)
  • 下载完成之后将OpenOffice安装包上传到服务器中,我选择放在根目录下opt/ 目录中
  • 切换到安装包所在目录,使用以下命令解压OpenOffice安装包
tar -zxvf Apache_OpenOffice_4.1.7_Linux_x86-64_install-deb_zh-CN.tar.gz(建议使用tab获取)
  • 会看到当前目录下多了一个"zh-CN"文件夹,切换进入该文件夹中的"DEBS"目录,使用以下命令安装OpenOffice:
 - cd zh-CN/DEBS/
 - sudo dpkg -i *.deb
 - cd desktop-integration/
 - sudo dpkg -i openoffice4.1-debian-menus_4.1.7-9800_all.deb(建议使用tab获取)

安装成功后就可以启动OpenOffice服务了

  • 启动OpenOffice服务

先切换到’opt/openoffice4/program/'目录下(安装包解压后出现的目录),使用以下命令启动服务
sentos启动

./soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard &

Ubuntu启动

soffice --headless --accept="socket,host=127.0.0.1,port=8100;urp;" --nofirststartwizard &

在这里插入图片描述
这里可以看到报错,无法启动openoffice,是因为服务器没有java环境 需要安装java环境
以下是可能需要用到的命令:

  • 查看OpenOffice是否成功启动:

netstat -nlp | grep 8100 如果没有显示则没成功
ps -ef |grep 8100启动后若要停止服务只需kill服务的PID就行

  • 卸载Openoffice

rpm -e rpm -qa |grep openoffice rpm -qa |grep ooobasis

2.安装JAVA环境(如果服务器没有JAVA环境的话)

OpenOffice的运行需要JAVA,所以必须安装。
首先使用java -version查看自己服务器是否已经安装了

  • 下载JDK,下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html
  • 根据自己的情况选择JAVA版本,操作系统位数不要选错
  • 将JDK上传到服务器的目录下,我的目录是/opt/java/,然后使用以下命令解压:
    tar -zxvf jdk-8u241-linux-x64.tar.gz (jdk名改成自己的)
    解压完成后编辑配置文件:vim /etc/profile 在其中添加以下内容:
	JAVA_HOME=/opt/java/jdk1.8.0_241
	CLASSPATH=$JAVA_HOME/lib/
	PATH=$PATH:$JAVA_HOME/bin
	export PATH JAVA_HOME CLASSPATH
  • 改完后使用source /etc/profile 更新系统环境配置。
  • 查看JAVA环境是否安装成功:java -version
  • 重新运行OpenOffice,查看是否成功,一般都没啥问题。

emm…结果我的出现了这个问题在这里插入图片描述

  • 我们需要通过yum源安装 “X Window System” 启动
    apt-get install yum(Ubuntu系统没有安装yum需要执行)
    centos系统需要安装一下命令
yum groupinstall "X Window System"
3.安装jodconverter
  • 使用jodconverter调用openoffice来实现office文件转pdf,这个方法对于linux下的php比较方便。
    jodconverter下载地址: https://sourceforge.net/projects/jodconverter/files/
  • 下载完后上传到linux服务器解压,然后切换到jodconverter的lib目录下,使用以下命令测试word转pdf:
    java -jar jodconverter-cli-2.2.2.jar test.docx test.pdf
  • 如果成功将word文档转成pdf文档,则表示你的openoffice和jodconver都已经安装成功了。(该命令默认test.docx也在lib目录下)
    当然你也可以不用切换到lib目录,使用以下命令也能实现转换:
    java -jar 'jar包地址' '源文件地址' '输出文件地址'
  • 转换完成后查看一下pdf文件内容,看看是否中文出现乱码或者显示不出,若存在该情况,还需要进行下面这一步:
4.解决转换结果中中文内容显示乱码的问题
  • 将windows系统的c:\window\fonts目录下的字体上传到linux服务器的usr\share\fonts目录下,一般都是这个目录,可以用cat /etc/fonts/fonts.conf确认一下。
    在这里插入图片描述
  • 只需要选中的这些即可
  • 上传完成后,使用命令fc-cache -fv更新缓存,然后重启openoffice服务(重启只需要kill掉pid再次启动即可),重新尝试文档转换发现字体正常。
    在这里插入图片描述
5.使用php实现文档转换
  • 新建一个php文件,键入以下代码:
$jodconverter_path = '/opt/jodconverter/jodconverter-2.2.2/lib/jodconverter-cli-2.2.2.jar';//jodconverter-cli-2.2.2.jar 程序绝对路径
$infile_path       = '/opt/test/1.docx';//需要转pdf格式的源文件
$outfile_path      = '/opt/test/1.pdf';//需要输出的文件绝对路径 
echo word2pdf($infile_path, $outfile_path, $jodconverter_path);

function word2pdf ($infile_path, $outfile_path, $jodconverter_path) {
    if (empty($infile_path)) return false;    
    try {
        $p = "/opt/java/jdk1.8.0_241/bin/java -jar ". $jodconverter_path. ' '. $infile_path. ' '. $outfile_path;
        
        $res = exec($p);
        return $res;
    } catch (Exception $e) {
        return false;
    }
}

  • 代码中的文件路径根据自己的情况修改,运行该php文件,则可以测试php能否成功将文件进行转换。
    在测试的过程中若遇到php无法执行exec()函数的问题,需要修改php.ini里的配置(disable_function等)。

四、自用线上TP5项目封装调用方法,适用于windows server和linux两种系统同时跑

<?php

namespace app\admin\controller;


use Exception;
use think\facade\Request;


class Office2Pdf
{



    /**
     * word2pdf() 执行odconverter用openOffice转pdf代码 linux系统下
     * @param $infile_path
     * @param $outfile_path
     * @param $jodconverter_path
     * @return bool
     */
    public function word2pdf($infile_path, $outfile_path, $jodconverter_path)
    {
        if (empty($infile_path)) return false;
        try {
            $set_charset = 'export LANG=en_US.UTF-8;'; //为防止中文文件转pdf时exec()函数执行出错 设置字符集为utf-8
            $p = "/opt/java/jdk1.8.0_241/bin/java -jar " . $jodconverter_path . ' ' . $infile_path . ' ' . $outfile_path;
            exec($set_charset.$p);
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * 获取PDF文件页数的函数获取  两系统通用
     * 文件应当对当前用户可读(linux下)
     * @param  [string] $path [文件路径]
     * @return int
     */
    public function getPdfPages($outfile_path)
    {
        if(!file_exists($outfile_path)) return 0;
        if(!is_readable($outfile_path)) return 0;
        // 打开文件
        $fp=@fopen($outfile_path,"r");
        if (!$fp)
        {
            return 0;
        }
        else
        {
            $max=0;
            while(!feof($fp))
            {
                $line = fgets($fp,255);
                if (preg_match('/\/Count [0-9]+/', $line, $matches))
                {
                    preg_match('/[0-9]+/',$matches[0], $matches2);
                    if ($max<$matches2[0]) $max=$matches2[0];
                }
            }
            fclose($fp);
            // 返回页数
            return $max;
        }
    }


    /**
     * office文件转pdf输出方法
     * @param $file_path
     * @return string
     */
    public function office2pdf($file_path = '666.xlsx')
    {
        //判断服务器操作系统 暂定为win和linux两种
        if (PHP_OS == 'Linux'){
            $jodconverter_path = "/opt/jodconverter/jodconverter-2.2.2/lib/jodconverter-cli-2.2.2.jar";
            $infile_path = "/var/www/yike-resource/public/".$file_path;
            $rand_path = time().rand(100000,999999).'.pdf'; //定义随机生成一个pdf格式文件名
            $outfile_path = "/var/www/yike-resource/public/uploads/office2pdf/".$rand_path;
            $this->word2pdf($infile_path, $outfile_path, $jodconverter_path);
            return "/uploads/office2pdf/".$rand_path;
        }elseif(PHP_OS == 'WINNT'){
            $con = new Office2Pdf();
            $infile_path = PUBLIC_UPLOADS.'/'.$file_path;
            $rand_path = time().rand(100000,999999).'.pdf';
            $outfile_path = PUBLIC_UPLOADS."/office2pdf/".$rand_path;
            $con->run($infile_path,$outfile_path);
            //echo $con->getPdfPages($outfile_path);
            return "office2pdf/".$rand_path;
        }
    }

    /**
     * win系统下操作openoffice方法
     * @var COM
     */
    private $osm;
    public function __construct()
    {
        if (PHP_OS == 'WINNT'){
            $this->osm = new \COM("com.sun.star.ServiceManager")or die ("Please be sure that OpenOffice.org is installed.n");
        }
    }
    public function MakePropertyValue($name,$value)
    {
        $oStruct = $this->osm->Bridge_GetStruct("com.sun.star.beans.PropertyValue");
        $oStruct->Name = $name;
        $oStruct->Value = $value;
        return $oStruct;
    }
    public function transform($input_url, $output_url)
    {
        $args = array($this->MakePropertyValue("Hidden",true));
        $oDesktop = $this->osm->createInstance("com.sun.star.frame.Desktop");
        $oWriterDoc = $oDesktop->loadComponentFromURL($input_url,"_blank", 0, $args);
        $export_args = array($this->MakePropertyValue("FilterName","writer_pdf_Export"));
        $oWriterDoc->storeToURL($output_url,$export_args);
        $oWriterDoc->close(true);
        return $this->getPdfPages($output_url);
    }
    public function run($input,$output)
    {
        $input = "file:///" . str_replace("\\","/",$input);
        $output = "file:///" . str_replace("\\","/",$output);
        return $this->transform($input, $output);
    }


}

  • 以上就是php通过openoffice实现在线预览word等office文件。
    第一次发博文,一是对过程的记录,二是希望能帮到有需要的你。如有错误,欢迎指正、
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐