1. 程式人生 > >不同使用者同時編輯Word文件中不同區域

不同使用者同時編輯Word文件中不同區域

1、功能介紹

         PageOffice能實現不同使用者同時編輯一個Word文件的不同區域,且儲存後不會相互影響和覆蓋他人編輯修改的內容。

線上對Word文件進行編輯時,可能會出現多人同時訪問、編輯同一個文件中不同區域的情況,例如多個老師同時線上批改一份試卷的不同題目、多個領導審批一份檔案並要在不同的地方加註不同的審批意見等等。要想實現這些功能,一般來說,在寫程式時,既要給不同的使用者分配不同的許可權和其可編輯的區域,還要控制不同使用者在編輯完自己的可編輯區域後儲存檔案時不能覆蓋他人的編輯內容。若是隻給不同使用者分配不同許可權是十分簡單和容易實現的,在此篇文章中不再多說,但是以往的程式設計方法根本無法實現多個使用者同時編輯Word

中的不同區域,而且儲存時也無法控制當前使用者儲存的內容不覆蓋前者儲存的內容。

而通過PageOffice中的資料區域(即DataRegion類)來實現不同使用者同時編輯一個Word文件中不同並且儲存時相互不受影響這一系列的功能就變得相當簡單而容易了。

什麼是資料區域?資料區域是Word文件中具有 "PO_" 字首命名的書籤所定位的文件區域。簡單來說,資料區域就是一種特殊的Word書籤物件,便於定位Word文件中的內容。資料區域是PageOffice開發平臺中重要的技術概念。

這裡舉個簡單的例子說明什麼是資料區域:假設開發者需要在待開啟的Word文件指定位置處顯示產品名稱,就可以先手動開啟此Word文件,在指定位置處插入書籤"PO_ProductName",儲存文件。這樣資料區域"ProductName"就定義好了。編寫程式碼 doc.OpenDataRegion("ProductName").Value ="PageOffice"; 即可在此資料區域處生成想要的內容。

資料區域的填充及資料區域格式的控制都是通過DataRegion類實現的,很多Word操作都需要呼叫DataRegion類完成。DataRegion類能通過呼叫 OpenDataRegion(String) 方法或CreateDataRegion(String, DataRegionInsertType, String) 方法獲得 DataRegion 物件。

         PageOffice實現多使用者同時編輯一個Word文件只需先在一個Word文件中可編輯區域的各個位置分別插入書籤做成Word模版,模版中有幾個可編輯區域再相應地建立幾個Word文件,最後通過程式將這些Word動態填充到資料區域中就可以實現多人同時編輯一個Word

文件了。

一般的開發人員使用Word比較少,可能不清楚Word書籤是怎樣插入的,下面簡單的介紹一下插入書籤的方法。

第一種方法:把游標定位到需要標記資料位置的地方,點Word選單中的“插入”-“書籤”,就會彈出一個標題為“書籤”的對話方塊(如下圖所示),輸入新書籤的名稱,注意:書籤名必須以字母、漢字、中文標點等開頭,可以包含數字但中間不能有空格(用PageOffice開發的時候不推薦使用中文命名書籤名)。點右側的“新增”按鈕,新的書籤名將出現在下面的列表中

第二種方法:選擇幾個文字、或一段文字、或者選擇一段包含表格和圖片的內容,為選中的內容指定書籤的物件,然後執行第一種方法的同樣操作,“插入”→“書籤”……

注意:如果新插入位置或新物件採用的是已有的書籤名,原有的書籤將自動取消。

PageOffice示例程式碼中的模板在製作的時候,多采用第二中方法定義書籤,插入書籤之前會先寫一個標示性的詞語用中括號括起來,比如:[姓名],然後選中“[姓名]”,再插入書籤。這樣做的目的是便於在檢視或編輯模板資料位置的時候一目瞭然。

在使用PageOffice開發的過程中,為了避免出現與使用者自己定義的書籤出現衝突,要求插入的書籤名稱必須以“PO_”開頭。注意是字母o,不是數字0。

在PageOffice的概念裡提到的資料區域,本質上就是書籤,但是隻有“PO_”(或者小寫的“po_”)開頭的書籤才叫資料區域,請大家注意這點。

二、不同使用者同時編輯Word文件中的不同區域的具體實現方法

         PageOffice多使用者同時編輯一個Word文件中的不同區域的實現過程很簡單,只需要將PageOfficeCtrl控制元件類結合WordDocument類和DataRegion類使用即可實現,具體的實現步驟如下:

①先在一個Word文件中設定好文件的正文,再在要設定可編輯區域的各個位置分別插入書籤(命名為“PO_com1”、“PO_com2”、)做成Word模版,命名為“test.doc”。

②“test.doc”模版中設定了幾個資料區域,就相應地再建立幾個Word文件,分別命名為“content1.doc”、“content2.doc”等。在這些建立的Word文件中可以根據需要設定文字格式和樣式。

③在程式中,通過DataRegion類將那些建立的Word文件動態填充到資料區域中。部分程式碼如下:

WordDocument doc = new WordDocument();

//開啟資料區域

DataRegion d1 = doc.openDataRegion("PO_com1");

DataRegion d2 = doc.openDataRegion("PO_com2");

//給資料區域賦值

d1.setValue("[word]doc/content1.doc[/word]");

d2.setValue("[word]doc/content2.doc[/word]");

注意:若要多人編輯Word檔案後儲存時不會相互覆蓋儲存結果,那麼,就要將各個資料區域中的內容分別儲存到單獨的Word檔案中。因此,在動態填充資料區域時,一定要將DataRegion物件的屬性“SubmitAsFile”設定為true。如下:

d1.setSubmitAsFile(true);

d2.setSubmitAsFile(true);

這樣以來,在儲存時PageOffice就會分別將資料區域的內容儲存到單個的Word檔案中。

資料區域值的型別可以是文字型別、Word檔案型別、Excel檔案型別、圖片型別等。一般將Word、Excel、圖片型別的值賦值給資料區域時,寫法為:“[word]word檔案路徑[/word]”、“[excel]excel檔案路徑[/excel]”、“[image]image圖片路徑[/image]”。此處為了實現多人同時編輯儲存一個Word文件且儲存結果互不受影響的效果, 只使用Word檔案型別。

PageOffice標準版只支援文字型別,專業版只支援文字、圖片和Word檔案型別,企業版文字、Word檔案、Excel檔案、Image圖片型別都支援。使用時請一定要注意。

資料區域的具體使用方法和屬性設定請參見相應開發語言的開發幫助和開發示例包中的示例。

④在程式中,控制不同使用者對Word文件中不同資料區域的可編輯性,即設定DataRegion類物件的Editing屬性,設定為true,即表示該資料區域可編輯;設定為false,則表示該資料區域不可編輯,該屬性的預設值為false

d1.Editing = true; //資料區域可編輯

    d2.Editing = false; //資料區域不可編輯

⑤呼叫PageOfficeCtrl控制元件類的WebOpen(Stringfilename, OpenModeType type, String userName)方法開啟Word檔案(“test.doc”)。注意,為了實現提交資料區域中的資料和將其分別儲存到不同的Word檔案中(“content1.doc”、“content2.doc),WebOpen()方法中的第二個引數,即Word文件的開啟模式需使用“docSubmitForm”。

⑥編輯完內容,點選儲存按鈕儲存Word文件時,PageOffice會在儲存頁面中將各個資料區域內編輯的內容分別儲存到各自的Word文件(“content1.doc”、“content2.doc)中。但是模版文件“test.doc”是不會提交和儲存的,這一點請注意。還有美中不足的就是不同使用者在不同資料區域內進行編輯時,頁面中不能實時的顯示Word中其它資料區域內的編輯內容,需儲存再重新整理頁面後才能顯示。

         PageOffice不同使用者同時編輯一個Word文件中不同區域並儲存的部分實現程式碼如下:

         //Java實現程式碼

控制不同使用者同時編輯一個Word文件中不同區域的程式碼:

... ...

WordDocument doc = new WordDocument();

//開啟資料區域

DataRegion d1 = doc.openDataRegion("PO_com1");

DataRegion d2 = doc.openDataRegion("PO_com2");

//給資料區域賦值

d1.setValue("[word]doc/content1.doc[/word]");

d2.setValue("[word]doc/content2.doc[/word]");

//若要將資料區域內容存入檔案中,則必須設定屬性“setSubmitAsFile”值為true

d1.setSubmitAsFile(true);

d2.setSubmitAsFile(true);

//根據登入使用者名稱設定資料區域可編輯性

//甲客戶:zhangsan登入後

if (userName.equals("zhangsan")) {

d1.setEditing(true); //設定資料區域為可編輯

d2.setEditing(false); //設定資料區域為不可編輯

}

//乙客戶:lisi登入後

... ...

PageOfficeCtrl poCtrl = new PageOfficeCtrl(request);

poCtrl.setWriter(doc); //不要忘記此句

poCtrl.addCustomToolButton("儲存", "Save", 1); //新增自定義儲存按鈕

... ...

poCtrl.setSaveDataPage("SaveData.jsp?userName=" + userName); //設定儲存頁

poCtrl.webOpen("doc/test.doc", OpenModeType.docSubmitForm, userName);//開啟模式為:docSubmitForm

poCtrl.setTagId("PageOfficeCtrl1");//此行必須

儲存頁面程式碼:

... ...

WordDocument doc = new WordDocument(request, response);

//根據使用者名稱判斷要儲存到哪個Word檔案中

if (request.getParameter("userName") != null &&request.getParameter("userName").trim().equalsIgnoreCase("zhangsan")) {

bytes = doc.openDataRegion("PO_com1").getFileBytes();

filePath = "content1.doc";

}

... ...

    //將檔案流儲存到Word文件中

FileOutputStream outputStream = new FileOutputStream(filePath);

outputStream.write(bytes);

outputStream.flush();

outputStream.close();

         //C#實現程式碼

控制不同使用者同時編輯一個Word文件中不同區域的程式碼:

WordDocument doc = new WordDocument();

DataRegion d1 = doc.OpenDataRegion("PO_com1");//開啟資料區域

d1.Value= "[word]doc/content1.doc[/word]"; //給資料區域賦值

d1.SubmitAsFile= true; //若要將資料區域內容存入檔案中,則必須設定屬性“SubmitAsFile”值為true

......

//根據登入使用者名稱設定資料區域可編輯性

//甲客戶:zhangsan 登入後

if (userName.Equals("zhangsan"))

{

d1.Editing= true;

d2.Editing= false;

}

//乙客戶:lisi 登入後

......

PageOfficeCtrl1.AddCustomToolButton("儲存", "Save",1); //新增自定義按鈕

......

PageOfficeCtrl1.SaveDataPage= "SaveData.aspx?userName=" +userName; //設定儲存頁

PageOfficeCtrl1.WebOpen("doc/test.doc", PageOffice.OpenModeType.docSubmitForm, userName);//開啟文件

儲存頁面程式碼:

PageOffice.WordReader.WordDocument doc = newPageOffice.WordReader.WordDocument();

//判斷登入的使用者

if (Request.QueryString["userName"]!= null && Request.QueryString["userName"].Equals("zhangsan"))

{

saveBytesToFile(doc.OpenDataRegion("PO_com1").FileBytes, Server.MapPath("doc/content1.doc"));//儲存資料區域的內容到相應的Word文件中

}

......

//儲存檔案流到Word檔案中

private voidsaveBytesToFile(byte[] bytes, string filePath)

{

FileStream fs = new FileStream(filePath,System.IO.FileMode.OpenOrCreate);

fs.Write(bytes, 0, bytes.Length);

fs.Close();

}

         上述示例的完整程式碼請參考相應開發語言的Samples示例包中高階功能的第19個示例:“控制不同使用者編輯Word文件中不同的區域(可同時編輯)(企業版)”。