利用WebOffice控件來進行編輯office文檔。


最近項目中需要用到在線編輯Office文檔。最后找來找去發現有個免費的控件“點聚WebOffice”。經過兩天的測試發現還不錯。雖然里面也有些不完善的地方。先說一下不足吧,想用的同學可以斟酌。

1、在Widnows 7 x64下運行不穩定,經常會導致ie瀏覽器崩潰。

2、打開的本地文件不能是2007新格式的文檔,如:docx/xlsx。如果打開一個docx的文檔,然后保存到服務器端時會發現沒有任何數據(使用PHP時,查看$_FILES)。

3、客戶端安裝的即便是Office2010,通過控件新建一個文檔,然后保存到服務器端時,格式還是2003以前的文檔格式。即后綴還是使用doc/xls。

4、客戶端安裝的Office最好是完整版的,不要安裝精簡版的。會導致打不開應用程序(官方的QQ群里有些同學提出的此bug)。

5、控件不支持https。

 

下面是我使用PHP時的demo,此demo是根據官方提供的asp版來修改的,僅做了項目中用到的一部分,如:新建與編輯文檔。

1、首先看一下目錄結構:

在站點的根目錄下weboffice_v6.0.5.0.cab是必須的,這樣的話,當客戶端沒有安裝控件時,我們就可以直接通過讓瀏覽器下載此文件來安裝。

2、開始編寫demo.php頁面,此頁面有3個按鈕:新建Word文檔、新建Excel文檔、刷新服務器端文件列表。

刷新服務器端文件列表按鈕的作用是獲取我們保存的文檔列表,即uploadfiles目錄下面的所有的文檔。

當單擊新建時會通過一個隱藏的form表單來打開一個新的頁面(webOffice.php),通過GET方式傳遞fileType參數。fileType值為:doc或xls。

通過單擊服務器端文件列表右側的編輯按鈕道理相同,僅傳遞的參數有所不同。編輯文件時只需要傳遞fileName即可。

View Code
 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <title>WebOffice Demo</title>
 6 <script type="text/javascript">
 7     function editFile(path) {
 8         var f = document.myForm;
 9         f.action = 'webOffice.php?fileName=' + path;
10         f.target = '_blank';
11         f.submit();
12     }
13     
14     function createFile(type) {
15         var f = document.myForm;
16         f.action = 'webOffice.php?fileType=' + type;
17         f.target = '_blank';
18         f.submit();
19     }
20 </script>
21 </head>
22 
23 <body>
24 <form name="myForm" action="webOffice.php" method="post">
25     <input type="hidden" id="fileName" name="fileName" />
26     <input type="button" id="newDoc" name="newDoc" value="新建Word文檔" onclick="createFile('doc')" />
27     <input type="button" id="newDoc" name="newDoc" value="新建Excel文檔" onclick="createFile('xls')" />
28 </form>
29 <form action="?" method="post">
30 <input type="submit" id="getFiles" name="getFiles" value="刷新服務器端文件列表" />
31 </form>
32 <table border="1" width="400" cellspacing="0" cellpadding="0">
33     <tr>
34         <th>文件名稱</th>
35         <th width=60>操作</th>
36     </tr>
37 <?php
38     if ($_POST['getFiles'] != '') {
39         $files = array();
40         $path = dirname(__FILE__) . "/uploadfiles";
41         
42         if ($handle = opendir($path)) {
43             while (false !== ($file = readdir($handle))) {
44                 $ext = substr($file, -3);
45                 
46                 if ($ext == 'doc' || $ext == 'xls') {
47                     // 如果服務器是Windows,文件名稱需要轉換成UTF-8
48                     $files[] = $_ENV['OS'] == 'Windows_NT' ? iconv('GB18030', 'UTF-8//IGNORE', $file) : $file;
49                 }
50             }
51             closedir($handle);
52         }
53         
54         if (count($files) > 0) {
55             foreach ($files as $file) {
56                 echo "<tr><td>$file</td><td><input type='button' value='編輯' onclick='editFile(\"" . $file . "\")' /></td>";
57             }
58         }
59     }
60 ?>
61 </table>
62 </body>
63 </html>

3、編寫webOffice.php頁面。首先要嵌入webOffice控件,可以通過script標簽來插入,官方提供的這個js文件其實很簡單,就是輸出一個object標簽對象。在這里面需要注意的是控件的高度,最好不要使用100%而是使用一個固定的值,如果使用百分比,那么控件所屬的容器就要指定高度。

1 var s = ""
2 s += "<object id=WebOffice1 height=586 width='100%' style='LEFT: 0px; TOP: 0px'  classid='clsid:E77E049B-23FC-4DB8-B756-60529A35FAD5' codebase=weboffice_v6.0.5.0.cab#Version=6,0,5,0>"
3 s +="<param name='_ExtentX' value='6350'><param name='_ExtentY' value='6350'>"
4 s +="</OBJECT>"
5 document.write(s)

嵌入控件之后要監聽控件的NotifyCtrlReady事件,官方提供的方式是使用script標簽的方式來監聽,而不是通過attachEvent的方式,標簽方式有一個優點即可以不必將代碼寫在嵌入控件之后,我們可以將其放在head部分。

 1 <SCRIPT LANGUAGE=javascript FOR=WebOffice1 EVENT=NotifyCtrlReady>
 2 <!--
 3     var fn = '<?php echo $fileName; ?>';
 4     
 5     if (fn) {
 6         fn = './uploadfiles/' + fn;
 7     }
 8     
 9     // 在裝載完Weboffice(執行<object>...</object>)控件后執行 "WebOffice1_NotifyCtrlReady"方法
10     WebOffice1_NotifyCtrlReady(fn, "<?php echo $fileType; ?>");
11 //-->
12 </SCRIPT>

這個事件也就是調用WebOffice1_NotifyCtrlReady函數,而這個函數的作用則是根據fileName來判斷是新建一個文檔還是打開一個文檔。

 1     /**
 2      * 控件初始化WebOffice方法
 3      * @param {String} fileName 要打開的文件名稱
 4      * @param {String} fileType 要打開的文件類型,doc/
 5      */
 6     function WebOffice1_NotifyCtrlReady(fileName, fileType) {
 7         var office = document.all.WebOffice1;
 8         if (fileName) {
 9             office.LoadOriginalFile(fileName, fileType);
10         } else {
11             office.LoadOriginalFile("", fileType);
12         }
13     }

最后一步也就是如何保存到服務器端。要將文檔保存到服務器端需要分四步走。

第一步,初始化HTTP。office.HttpInit();

第二步,由於weboffice的提交數據跟平常的form表單的提交沒什么區別,因此我們可以在此進行附加一些其他的數據,如文件名。office.HttpAddPostString("fileName", fileName);

第三步,將我們需要保存的文檔附加進來。office.HttpAddPostCurrFile("docContent", '');第二個參數就是以什么文件名傳遞給服務器,直接傳遞一個空字符串即可。

第四步,將數據提交到一個php接收頁。office.HttpPost("./resources/php/upload.php");

這四步,除了第二步之外其他的三步都是必不可少的。

下面是webOffice.php頁面的完整代碼:

View Code
 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 2 <html xmlns="http://www.w3.org/1999/xhtml">
 3 <head>
 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5 <title>Office在線編輯器</title>
 6 </head>
 7 <?php
 8     $fileName = $_GET['fileName'];
 9     
10     $fileType = $_GET['fileType'];
11     
12     if ($fileType == '') {
13         $fileType = strtolower(substr($fileName, -3)) == 'doc' ? 'doc' : 'xls';
14     }
15 ?>
16 <script type="text/javascript">
17     /**
18      * 控件初始化WebOffice方法
19      * @param {String} fileName 要打開的文件名稱
20      * @param {String} fileType 要打開的文件類型,doc/
21      */
22     function WebOffice1_NotifyCtrlReady(fileName, fileType) {
23         var office = document.all.WebOffice1;
24         if (fileName) {
25             office.LoadOriginalFile(fileName, fileType);
26         } else {
27             office.LoadOriginalFile("", fileType);
28         }
29     }
30     
31     // 關閉頁面時調用此函數,關閉文件
32     function window_onunload() {
33         document.all.WebOffice1.Close();
34     }
35     
36     function SaveDoc() {
37         var fileType = '<?php echo $fileType; ?>',
38             fileName = document.myForm.fileName.value,
39             office   = document.all.WebOffice1;
40         
41         if (!~fileName.indexOf('.' + fileType)) { fileName += '.' + fileType; }
42         
43         office.HttpInit();
44         
45         // 添加相應的Post元素 
46         office.HttpAddPostString("fileName", fileName);
47         
48         office.HttpAddPostCurrFile("docContent", '');        // 上傳文件
49     
50         var result = office.HttpPost("./resources/php/upload.php");
51         
52         if("OK" == result){
53             alert("文件上傳成功");    
54             window.close();
55         }else
56             alert("文件上傳失敗")
57     }
58 
59 </script>
60 <SCRIPT LANGUAGE=javascript FOR=WebOffice1 EVENT=NotifyCtrlReady>
61 <!--
62     var fn = '<?php echo $fileName; ?>';
63     
64     if (fn) {
65         fn = './uploadfiles/' + fn;
66     }
67     
68     // 在裝載完Weboffice(執行<object>...</object>)控件后執行 "WebOffice1_NotifyCtrlReady"方法
69     WebOffice1_NotifyCtrlReady(fn, "<?php echo $fileType; ?>");
70 //-->
71 </SCRIPT>
72 
73 <body onunload="window_onunload()">
74 <form name="myForm" method="post">
75     <label for="fileName">文件名:</label>
76     <input type="text" id="fileName" name="fileName" value="<?php echo $fileName; ?>" />
77     <input type="submit" id="saveFile" name="saveFile" value="保存文件到服務器" onclick="SaveDoc()" />
78 </form>
79 <script src="resources/js/LoadWebOffice.js"></script>
80 </body>
81 </html>

4、編寫upload.php頁面。即接收上傳的文件並且保存到uploadfiles目錄下。大家還是直接看代碼吧,php上傳沒什么可說的,很簡單,不像是ASP那么麻煩。

在upload.php頁面中用到了一個uf.class.php類,我簡單的封裝的一個上傳類。

uf.class.php
  1 <?php
  2     /**
  3      * PHP上傳文件
  4      * 公開屬性,overwrite,默認true
  5      */
  6     class uploadFile {
  7         private $name;                // 上傳表單的name
  8         private $fileName;            // 文件名
  9         private $uploadDir;            // 文件存放目錄
 10         private $type;                // 允許上傳的文件類型
 11         public $overwrite;            // 是否覆蓋已存在的文件
 12         
 13         function __construct() {
 14             $this->name = 'file';
 15             $this->fileName = '';
 16             $this->uploadDir = 'D:/Codes/WebOffice/uploadfiles/';
 17             $this->type = array("xlsx", "doc", "docx", "xls");
 18             $this->overwrite = true;
 19         }
 20         
 21         /**
 22          * 檢測文件后綴
 23          * @param {String} $f 要檢測的文件名稱
 24          */
 25         public function fileExt($f) {
 26             return substr(strrchr($f, '.'), 1);
 27         }
 28         
 29         /**
 30          * 設置上傳表單的name
 31          * @param {String} $n 表單的name
 32          */
 33         public function setName($n) {
 34             if ($n == '') {
 35                 return false;
 36             } else {
 37                 $this->name = $n;
 38             }
 39         }
 40         
 41         /**
 42          * 設置文件名
 43          * @param {String} $fn 文件名
 44          */
 45         public function setFileName($fn) {
 46             if ($fn == '') {
 47                 return false;
 48             }
 49             $this->fileName = $fn;
 50             return true;
 51         }
 52         
 53         /**
 54          * 設置文件存放目錄
 55          * @param {String} $p 文件存放目錄
 56          */
 57         public function setPath($p) {
 58             if ($p == '') {
 59                 return false;
 60             }
 61             $this->uploadDir = $p;
 62             return true;
 63         }
 64         
 65         /**
 66          * 設置允許上傳的文件格式
 67          * @param {Array} $t 文件格式數組
 68          */
 69         public function setFileType($t) {
 70             if (is_array($t)) {
 71                 $this->type = $t;
 72                 return true;
 73             } else {
 74                 return false;
 75             }
 76         }
 77         
 78         /**
 79          * 上傳文件
 80          */
 81         public function upload() {
 82             if ($this->fileName == '') {
 83                 $this->fileName = $_FILES[$this->name]['name'];
 84             }
 85             
 86             //判斷文件類型
 87             /*if(!in_array(strtolower($this->fileExt($_FILES[$this->name]['name'])), $this->type)) {
 88                 echo "<script>alert('您只能上傳以下類型文件: ".implode(",",$this->type)."');</script>";
 89                 return '';
 90             } else {*/
 91                 $uploadfile = $this->uploadDir.$this->fileName;
 92                 
 93                 if (!$this->overwrite && file_exists($uploadfile)) {
 94                     /*echo "<script>alert('文件已經存在!');</script>";*/
 95                     return '';
 96                 }
 97                 
 98                 if (move_uploaded_file($_FILES[$this->name]['tmp_name'], $uploadfile)) {
 99                     /*echo "<script>alert('上傳成功!');</script>";*/
100                     return $uploadfile;
101                 }
102             /*}*/
103         }
104     }
105 ?>
 1 <?php
 2     require_once('uf.class.php');
 3     $upload = new uploadFile();
 4     $upload->setName('docContent');
 5     if ($_ENV['OS'] != 'Windows_NT') {
 6         $upload->setPath('/var/ins-g/webOffice/uploadfiles/');
 7     }
 8     $upload->setFileName($_POST['fileName']);
 9     $result = $upload->upload();
10     
11     echo "OK";
12 ?>

5、如果有同學跟我一樣,項目是跑在https下,但此控件又不支持https,所以我們還是創建一個虛擬主機來專門的跑這個在線編輯。這也是沒有辦法的辦法。

找到apache的配置文件httpd.conf。在最后添加以下幾行配置信息。

Listen 88
<VirtualHost *:88>
    DocumentRoot /var/ins-g/webOffice
    SSLEngine off
</VirtualHost>

Documentroot的路徑即為插件程序所在的目錄。SSLEngine off即關閉ssl而用http來訪問。

還要注意要設置uploadfiles目錄有可寫的權限。

一切就緒后重啟apache即可。

 

完整的示例與官方開發文檔可以單擊下面的鏈接進行下載。

http://pan.baidu.com/netdisk/singlepublic?fid=759613_3581574499


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM