溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

.net 2.0下的OOXML神器:NPOI.OpenXml4Net

發布時間:2020-07-15 04:54:09 來源:網絡 閱讀:2700 作者:瞿杰 欄目:編程語言

作者:Tony Qu

NPOI官方博客:http://tonyqus.sinaapp.com | 官方QQ群:189925337

 

可能很多人已經習慣了使用.Net 3.0下的System.IO.Packaging(WindowsBase.dll)來操作Office 2007/2010的文件格式,以至于大家都默許了.net 2.0下無法操作OOXML文件的觀點,盡管也有人使用第三方zip類庫來操作OOXML文件,但是遇到關系維護之類的問題,就開始糾結了,你必須自己去不斷地維護.rels文件(OOXML中用于維護文件內關系的文件,這里不是后綴名,這個文件就叫這個名字。),而且文件的內容越復雜,關系維護就越痛苦。盡管微軟出了OpenXml SDK 2.0,但是很遺憾,這套庫也是基于.net 3.0的。當然,我倒不是.net 3.0的堅決反對者,只是出于部署方面的考慮,要知道目前基于.net 2.0的應用還是占據相當一部分份額的,盡管.net 3.0/3.5出來也3年了,但是相對于.net 2.0而言,只能算剛剛起步,這也是NPOI始終堅持.net 2.0版本為主線版本的原因。

有人可能要說,.net 3.0/3.5不也是基于.net 2.0的嗎?話是這么說,但是部署起來,還是要單獨部署.net 3.0包,不是嗎?相當于額外增加一套庫,就拿我目前的公司來說,我們仍然在用vs2005開發,服務器上也只部署了.net 2.0 framework。

.net 2.0下的OOXML神器:NPOI.OpenXml4Net

poi中有一個庫叫OpenXml4j,由Julien Chable于2008年捐贈給POI項目,主要負責OOXML基礎操作,如創建、讀取、修改、關系維護等。最近NPOI團隊完成了OpenXml4j的移植工作,于是就有了NPOI.OpenXml4Net,該組件將包括在NPOI下一個版本中,目前你可以通過googlecode的svn獲得完整代碼,自行在本地編譯。OpenXml4Net使用SharpZip作為底層zip操作庫,而非Ionic.Zip,主要原因是SharpZip的設計與java中的zip庫更接近,移植相對簡單,所以我們選擇了這條捷徑。不過有一點要向大家說明,OpenXml4Net僅負責底層操作,比如創建部件、創建關系等,但不包括Office上層的功能,如創建xlsx文件、添加單元格等,這只是一個底層操作庫,NPOI將在后續版本中陸續增加,Excel 2007, Word 2007, PowerPoint 2007對應的命名空間分別是NPOI.XSSF, NPOI.XWPF, NPOI.XLSF,NPOI.XSSF按計劃將在半年內完成(預計在2012年6月或7月發布),這次隨本文發布的算是社區預覽版,你可以基于這個版本給我們提建議和bug。

從頭創建OOXML文件

任何一個OOXML都是一個zip文件,在本例中為了方便打開,我們直接使用.zip作為新建文件的擴展名。

//create ooxml file in memory
Package p = Package.Create();

//create package parts
PackagePartName pn1=new PackagePartName(new Uri("/a/abcd/e",UriKind.Relative),true);
if (!p.ContainPart(pn1))
    p.CreatePart(pn1, MediaTypeNames.Text.Plain);

PackagePartName pn2 = new PackagePartName(new Uri("/b/test.xml", UriKind.Relative), true);
if (!p.ContainPart(pn2))
    p.CreatePart(pn2, MediaTypeNames.Text.Xml);

//save file 
p.Save("test.zip");

//don't forget to close it
p.Close();

這里我們創建了2個部件,分別是位于/a/abcd目錄下的e,和位于/b目錄下的test.xml。這里有幾點值得注意:

a. Package.Create有好幾種調用方式,其中一種是上面這種Package.Create(),這樣最直接的好處就是可以在內存中創建文件;而Package.Create(path),即事先傳入文件名,直接在文件系統上創建文件,不用MemoryStream。當然啦,對于大文件(超過100M)以上的文件,使用Packakge.Create()做會占用較多的內存,所以如果并發量很高的話,建議慎用。

b. 用了p.ContainPart來判斷節點是否已經存在,盡管對于新創建的文件這么做意義不大,但是這是個好習慣。

c. 創建PackagePartName的時候,Uri必須是Relative類型的,所以要傳UriKind.Relative。這一點.Net做的比較挫,默認Uri都是Absolute的,而且一旦Uri為Relative類型的,基本上調用任何Uri的屬性全部會拋異常,這實現夠坑爹的。

 

修改已存在的OOXML文件,并保存為新文件

修改已存在的文件也很簡單,Package.Open就可以了,但由于最后要保存,務必傳入PackageAccess.READ_WRITE,否則會拋異常。

//create ooxml file in memory
Package p = Package.Open("test.zip",PackageAccess.READ_WRITE);
//create package parts
PackagePartName pn3 = new PackagePartName(new Uri("/c.xml", UriKind.Relative), true);
if (!p.ContainPart(pn3))
    p.CreatePart(pn3, MediaTypeNames.Text.Xml);

//save file 
p.Save("test1.zip");

//don't forget to close it
p.Close();

對于已存在的文件,目前仍然有個bug,那就是不能直接保存為當前文件名,存在文件被占用的問題,我們將嘗試在正式版中解決這個問題。

 

目前我們仍然在對OpenXml4Net接口進行調整,以提高組件的易用性和穩定性。如果大家發現啥bug或者問題,請直接通過郵件聯系我。

下載NPOI.OpenXML4Net請到這里:http://code.google.com/p/npoi/downloads/list

OpenXML4Net的源代碼請通過googlecode svn獲取

 

今年NPOI計劃出一本入門級指導書,名字未定,主要面向NPOI初學者,也可以作為NPOI功能速查手冊,幫助更多的人上手。有興趣的出版社可以通過.net 2.0下的OOXML神器:NPOI.OpenXml4Net聯系我。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女