一、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 则不需要。
[图片上传失败...(image-ac19fb-1590543312504)]
在这里插入图片描述
②windows server格式转换代码实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | <?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 2 3 | 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安装包
1 | tar -zxvf Apache_OpenOffice_4.1.7_Linux_x86-64_install-deb_zh-CN.tar.gz(建议使用tab获取) |
- 会看到当前目录下多了一个"zh-CN"文件夹,切换进入该文件夹中的"DEBS"目录,使用以下命令安装OpenOffice:
1 2 3 4 | - 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/'目录下(安装包解压后出现的目录),使用以下命令启动服务
1 | ./soffice -headless -accept="socket,host=127.0.0.1,port=8100;urp;" -nofirststartwizard & |
在这里插入图片描述
这里可以看到报错,无法启动openoffice,是因为服务器没有java环境 需要安装java环境
以下是可能需要用到的命令:
- 查看OpenOffice是否成功启动:
- 卸载Openoffice
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 在其中添加以下内容:
1 2 3 4 | 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系统需要安装一下命令
1 | 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文件,键入以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $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两种系统同时跑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | <?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文件。
第一次发博文,一是对过程的记录,二是希望能帮到有需要的你。如有错误,欢迎指正、