當了解word實質上是xml以後,就不難了解如何操作word了。理論上說,你不需要任何工具就能對它進行操作,當然複雜性極高。微軟推出了open xml sdk, 專門幫助.net語言與office實作互操作,這也成了com元件外的新選擇,但它的安裝包有100m, 對很多部署來說,難度不小。
這個元件docx本身實際上是對xml操作的封裝庫,如果你有興趣看它的源代碼,基本核心就是xml的字元串組裝和拼接,添加一個圖表的本質就是在對應xml标簽下面再增加一個圖表的子文檔。
看到字元串拼接,有經驗的同學肯定站出來會問性能如何。它沒有使用stringbuilder,但本身性能不差,我生成100頁的圖文并茂的word文檔也是瞬間的事情,是以,沒有關系。
對程式開發來說,最常見的需求便是自動生成文檔,完全從0生成圖文并茂,排版合理的文檔對程式員來說不現實,代碼多得海了去了。是以很多人的做法是字元串替換,通過替換特定文字來操作,但這樣顯然是相當不專業的。
比較合理的做法,是office裡面的“域”。域的本質,對程式員來說就是表達式,這個變量可以是文檔字數,文檔頁數(這是office裡面自帶的屬性)。域相當牛逼,甚至可以連接配接到一個資料庫,一個按鈕,乃至一篇網頁上去,真心無所不能。
同樣你也可以自己添加屬性,也就是所謂“自定義屬性”。
如何檢視文檔中的所有自定義域呢?
在word最上面的“插入”卷展欄下選擇文檔部件->域,如下圖所示,并在域控制框中左側選擇docproperty,即可看到所有的屬性:

怎麼在文檔中插入一個自定義域呢?一種做法是,随便在上圖中選擇一個域(比如author),點選确定,就會在插入的位置生成一個域。 然後點選右鍵,選擇‘切換域代碼’,即可改變裡面的域定義:
修改author,變成你想要的屬性,就可以了,把這個東西拷到别的地方,再修改下域代碼,就是一個新的域定義了。這些域定義,可以被我們用程式操作來替換。
由于域實質上是表達式,是以涉及一個計算過程。可以選擇列印時自動更新,或者ctrl+a全選,然後f9,就可全部更新所有域表達式。
但是,在實際開發中,有個緻命的問題: 當你通過模闆,為自定義屬性指派,生成新文檔後,打開新文檔這些域并沒有自動更新,這是非常麻煩的,因為客戶可不想打開文檔後發現那些核心資料都是奇怪的東西,讓他們去摁f9自動更新域更是不可能。但要命的是,有些域被更新了,有些域沒有更新,從域定義上來看,沒有任何差別,這到底是怎麼回事? 如果有大神解決了這個問題,請不吝賜教!
說到這裡,有一個良好排版的模闆,加上自動替換的功能,文檔生成應該差不多了吧?不,還要插入圖表和圖檔,這些用域暫時還不好解決。
插入圖檔的問題,關鍵是插入位置,你需要找到要插入的位置所在的段落(paragraph).我的做法是,用linq查詢,通過定位關鍵字的做法找到段落,然後插入之即可。雖然粗糙,但還能用。插入表格類似。
但,怎麼插入圖表?所謂圖表,就是柱狀圖餅狀圖等等的東西?雖然官方示例裡有生成圖表的功能,但我用word2013怎麼都打不開: “該文檔有問題”。百思不得其解,花了半天才在别人的2010上打開,大喊坑爹(是以,docx對office2013的相容性不夠!)
那好吧,我們用word2010或者07總可以了吧?但目前版本的源代碼,隻能往文檔的最後添加圖表,因為隻有一個這樣的函數:
這不是坑爹呢麼?另外有時候插入圖表或圖檔會出錯,顯示xml錯誤,建立連接配接的id重複! 更是坑爹。
在這個地方會抛異常。
經過分析,是上面那個生成relationshipid的函數出錯了, 後來,索性改了這個函數的方法,直接從guid生成,這樣就不會錯了,代碼如下。
至于隻能在文檔最後添加圖表的問題,我做了以下的代碼修改:
和源代碼對比,很容易就能看出兩者的差別。
我能添加更多的圖表嗎?當然可以。源代碼隻内置了三種圖表:pie, line和bar,不能滿足要求,既然充分了解了它的原理,不妨我們擴充它吧:
用了這個元件,感受良多,這哥們和我一樣的在校學生,,但已經做了這樣的開源項目,下載下傳量超過18000+。 雖然理論不一定多牛逼,但确實滿足廣大人民群衆需要了,400kb的dll檔案,直接解決了.net平台word生成這一剛性需求。 但作者确實下了功夫,大量的xml轉換和分析,純粹的體力活啊!
1. 對office2013的支援不夠
2. api遠沒達到完善,例如無法良好的操作圖表類型,隻能使用預設值。
3. 代碼欠重構,可獲得更好的程式風格和性能的提升。
4. 域更新不正常
如果這幾個問題能解決,那确實是最好不過的了。除此之外,其實還有很多小問題,一方面期待作者解決,另外一方面如果項目需求緊急的話,索性我們自己先改了得了。代碼還是很容易了解的。
我嘗試把它用在項目中,經過測試,發現基本穩定,大家可以嘗試采納。
有任何問題,歡迎随時交流,如果您覺得對您有幫助,請點推薦,謝謝!