一、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 则不需要。
②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文件。
第一次发博文,一是对过程的记录,二是希望能帮到有需要的你。如有错误,欢迎指正、