最近在做一个文库网站项目,需要让文档能在网页中预览。 在网页上能预览,需要实现word文件转pdf, ppt文件转图片。
我实现的逻辑是借用windows office 软件,通过调用PHP执行office转换命令。以下是我的操作步骤,仅供大家参考。
一、 服务器环境安装和设置
- 购买windows 服务器,安装chrome, rar;服务器系统设置(电源>高级计划>从不关闭显示器)
- 安装宝塔,配置LNMP环境
- 安装office2013
- 打开php.ini,搜索php_com_dotnet和php_com_dotnet: extension=php_com_dotnet.dll //把前面的分号去掉 com.allow_dcom = true //改为true
- 打开php的安装目录下的 php.in 文件,找到 disable_classes = 这行。果然,com 在 disable_classes = 里面,代码如下: disable_classes = com 把 com 删除,这行代码变为: disable_classes =
- 重启php
- win+r 输入 dcomcnfg 进入配置office组件服务权限配置
- 如果这种方式找不到组件可以使用另一种方式,输入mmc -32, 添加或删除管理单元
添加后,再次进入dcomcnfg,组件配置
记住 标识为 交互式用户
二、 添加接口网站
三、 接口代码分享
<?php
set_time_limit(0);
$keys = 'HQRux0Z6RF00a1xj','K86njv0Vbxgg390p','8GA3KGsAtRed7w5L','bGcsJ67xdLEsTxxL';
$appkey = $_POST'appkey';
$file = $_POST'file';
$action = $_POST'action';
$rootPath = rtrim($_SERVER'DOCUMENT_ROOT',DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
$current_url = get_url();
$rootUrl = rtrim(str_replace(basename($current_url),'',$current_url),'/')."/";
if(empty($appkey)||empty($file)||empty($action))
{
$result = [
'error' => 1,
'msg' => '参数错误',
'code'=>500,
'data'=>[]
];
echo_json($result);
}
else
{
if(!in_array($appkey,$keys))
{
$result = [
'error' => 1,
'msg' => '非法appkey',
'code'=>500,
'data'=>[]
];
echo_json($result);
}
else
{
//个人目录空间
$ownerPath = str_replace('/',DIRECTORY_SEPARATOR,$rootPath).$appkey.DIRECTORY_SEPARATOR;
$ownerUrl = $rootUrl.$appkey."/";
if(is_dir($ownerPath))
{
$dirsize = CalcDirectorySize($ownerPath);
if($dirsize>=524288000)//超过500Mb,清空目录
{
dir_delete($ownerPath);
dir_create($ownerPath);
}
}
else
{
dir_create($ownerPath);
}
chmod($ownerPath,0777);
$filename = basename($file);
$filemd5 = md5($filename);
$sourceFile = $ownerPath.$filemd5.'.'.fileext($filename);
$workpath = $ownerPath.$filemd5.DIRECTORY_SEPARATOR;
$workUrl = $ownerUrl.$filemd5."/";
if(!is_dir($workpath))dir_create($workpath);
chmod($workpath,0777);
if(!file_exists($sourceFile))file_put_contents($sourceFile,https_request($file));
chmod($sourceFile,0777);
//转换成pdf
if($action=='topdf')
{
if(!file_exists($sourceFile))
{
$result = [
'error' => 1,
'msg' => '转码失败',
'code'=>200,
'data'=>[]
];
echo_json($result);
}
$ext = fileext($sourceFile);
$pdfname = str_replace('.'.$ext,'.pdf',basename($sourceFile));
$pdfPath = $workpath.$pdfname;
$pdfUrl = $workUrl.$pdfname;
if(in_array($ext,array('doc','docx','wps')))
{
$word = new COM("word.Application") or die("Could not initialise Object");
$word->Documents->Open($sourceFile);
$word->ActiveDocument->ExportAsFixedFormat($pdfPath, 17, false, 0, 0, 0, 0, 7, true, true, 2, true, true, false);
$word->Quit(false);
unset($word);
}
if(in_array($ext,array('ppt','pptx','dps')))
{
$ppt = new COM("powerpoint.application") or die("Unable to instantiate Powerpoint");
$presentation = $ppt->Presentations->Open($sourceFile, false, false, false);
$presentation->SaveAs($pdfPath,32,1);
$presentation->Close();
$ppt->Quit();
unset($ppt);
}
if(in_array($ext,array('xls','xlsx','et')))
{
$excel = new COM("excel.application") or die("Unable to instantiate excel");
$workbook = $excel->Workbooks->Open($sourceFile, null, false, null, "1", "1", true);
$workbook->ExportAsFixedFormat(0, $pdfPath);
$workbook->Close();
$excel->Quit();
unset($excel);
}
$result = [
'error' => 0,
'msg' => '转码成功',
'code'=>200,
'data'=>['pdf'=>$pdfUrl]
];
echo_json($result);
}
//PPT转图片
if($action=='ppt2img')
{
$powerpnt = new COM("powerpoint.application") or die("Unable to instantiate Powerpoint");
$presentation = $powerpnt->Presentations->Open2007($sourceFile, false, false, false,true) or die("Unable to open presentation");
//$presentation = $powerpnt->Presentations->Open($sourceFile, false, false, false) or die("Unable to open presentation");
foreach($presentation->Slides as $slide)
{
$slideName = $slide->SlideNumber-1;
$to = $workpath.$slideName.".jpg";
$slide->Export($to, "jpg", "960", "540");
$urls[] = $workUrl.$slideName.".jpg";
}
$presentation->Close();
$powerpnt->Quit();
$powerpnt = null;
$result = [
'error' => 0,
'msg' => '转码成功',
'code'=>200,
'data'=>['imgs'=>$urls]
];
echo_json($result);
}
}
}
/****以下是全局函数****/
function echo_json($arr){
ob_clean();
header('Content-type: application/json');
echo json_encode($arr);exit;
}
//Curl
function https_request($url,$options = null,$data = null,$header = null){
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); //强制协议为1.0
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 ); //强制使用IPV4协议解析域名
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
}
(isset($options['header'])&&$options['header'])?curl_setopt($curl, CURLOPT_HEADER, 1): curl_setopt($curl, CURLOPT_HEADER, 0);//如果有响应头
if(!empty($header))//如果有请求头
{
$curl_header = array();
foreach($header as $key=>$value)
{
$curl_header[] = "$key:$value";
}
curl_setopt($curl,CURLOPT_HTTPHEADER, $curl_header);
}
if(isset($options['gzip'])&&$options['gzip']==1) curl_setopt($curl, CURLOPT_ENCODING, "gzip"); //如果页面开启了GZIP压缩
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0');
if(!empty($options['time_out']))
{
curl_setopt($curl, CURLOPT_TIMEOUT, $options['time_out']);
}
else
{
curl_setopt($curl, CURLOPT_TIMEOUT, 600);
}
curl_setopt ($curl, CURLOPT_REFERER, get_url());
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
function fileext($filename) {
return strtolower(trim(substr(strrchr($filename, '.'), 1, 10)));
}
/*
- 转化 \ 为 /
- @param string $path 路径
- @return string 路径
- */ function dir_path($path) { $path = str_replace('\', '/', $path); if(substr($path, -1) != '/') $path = $path.'/'; return $path; } /**
- 创建目录
- @param string $path 路径
- @param string $mode 属性
- @return string 如果已经存在则返回true,否则为flase */ function dir_create($path, $mode = 0777) {
if(is_dir($path)) return TRUE;
$path = dir_path($path);
$temp = explode('/', $path);
$cur_dir = '';
$max = count($temp) - 1;
for($i=0; $i<$max; $i++) {
$cur_dir .= $temp[$i].'/';
if (@is_dir($cur_dir)) continue;
@mkdir($cur_dir, 0777,true);
@chmod($cur_dir, 0777);
}
return is_dir($path);
}
/*
- 拷贝目录及下面所有文件
- @param string $fromdir 原路径
- @param string $todir 目标路径
- @return string 如果目标路径不存在则返回false,否则为true / function dir_copy($fromdir, $todir) { $fromdir = dir_path($fromdir); $todir = dir_path($todir); if (!is_dir($fromdir)) return FALSE; if (!is_dir($todir)) dir_create($todir); $list = glob($fromdir.''); if (!empty($list)) { foreach($list as $v) { $path = $todir.basename($v); if(is_dir($v)) { dir_copy($v, $path); } else { copy($v, $path); @chmod($path, 0777); } } } return TRUE; } /**
- 转换目录下面的所有文件编码格式
- @param string $in_charset 原字符集
- @param string $out_charset 目标字符集
- @param string $dir 目录地址
- @param string $fileexts 转换的文件格式
- @return string 如果原字符集和目标字符集相同则返回false,否则为true */ function dir_iconv($in_charset, $out_charset, $dir, $fileexts = 'php|html|htm|shtml|shtm|js|txt|xml') { if($in_charset == $out_charset) return false; $list = dir_list($dir); foreach($list as $v) { if (pathinfo($v, PATHINFO_EXTENSION) == $fileexts && is_file($v)){ file_put_contents($v, iconv($in_charset, $out_charset, file_get_contents($v))); } } return true; } /**
- 列出目录下所有文件
- @param string $path 路径
- @param string $exts 扩展名
- @param array $list 增加的文件列表
- @return array 所有满足条件的文件 / function dir_list($path, $exts = '', $list= array()) { $path = dir_path($path); $files = glob($path.''); foreach($files as $v) { if (!$exts || pathinfo($v, PATHINFO_EXTENSION) == $exts) { $list[] = $v; if (is_dir($v)) { $list = dir_list($v, $exts, $list); } } } return $list; } /**
- 设置目录下面的所有文件的访问和修改时间
- @param string $path 路径
- @param int $mtime 修改时间
- @param int $atime 访问时间
- @return array 不是目录时返回false,否则返回 true / function dir_touch($path, $mtime = TIMESTAMP, $atime = TIMESTAMP) { if (!is_dir($path)) return false; $path = dir_path($path); if (!is_dir($path)) touch($path, $mtime, $atime); $files = glob($path.''); foreach($files as $v) { is_dir($v) ? dir_touch($v, $mtime, $atime) : touch($v, $mtime, $atime); } return true; } /**
- 目录列表
- @param string $dir 路径
- @param int $parentid 父id
- @param array $dirs 传入的目录
- @return array 返回目录列表 / function dir_tree($dir, $parentid = 0, $dirs = array()) { global $id; if ($parentid == 0) $id = 0; $list = glob($dir.''); foreach($list as $v) { if (is_dir($v)) { $id++; $dirs$id = array('id'=>$id,'parentid'=>$parentid, 'name'=>basename($v), 'dir'=>$v.'/'); $dirs = dir_tree($v.'/', $id, $dirs); } } return $dirs; }
function dir_child($dir) {
$dirArray[]=NULL;
if (false != ($handle = opendir ( $dir ))) {
$i=0;
while ( false !== ($file = readdir ( $handle )) ) {
//去掉"“.”、“..”以及带“.xxx”后缀的文件
if ($file != "." && $file != "..") {
$dirArray[$i]=$file;
$i++;
}
}
//关闭句柄
closedir ( $handle );
}
return $dirArray;
}
/**
- 删除目录及目录下面的所有文件
- @param string $dir 路径
- @return bool 如果成功则返回 TRUE,失败则返回 FALSE / function dir_delete($dir) { $dir = dir_path($dir); if (!is_dir($dir)) return FALSE; $list = glob($dir.''); foreach($list as $v) { is_dir($v) ? dir_delete($v) : @unlink($v); } return @rmdir($dir); }
function CalcDirectorySize($DirectoryPath) {
// I reccomend using a normalize_path function here
// to make sure $DirectoryPath contains an ending slash
// (-> http://www.jonasjohn.de/snippets/php/normalize-path.htm)
// To display a good looking size you can use a readable_filesize
// function.
// (-> http://www.jonasjohn.de/snippets/php/readable-filesize.htm)
$Size = 0;
$Dir = opendir($DirectoryPath);
if (!$Dir)
return -1;
while (($File = readdir($Dir)) !== false) {
// Skip file pointers
if ($File[0] == '.') continue;
// Go recursive down, or add the file size
if (is_dir($DirectoryPath . $File))
$Size += CalcDirectorySize($DirectoryPath . $File . DIRECTORY_SEPARATOR);
else
$Size += filesize($DirectoryPath . $File);
}
closedir($Dir);
return $Size;
}
/*
- 获取当前页面完整URL地址 */ function get_url() { $sys_protocal = isset($_SERVER'SERVER_PORT') && $_SERVER'SERVER_PORT' == '443' ? 'https://' : 'http://'; $php_self = $_SERVER'PHP_SELF' ? safe_replace($_SERVER'PHP_SELF') : safe_replace($_SERVER'SCRIPT_NAME'); $path_info = isset($_SERVER'PATH_INFO') ? safe_replace($_SERVER'PATH_INFO') : ''; $relate_url = isset($_SERVER'REQUEST_URI') ? safe_replace($_SERVER'REQUEST_URI') : $php_self.(isset($_SERVER'QUERY_STRING') ? '?'.safe_replace($_SERVER'QUERY_STRING') : $path_info); return $sys_protocal.(isset($_SERVER'HTTP_HOST') ? $_SERVER'HTTP_HOST' : '').$relate_url; }
/*
- 安全过滤函数
- @parame $string
- @return string / function safe_replace($string) { $string = str_replace('%20','',$string); $string = str_replace('%27','',$string); $string = str_replace('%2527','',$string); $string = str_replace('','',$string); $string = str_replace('"','"',$string); $string = str_replace("'",'',$string); $string = str_replace('"','',$string); $string = str_replace(';','',$string); $string = str_replace('>','>',$string); $string = str_replace('<','<',$string); $string = str_replace('{','',$string); $string = str_replace('}','',$string); $string = str_replace('\','',$string); return $string; } ?>
下面是接口文件:
四、调用配置好的站点api.php 文件路径,传入适当参数,就可以实现转换功能。
特别感谢知沃文库系统团队提供的技术指导,同时也欢迎大家指正交流!