一个在线显示doc文本的实例

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">最近带着一对攻城狮给客户做一个web平台系统,在与客户做需求分析的过程中,发现客户有个需求痛点,那就是希望能在web上直接浏览doc文本的内容。原来的老平台在显示doc文本时,有很多问题,例如原有doc文本排版格式显示错误,例如表格位置发生了偏移,字体不再是原有doc里的字体等等。如果新系统能解决客户这一痛点,想必我们技术团队的实力会得到客户进一步的肯定。</span>


我做过调查,发现在线显示doc文本内容方法很多,一种方法是购买中间件,例如pageoffice等,这种方法缺点是中间件价格较高,客户不愿意多花费。另外方法是,先将doc转换成pdf, 将pdf转化成swf, 在客户端安装flexpaper插件,然后播放转化好的swf, 百度文库就是这么做的。第二种方法有一个很大的缺点是,用户必须自己安装flexpaper插件。但很多用户都是电脑小白,让他们动手做些操作,即使简单,但他们也会有很强的抗拒感,所以第二种方法不可行。


经过一段时间的思索,我发现可以将第二种方法简化,从而去掉手动安装插件的步骤,这样便能极大的改善用户体验了。我的做法是:doc转pdf, 然后利用mozilla开源javascript代码播放转换好的pdf,这样一来,用户将doc上传服务器后,可以通过转换后的pdf,方便的浏览上传的doc文档, 为此我在阿里云上实现了我的想法,例子如下:

在浏览器中输入:http://123.56.124.193/pdf.js/web/upload.html,会显示出doc文档上传页面:


点击 "send file" 按钮, 选择的doc文档会上传到阿里云服务器,在服务器上,我会将doc转换成pdf, 然后让浏览器将转换后的pdf显示出来:


pdf 能完美的保留doc的文档格式,显示效果跟doc完全一样,这种实现方法让客户很满意,由于我在研究的过程中学习和借鉴了很多网友的做法,这次把我的做法分享出来,和大家一起探讨。


mozilla pdf js 插件下载:

在服务区目录下执行:

git clone git://github.com/mozilla/pdf.js.git
下载后,在浏览器输入:

http://your_host_ip/pdf.js/web/viewer.html

那么一个pdf显示例子就会出来了,有关插件的详细信息可访问:

https://github.com/mozilla/pdf.js


实现细节:

1. doc 转 pdf.

doc 转 pdf 方法很多,我用的是libreoffice 的转换功能,由于我使用的是阿里云ubuntu服务器,其本身就自带了libreoffice 软件,通过libreoffice 将doc格式文件转换成pdf的命令比较简单,假设当前目录下有一个doc文档叫 1.doc, 那么将其转化为pdf 命令如下:

libreoffice --headless --invisible --convert-to pdf 1.doc

执行后,目录下会自动生成 1.pdf.


2. php 实现自动转换。

我们不可能对用户上传的每个doc文档,都手动调用上面的命令来转化,这里,我利用php来实现自动调用libreoffice 的pdf 转换命令功能,php 的exec能直接执行shell 命令,但如果在脚本中直接输入上述命令执行exec,那是会失败的。因为libreoffice 运行时,需要对HOME读取环境变量,用php执行exec,执行环境的HOME 环境变量是空,所以直接利用php调用是不行的,在php脚本代码中需要先设置HOME变量,在执行exec函数,代码如下:

<?php
      function execInBackground($cmd) {

        if (substr(php_uname(), 0, 7) == "Windows"){

        pclose(popen("start /B ". $cmd, "r"));

       }

        else {
            exec($cmd);
        }
}

 function convertDoc2Pdf($filename)
      {
          $mainFile = $filename;

          $cmd2 = "export HOME=/tmp

             libreoffice --headless --invisible --norestore --convert-to pdf " .
                    "'$mainFile'";

        $saved = getenv("LD_LIBRARY_PATH");        // save old value 

        $newld = "/usr/lib";  // extra paths to add 

        if ($saved) {
            putenv("LD_LIBRARY_PATH=" . $newld);
        }

        execInBackground($cmd2);
        putenv("LD_LIBRARY_PATH=$saved");
    }
?>

只要把上传的doc名字传给converDoc2Pdf, 那么服务器端就自动对上传的doc 转换成pdf.

3. 设计上传页面

上传页面很简单,就是一个上传文件的表单:

<html>
    <head>
      <title>Upload a doc file</title>
    </head>

    <body>
      <h1>upload new files</h1>
      <form action="upload.php" method="post" enctype="multipart/form-data"/>
         <div>
           <input type="hidden" name="MAX_FILE_SIZE" value="67108864" />
           <label for="userfile">Upload a file:</label>
           <input type="file" name="userfile" id="userfile"/>
           <input type="submit" value="send File"/>
         </div>
      </form>
    </body>
  </html>

4. 上传后php的处理

当文件上传到服务器后,服务器执行upload.php, php脚本先对上传的文件作一些安全检查,并检查上传的文件是否是doc文档,如果不是,返回错误信息,如果是的话,将文件转到pdf.js/web 目录下,然后调用converDoc2Pdf函数将文本转成pdf, 接着返回一个301重定向给浏览器,浏览器根据重定向的url, 加载mozilla pdf插件,并显示转换好的pdf文档:

<html>
  <head>
    <title>Uploading...</title>
  </head>
  <body>
    <h1>Uploading file<h1>
    <?php
      function execInBackground($cmd) {

        if (substr(php_uname(), 0, 7) == "Windows"){

        pclose(popen("start /B ". $cmd, "r"));

       }

        else {
            exec($cmd);
        }
      }

      function convertDoc2Pdf($filename)
      {
          $mainFile = $filename;

          $cmd2 = "export HOME=/tmp

             libreoffice --headless --invisible --norestore --convert-to pdf " .
                    "'$mainFile'";

        $saved = getenv("LD_LIBRARY_PATH");        // save old value 
        $newld = "/usr/lib";  // extra paths to add 

        if ($saved) {
            putenv("LD_LIBRARY_PATH=" . $newld);
        }

        execInBackground($cmd2);
        putenv("LD_LIBRARY_PATH=$saved");
      }

function get_extension($filename) {
        return substr($filename, strrpos($filename, '.') + 1);
    }

      if ($_FILES['userfile']['error'] > 0)
      {
         echo 'Problem:';
         switch ($_FILES['userfile']['error'])
         {
           case 1: echo 'File exceeded upload_max_filesize';
                   break;
//           case 2: echo 'File exceeded max_file_size';
  //                 break;
           case 3: echo 'File only partially upload';
                   break;
           case 4: echo 'No file uploaded';
                   break;
           case 6: echo 'Cannot upload file: No temp directory specified';
                   break;
          case 7: echo 'Upload failed: Cannot write disk';
                   break;
         }
         exit;

      }

      $upfile = '/var/www/html/pdf.js/web/'.$_FILES['userfile']['name'];
      if (get_extension($upfile) != "doc")
      {
         echo "upload file is no word document<br/>";
         exit;
      }
      if (is_uploaded_file($_FILES['userfile']['tmp_name']))
      {
        if (!move_uploaded_file($_FILES['userfile']['tmp_name'], $upfile))
        {
          echo 'Problem: Could not move file to destination directory';
          exit;
        }
      }
      else
      {
        echo 'Problem: Possible file upload attack. Filename: ';
        echo $_FILES['userfile']['name'];
        exit;
      }

      echo 'File uploaded successfully and begin to convert to pdf<br><br>';
      convertDoc2Pdf($_FILES['userfile']['name']);
      $pdfFileName = str_replace(".doc", ".pdf", $_FILES['userfile']['name']);
      $redirectURL = "http://123.56.124.193/pdf.js/web/viewer.html?file=".$pdfFileName;
      header("Location: ".$redirectURL, true, 301);
    ?>
    
  </body>
</html>

以上就是我做的一个在线显示doc文档的小系统,系统放在阿里云服务器,大家可以用我在文中提供的url上传doc文件来体验一下。


猜你喜欢

转载自blog.csdn.net/tyler_download/article/details/50013359