2010年3月13日

[輕鬆學會 Chart Control] 將圖表匯出至 Excel - 使用NPOI

好久沒開 Chart Control 議題了
剛好前陣子 Codeplex 出現可以輕鬆建立 Excel 檔案的 Library-NPOI
於是坎尼想說研究一下,看能不能把 Chart Control 匯出圖片到 Excel 中
沒想到只花了不到1小時就研究出來了,真的是很簡單 :D

I.準備

首先是下載 NPOI Library,並將它加入至專案中
其他相關說明可以參考 MSDN 上的文章
在 Server 端存取 Excel 檔案的利器:NPOI Library

坎尼這邊就不多話,直接進入今天主題

II.範例

首先開啟一個 Web 專案,把 NPOI 的 Library 加入專案中
建立一個 Web page,在畫面上放入一個 Chart Control
另外再放個 Gridview 來呈現資料 ,最後建立 Button 來觸發匯出的事件
nwc01 將畫面切換到 .cs 檔裡
引用這次範例中會用的兩個 Namespace:
NPOI.HSSF.UserModel – 建立 Excel 內容
NPOI.HSSF.Util - 建立相關樣式屬性

nwc00 
接著到匯出按鈕事件,建立 workbook 部分也跳過 (那不就什麼都沒講嗎? 毆
nwc03上面的 Code 就不詳細說明,主要是將 Chart 存成 Stream
再利用 NPOI 提供圖片插入方法,把 Stream 轉為 Excel 可讀取的圖片格式
(注意圖片的匯出格式以及匯入格式)
最後再將整個 workbook 匯出即可 (見下圖)
nwc02 資料部分坎尼本來還想加上樣式,後來覺得有點麻煩就作罷 (喂!

III.結論

NPOI 真的是很好用的 Library,建議有需求的人都可以去下載來試玩看看

本次範例 下載

參考資料:
NPOI Codeplex
在 Server 端存取 Excel 檔案的利器:NPOI Library
用 NPOI 操作EXCEL--插入圖片

15 則留言:

Unknown 提到...

產生出來的 excel 圖表挺有質感的,推啦~

坎尼 提到...

其實 NPOI 也可以用點小技巧來加入 Excel 的內建圖表,見下面連結 :D
http://www.cnblogs.com/atao/archive/2009/10/25/1589606.html

child 提到...

很棒的文章,推啦!
範例檔好像無法下載,不知版大是否可以重新上傳? 謝謝版大的教學和分享^^

坎尼 提到...

hi child,

已經重新補上連結

很抱歉拖這麼久 <(_ _)>

Unknown 提到...

能不能請教一下 :

不知有什麼辦法可以使用NPOI同時插入 2張以上的圖片至EXCEL內,我目前可以插入一張,但同時插入兩張以上,不是沒有出現圖,就是只會出現最後一張圖,前面的都不見了。以下是我的code,還請懂的大大幫幫忙,謝謝。


chart1.SaveImage(mschart, System.Windows.Forms.DataVisualization.Charting.ChartImageFormat.Png);
int pictureIndex = workbook.AddPicture(mschart.ToArray(), NPOI.SS.UserModel.PictureType.PNG);
HSSFPatriarch patriach = (HSSFPatriarch)sheet1.CreateDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor();
HSSFPicture pict = (HSSFPicture)patriach.CreatePicture(anchor, pictureIndex);
pict.Resize();

chart2.SaveImage(mschart, System.Windows.Forms.DataVisualization.Charting.ChartImageFormat.Png);
int pictureIndex1 = workbook.AddPicture(mschart.ToArray(), NPOI.SS.UserModel.PictureType.PNG);
HSSFPatriarch patriach1 = (HSSFPatriarch)sheet1.CreateDrawingPatriarch();
HSSFClientAnchor anchor1 = new HSSFClientAnchor();
HSSFPicture pict1 = (HSSFPicture)patriach.CreatePicture(anchor1, pictureIndex1);
pict1.Resize();


workbook.Write(ms);
FileStream file = new FileStream(@"C:\Documents and Settings\N990816\桌面\123.xls", FileMode.Create);
workbook.Write(file);
file.Close();
workbook = null;
ms.Close();

如果我把chart2移除,chart1插入就正常了,但就是不能同時兩個以上的圖都進excel

坎尼 提到...

Hi Derek,
坎尼和你用差不多的方式撰寫,是可以匯出兩張以上的圖片
最主要的差異在於:只宣告了一個 HSSFPatriarch 去進行 CreateDrawingPatriarch() 的動作

另外要用同一個 MemoryStream (你範例中的 mschart),在進行 SaveImage 之前應該要先清空(坎尼則是另外宣告一個 MemoryStream 來儲存圖片串流 :)

blackXD 提到...

坎尼您好,
我最近正好在用NPOI建Excel Chart,
剛好看到您這篇文章,
可惜範例檔已無法再下載...
可否麻煩提供範例檔呢?
先感謝您了!

坎尼 提到...

hi blackXD,

範例連結已經修正,不過由於那時是幾個範例一起寫,所以我就將整個專案檔打包囉~

要是檔案有問題請再告知 :)

blackXD 提到...

坎尼您好,
範例我已經下載了,謝謝您:)

我這邊還有個疑問...
就是NPOI是不是沒辦法用程式的方式操作Chart的部分?(我使用版本為1.2.3.0)
我這邊目前是參考"http://www.cnblogs.com/atao/archive/2009/10/25/1589606.html"
這個網址的做法(使用公式=>名稱管理員)
達到我要的效果(如網頁範例)

如果可以操作,
不知這邊可請坎尼教我嗎?

坎尼 提到...

hi blackXD,

本篇範例介紹的是把 Chart Control 製成的圖表,以圖片的方式匯出
而 NPOI 的方式是直接操作 Excel 的 Chart

你指的操作是在網頁上? 還是指匯出的檔案?

但基本上 NPOI 只專司建立/讀取 Excel 檔案,是不能用來操作 Chart Control 元件的

匿名 提到...

坎尼您好,
我有下載你的範例,
我的NPOI是1.2.3的版本
範例中HSSFSheet mySheet1= workbook.CreateSheet("冗員成本表");
這部分我自己一直無法弄出,後面一直出現錯誤
如圖:http://ppt.cc/kL4i
不知道是不是參考有少加 我看您的範例的參考NPOI加了很多
但我只加了一個NPOI...
圖:http://ppt.cc/0QSH
因為我目前只要把Chart控制項出現的結果匯出至Excel上
不知道哪個部分弄錯 或是哪個部分少加....

然後我想問問是否能夠匯出至Word呢?

以上 謝謝!

坎尼 提到...

Hi,
本篇範例是用NPOI 1.2.1,那時NPOI的作者是將功能切割成不同namespace,所以有許多dll
然而在NPOI 1.2.3裡已經將所有的namespace整合到NPOI底下,所以只需引入NPOI.dll沒錯

再來就是 NPOI 1.2.3 已修正部分方法的產出型別,比如:HSSFWorkbook.CreateSheet()
這部分要開發人員自己進行轉型

以樓上的圖來講,CreateSheet() 部分要改成
HSSFSheet TESTSheet1 = workbook.CreateSheet("圖檔") as HSSFSheet;

然後 CreateDrawingPatriarch() 部分要改成
HSSFPatriarch patriarch = TESTSheet1.CreateDrawingPatriarch() as HSSFPatriarch;

轉換到新版本的時候若有問題,先參考 Visual Studio 給的訊息吧,應該很容易懂~ (坎尼一換上新版本的NPOI就出現型別錯誤的訊息了)

坎尼 提到...

坎尼剛去查了一些資料,負責word用的HWPF類別目前仍非穩定版本,加上當時開發這塊的人員已經出走,所以現有版本的 NPOI 還是以 Excel 為主,尚未支援word的匯出,這部分可能要再去找其他第三方元件了

黑小胡 提到...

Dear 坎尼

我使用的NPOI是NPOI 1.2.5 這個版本,但是我再加入
int pictureIdx2 = workbook.AddPicture(msPic.ToArray(), HSSFWorkbook.PICTURE_TYPE_PNG);

這一段時出現了
錯誤 5 'NPOI.HSSF.UserModel.HSSFWorkbook' 不包含 'PICTURE_TYPE_PNG' 的定義

我開頭也是有
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;

也有加入NPOI.dll

但是沒有出現'PICTURE_TYPE_PNG' 的定義

可以請大大幫我解惑嗎?

坎尼 提到...

Hi 黑小胡,
這部份你需要去查 1.2.5 版的 PictureType 的列舉為何,直接下載 1.2.5 的 source code 去追蹤應該很快!

Google Spreadsheet 裡用規則運算式

最近因為工作關係,遇到要用 Google Form 及 Google Sheet 所以研究了 Google Sheet 裡的一些 function 怎麼用 首先,分享一下如何在 Google Sheet 裡用規則運算 :D