導讀: 在涉及到word文檔生成的項目中,通常採用編程將數據填充到word模板中生成文件的實現方式,若是模板由開發人員本身設計,那麼編程填充數據是相對容易實現的;但若是用戶但願能夠本身修改模板或本身定義新模板,而且又不須要開發人員針對新模板重寫代碼,那麼應該使用怎樣的技術來實現這種需求呢?本文就此問題展開論述。html
在實際的開發過程當中,針對導出生成word文檔的需求,都是用程序填充數據到word模板中來實現的。所謂模板也就是標記了數據位置和字體段落樣式的Word文件。通常來講,模板中的數據能夠分爲兩種:一種是一對一的,一個數據在模版中對應一個數據位置,好比一個模板只須要使用「部門、姓名、緣由、天數、日期」5個數據,每一個數據只須要在文件中使用一次,以下圖模板所示:編程
用戶定義模板時可使用所有數據,也可使用5個數據中的任意4個、3個甚至1個,但模板中數據標籤的數量老是這個集合的子集。服務器
另外一種是一對多,一個數據在同一個模版中可使用一次,也可使用屢次。例以下圖的介紹信的模板,每個數據都須要在文件中出現兩次。字體
若是一個項目系統中全部的模板都是固定的,那麼只須要在系統開發過程當中由開發人員和用戶一塊兒把模板作好,以後,開發人員根據業務邏輯編寫程序,給模板中的數據位置填充具體的數據便可實現,但在實際的應用中,不少時候不是這樣的,最終用戶仍是但願能本身隨時新建和修改模板,以知足不斷變化的業務需求,若是每次模板的變化都須要和開發人員一塊兒來完成,那麼這個項目就永遠不會完工。
爲了知足用戶的這一需求,在項目中就須要提供一個模板製做和管理的模塊,又爲了讓程序能夠控制和識別用戶定義模板中的數據位置,那麼就須要開發人員來製做一個約定,讓最終用戶在新建或編輯模板時必須按照約定來製做模板。那麼應該如何約定呢? PageOffice提供的解決方案就是使用書籤和特殊格式的文原本對文檔中須要插入數據的位置作標記。spa
第一種方法使用書籤來標記數據位置。Word文檔中插入書籤的方法:把光標定位到須要標記數據位置的地方,點Word菜單中的「插入」-「書籤」,就會彈出一個標題爲「書籤」的對話框,輸入新書籤的名稱,書籤名能夠包含數字但中間不能有空格,用PageOffice開發的時候不推薦使用中文命名書籤名。注意:若是新插入位置或新對象採用的是已有的書籤名,原有的書籤將自動取消,因此使用書籤來標記數據位置的話,確定是一個數據對應模板中一個位置的一對一模式。
在使用PageOffice開發的過程當中,爲了不出現與用戶本身定義的書籤出現衝突,要求插入的書籤名稱必須以「PO_」開頭。注意是字母o,不是數字0。書籤名是不區分大小寫的也能夠寫成「po_」。在PageOffice的概念裏提到的數據區域,本質上就是書籤,可是隻有「po_」開頭的書籤才叫數據區域(DataRegion),請你們注意這點。設計
第二種方法就是使用特殊格式的文原本標記數據位置,好比說:【合同日期】、【##合同日期##】、[合同日期]……等等。使用書籤標記數據位置有一個明顯的缺點,同一個書籤名稱在一個word文檔中只能出現一次,也就是說一個數據區域在文檔中確定是惟一的,可是不少時候模版中須要多處位置使用一樣的數據變量,例如上面舉例使用的「合同日期」可能就須要在一個合同中多個位置出現,使用數據區域確定是沒法知足需求的,可是使用特殊格式的文原本標記就沒有這種限制了。3d
在PageOffice的概念裏,這種【合同日期】、【##合同日期##】、[合同日期]……等等特殊格式的文本均可以被認爲是數據標籤(DataTag),同一個數據標籤能夠在一份文件中多個位置出現屢次,動態填充數據標籤生成文件的時候,同一個數據標籤都會被一樣的數據替換。code
注意:【合同日期】和【##合同日期##】是兩個不一樣的數據標籤,同一個數據標籤必定要是文本格式徹底一致,好比:【##合同日期##】和【##合同日期##】雖然字體顏色和大小都不同,可是文本內容是徹底同樣的,就被認爲是同一個數據標籤,因此在模版製做的時候定義數據標籤是很簡單的,只須要插入一樣格式的文本就能夠了。htm
雖然以上的兩點約定已經定好了,可是讓用戶在編輯模版的時候使用office自身的功能來製做和編輯模版,仍是步驟繁瑣、困難重重,製做的模板也容易出現一些問題,爲此,PageOffice提供了定義模板的接口,由開發人員使用程序預先定義好用戶可使用的數據區域和數據標籤,當用戶編輯模版的時候,給用戶彈出一個數據區域和數據標籤的選擇窗口,用戶只須要選擇使用這些數據區域和數據標籤插入到word模版中,設置好數據的段落格式、字體、樣式、顏色等等。這樣以來,不但處理好了約定的問題,並且使得用戶自定義模板的操做更加簡單快捷。對象
PageOffice給開發人員提供了定義模版的接口DefineDataRegion和DefineDataTag方法,
WordDocument doc = new WordDocument(); doc.getTemplate().defineDataRegion("Name", "[ 姓名 ]"); doc.getTemplate().defineDataRegion("Address", "[ 地址 ]"); doc.getTemplate().defineDataRegion("Tel", "[ 電話 ]"); doc.getTemplate().defineDataRegion("Phone", "[ 手機 ]"); doc.getTemplate().defineDataRegion("Sex", "[ 性別 ]"); doc.getTemplate().defineDataRegion("Age", "[ 年齡 ]"); doc.getTemplate().defineDataRegion("Email", "[ 郵箱 ]"); doc.getTemplate().defineDataRegion("QQNo", "[ QQ號 ]"); doc.getTemplate().defineDataRegion("MSNNo", "[ MSN號 ]");
或者用ASP.NET開發的話,代碼以下:
PageOffice.WordWriter.WordDocument doc = new PageOffice.WordWriter.WordDocument(); doc.Template.DefineDataRegion("Name", "[ 姓名 ]"); doc.Template.DefineDataRegion("Address", "[ 地址 ]"); doc.Template.DefineDataRegion("Tel", "[ 電話 ]"); doc.Template.DefineDataRegion("Phone", "[ 手機 ]"); doc.Template.DefineDataRegion("Sex", "[ 性別 ]"); doc.Template.DefineDataRegion("Age", "[ 年齡 ]"); doc.Template.DefineDataRegion("Email", "[ 郵箱 ]"); doc.Template.DefineDataRegion("QQNo", "[ QQ號 ]"); doc.Template.DefineDataRegion("MSNNo", "[ MSN號 ]");
開發人員用服務器端程序定義好用戶可以使用的數據區域,用戶在客戶端編輯模版的時候就可使用這些數據區域。注意,這裏的代碼中不須要寫PO_ 開頭,PageOffice會自動添加這個前綴。用戶編輯模版時看到的數據區域管理窗口,以下圖所示:
左側「待添加數據區域」列表是能夠用戶目前可使用的數據區域,右側「已添加數據區域」列表是文檔中已經添加的數據區域。此窗口的實現代碼已經由PageOffice封裝完畢,無需開發人員本身寫複雜的js+html代碼去實現,而且此窗口中內容的樣式是能夠修改的,若是對那些樣式不太滿意,只須要對此窗口html代碼的樣式作簡單的調整便可。用戶編輯數據區域時的效果,以下圖所示:
WordDocument doc = new WordDocument(); doc.getTemplate().defineDataTag("{ 甲方 }"); doc.getTemplate().defineDataTag("{ 乙方 }"); doc.getTemplate().defineDataTag("{ 擔保人 }"); doc.getTemplate().defineDataTag("【 合同日期 】"); doc.getTemplate().defineDataTag("【 合同編號 】");
或者用ASP.NET開發的代碼以下:
PageOffice.WordWriter.WordDocument doc = new PageOffice.WordWriter.WordDocument(); doc.Template.DefineDataTag("{ 甲方 }"); doc.Template.DefineDataTag("{ 乙方 }"); doc.Template.DefineDataTag("{ 擔保人 }"); doc.Template.DefineDataTag("【 合同日期 】"); doc.Template.DefineDataTag("【 合同編號 】");
開發人員用服務器端程序定義好用戶可以使用的數據標籤,用戶在客戶端編輯模版的時候就可使用這些數據標籤。用戶編輯模版時看到的數據標籤管理窗口,以下圖所示:
同數據區域同樣,對此窗口的實現代碼,PageOffice也已經封裝完畢,無需開發人員本身寫複雜的js+html代碼去實現,而且此窗口中內容的樣式是能夠修改的,若是對那些樣式不太滿意,只須要簡單的調整一下此窗口html代碼中的樣式便可。開發人員只管編寫程序給數據標籤賦值對應的數據,用戶本身定義模版的樣式、數據位置和數據的多少,用戶可使用所有的數據區域,也能夠只使用部分, PageOffice在生成文件的時候,會自動忽略沒有使用的數據標籤,而不須要開發人員作任何代碼的調整。
與數據區域的管理不一樣的是,因爲數據標籤在文件中不是惟一的,因此無論在文件中添加了多少個數據標籤,在數據標籤管理窗口中的數據標籤都是不會減小的。
開發人員只須要使用上面的兩個方法,針對word模版編寫程序,給全部的數據區域和數據標籤賦值相應的數據便可,無需關心模版中到底使用了多少個數據區域和數據標籤,那些Word模版中歷來沒有使用過的數據區域和數據標籤,PageOffice會自動忽略,而無需開發人員作任何代碼的修改,從而完美實現用戶自定義模板的需求。
Java開發的賦值代碼以下:
WordDocument doc = new WordDocument(); doc.openDataRegion("Name").setValue("張三"); doc.openDataRegion("Age").setValue("21"); …… doc.openDataTag("{ 甲方公司名稱 }").setValue("微軟中國總部"); doc.openDataTag("{ 乙方公司名稱 }").setValue( "北京幻想科技公司"); …… poCtrl.setWriter(doc);
ASP.NET開發的賦值代碼以下,
PageOffice.WordWriter.WordDocument doc = new PageOffice.WordWriter.WordDocument(); doc.OpenDataRegion("Name").Value = "張三"; doc.OpenDataRegion("Age").Value = "21"; …… doc.OpenDataTag("{ 甲方公司名稱 }").Value = "微軟中國總部"; doc.OpenDataTag("{ 乙方公司名稱 }").Value = "北京幻想科技公司"; …… PageOfficeCtrl1.SetWriter(doc);
詳細請參考PageOffice開發包裏Samples4中的相關示例演示: 2、30、用戶自定義模板中數據區域(DataRegion)的位置(專業版、企業版) 2、3一、用戶自定義模板中數據標籤(DataTag)的位置(專業版、企業版) 3、十二、實現「用戶自定義Word模板」動態生成文件(專業版、企業版)