一、概述?
在開發(fā)應(yīng)用程序時(shí),經(jīng)常會(huì)遇到必須提供交互式圖表的情況。例如,你可能在開發(fā)一個(gè)管理銷售和產(chǎn)品數(shù)據(jù)的應(yīng)用程序,數(shù)據(jù)保存在SQL?Server數(shù)據(jù)庫上,應(yīng)用程序允許用戶添加數(shù)據(jù)、更新現(xiàn)有數(shù)據(jù),但除了這些功能之外,客戶還要求應(yīng)用程序能夠用餅圖、柱形圖或XY散點(diǎn)圖的形式直觀地描述數(shù)據(jù)。?
在Windows桌面應(yīng)用程序中,這類要求從來不成為問題,可供選用的圖形庫和繪圖組件實(shí)在太多了。但對(duì)于Web應(yīng)用程序,問題就變得復(fù)雜多了。要在Web應(yīng)用中繪制圖表,可供選擇的辦法包括:?
■?客戶端:?
利用各種ActiveX組件,Web瀏覽器內(nèi)完全有可能達(dá)到“豐富”Windows客戶程序那樣的功能。缺點(diǎn)是客戶端的設(shè)置復(fù)雜化,要求發(fā)布客戶端軟件,通常按照每客戶端的方式計(jì)算許可證費(fèi)用。另外,非MS?Windows/IE的客戶端一般難以運(yùn)行。?
■?服務(wù)器端:?
利用Web服務(wù)器上運(yùn)行的服務(wù)器端代碼,動(dòng)態(tài)地生成圖表,然后以GIF或JPG圖形的形式發(fā)送給客戶端。這種辦法的優(yōu)點(diǎn)是,客戶端只需要一個(gè)標(biāo)準(zhǔn)的瀏覽器。與客戶端技術(shù)相比的缺點(diǎn)是,圖形的交互能力差(除非向服務(wù)器提交新的請(qǐng)求,否則就不能縮放、滾動(dòng))。許多地圖網(wǎng)站(例如Mapquest.com)大量地運(yùn)用了這一技術(shù)。注意,地圖圖形不是保存在Web服務(wù)器上,而是用戶發(fā)出一個(gè)請(qǐng)求時(shí)動(dòng)態(tài)從地圖數(shù)據(jù)庫生成。?
本文主要討論如何利用服務(wù)器端的圖表繪制技術(shù)在ASP.NET?Web頁面中提供圖形功能
二、設(shè)置圖表引擎?
如果要在ASP.NET應(yīng)用程序中繪制圖表,必須要有一個(gè)合適的圖表引擎。ASP.NET有一個(gè)內(nèi)建的圖形工具庫,即System.Drawing名稱空間的GDI+,可以用來創(chuàng)建簡(jiǎn)單的餅圖、柱形圖、折線圖等,不過它屬于低級(jí)的API,算不上繪制圖表的引擎,特別是不適合繪制復(fù)雜的圖表。?
???本文要討論的主角是OWC,即Office?Web?Components,或者“Office?Web組件”。按照微軟的定義,OWC是一種“將類似Office的功能擴(kuò)展到Web的微軟技術(shù)”。它可以在客戶端使用,例如我們將Excel工作表保存為Web頁面時(shí)就要用到,利用它可以方便地將交互式電子表格和圖表發(fā)布到Web頁面。同時(shí),OWC也是一個(gè)優(yōu)秀的服務(wù)器端圖表引擎,具有與MS?Excel同樣強(qiáng)大的圖表繪制能力。?
三、OWC的許可證問題?
如果你曾經(jīng)用過版本較早的OWC,可能已經(jīng)遇到過微軟的許可證問題。以前這個(gè)問題相當(dāng)令人煩惱,微軟不僅要求服務(wù)器上必須有Office許可證,而且每一臺(tái)客戶PC上也同樣要有。?
實(shí)際上,這相當(dāng)于將OWC的用途局限到了Intranet之內(nèi),只有Intranet之內(nèi)才可以保證客戶PC上都安裝了Office許可證。不過現(xiàn)在微軟的態(tài)度有所放緩——服務(wù)器上仍舊要安裝Office許可證,但只要圖表是“非交互式”用途,例如本文的服務(wù)器端圖表繪制,客戶端就不必再裝Office許可證。實(shí)際上,就連服務(wù)器端也不必安裝完整的Office許可證,Excel?2002或FrontPage?2002的許可證就已足夠,從而使OWC變成了價(jià)廉物美的服務(wù)器端圖表引擎。?
那么,在服務(wù)器上安裝MS?Office?不,沒有必要。雖然從許可證條件看,OWC應(yīng)該是Office的一部分,但從技術(shù)上說,OWC是一個(gè)獨(dú)立的產(chǎn)品。Web服務(wù)器上只需安裝OWC軟件包,不必安裝整個(gè)Office。?
OWC首次出現(xiàn)于Office?2000,即OWC?9.0。在Office?XP中,OWC的編程模式已作了修改,這使得OWC?XP(也就是OWC?10)不能與OWC?9.0完全兼容。OWC?10要求在ASP.NET環(huán)境中運(yùn)行,所以O(shè)WC?10軟件包必須安裝到ASP.NET服務(wù)器上。?
接下來,很自然的一個(gè)問題是:哪里可以下載OWC?10軟件包?令人驚奇的是,它可以從微軟的網(wǎng)站免費(fèi)下載,地址是http://office.microsoft.com/downloads/2002/owc10.aspx,
(中文地址:http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=982B0359-0A86-4FB2-A7EE-5F3A499515DD 網(wǎng)際浪子注)但要注意的是,Web服務(wù)器上必須安裝了某種Office?2002的許可證才能合法地使用OWC?10。?
四、OWC的運(yùn)行機(jī)制?
OWC是一組COM(ActiveX)控件的集合,涵蓋電子表格、圖表、數(shù)據(jù)透視表等功能。它經(jīng)常被當(dāng)作客戶端技術(shù)使用,這時(shí)COM控件就安裝在客戶端PC上。如果在服務(wù)器端使用,人們主要感興趣的是它的圖表繪制功能。?
有了OWC,我們可以在ASP.NET?Web服務(wù)器上動(dòng)態(tài)創(chuàng)建一個(gè)圖表,然后將圖表以GIF圖形的形式發(fā)送到客戶端。客戶端看到的僅僅是一個(gè)普通的圖形文件,但在“背后”,圖形文件實(shí)際上是由服務(wù)器上ASP.NET回應(yīng)客戶請(qǐng)求時(shí)動(dòng)態(tài)生成的。因此,這種技術(shù)對(duì)客戶端沒有特殊的要求,只要能夠顯示GIF圖形就可以了,即使Netscape和Opera也不存在任何問題。?
既然如此,為什么在ASP.NET開發(fā)領(lǐng)域中,OWC這一優(yōu)秀的微軟技術(shù)尚未被廣泛采用呢?微軟根本不為OWC作市場(chǎng)宣傳,再加上令人迷惑的許可證問題,當(dāng)然令許多開發(fā)者望而卻步。也許微軟認(rèn)為該產(chǎn)品還沒有完全成熟,即將到來的Office?2003將會(huì)帶來OWC?11,它的編程模式還會(huì)有所改變。另外,還有一種可能是微軟擔(dān)心OWC技術(shù)的廣泛采用會(huì)影響Office的銷售。?
再者,關(guān)于OWC的編程實(shí)例很少。微軟知識(shí)庫有幾個(gè)客戶端的例子和“傳統(tǒng)”ASP的服務(wù)器端例子,但找不到在ASP.NET環(huán)境中使用OWC?10的例子。OWC的新聞組,microsoft.public.office.developer.web.components,主要討論的也是客戶端的應(yīng)用。如果你要在ASP.NET環(huán)境中使用OWC?10,主要還是靠自己摸索。正是因?yàn)檫@些原因,所以本文從相當(dāng)廣泛的角度探討了該技術(shù)的實(shí)際應(yīng)用。?
五、在Web服務(wù)器上安裝OWC?10?
要想在ASP.NET?Web服務(wù)器上用OWC繪制圖表,首先應(yīng)當(dāng)安裝必要的軟件和修改一些配置。?
第一,Web服務(wù)器上當(dāng)然應(yīng)該有ASP.NET運(yùn)行環(huán)境。除了.NET?Framework?Redistributable,還要有GACUTIL程序(屬于.NET框架SDK)來配置OWC控件,也就是說,還要安裝.NET?Framework?SDK工具。如果把.NET?Framework?1.1?Redistributable和SDK安裝到了默認(rèn)目錄,PATH環(huán)境變量的內(nèi)容應(yīng)當(dāng)包含:C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322;C:\Program?Files\Microsoft.NET\SDK\v1.1\Bin。?
接下來再在Web服務(wù)器上安裝OWC?10。OWC可以從微軟免費(fèi)下載,安裝時(shí)只要采用所有默認(rèn)選項(xiàng)即可。?
由于OWC?10是一種COM技術(shù),為了讓.NET代碼使用OWC?10組件,還必須安裝Office?XP的Primary?Interop?Assembly(PIA),PIA可以從微軟網(wǎng)站下載(http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnoxpta/html/odc_oxppias.asp)。
(網(wǎng)際浪子發(fā)現(xiàn)的地址是:http://www.microsoft.com/downloads/details.aspx?FamilyId=C41BD61E-3060-4F71-A6B4-01FEBA508E52&displaylang=en)
下載得到的OXPPIA.exe是一個(gè)壓縮文件,現(xiàn)在把它解壓縮到服務(wù)器上的一個(gè)目錄,假設(shè)是C:\oxppia,然后啟動(dòng)一個(gè)命令窗口(注意,確保PATH環(huán)境變量已正確設(shè)置[網(wǎng)際浪子注:可以用我作的SETPATH.BAT運(yùn)行一下]),轉(zhuǎn)到c:\oxppia目錄,運(yùn)行REGISTER.bat。?
這個(gè)命令把Office?XP?PIA導(dǎo)入到全局程序集緩沖區(qū),修改注冊(cè)表設(shè)置。注意觀察REGISTER.bat命令的輸出,確信GACUTIL命令確實(shí)在運(yùn)行。如果PATH環(huán)境變量設(shè)置有誤,PIA不可能正確導(dǎo)入。README文檔說應(yīng)當(dāng)用VS.NET命令行環(huán)境,但Web服務(wù)器上可能沒有安裝VS.NET,這時(shí)就要手工修改PATH環(huán)境變量了(效果一樣)。?
最后,還要把下面這行代碼加入Web服務(wù)器的machine.config文件的<assemblies>節(jié),對(duì)于.NET?Framework?1.1,machine.config文件可以在C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\CONFIG目錄下找到:?
<add?assembly="Microsoft.Office.Interop.OWC,?Version=10.0.4504.0,?
?????Culture=neutral,?PublicKeyToken=31bf3856ad364e35"/>
?
浪子注明:如果發(fā)生不能編譯的錯(cuò)誤,可能要再次運(yùn)行注冊(cè)步驟!我這里這樣,大家如果不一樣,可以自己試試。
六、OWC編程模式?
???要生成圖表的數(shù)據(jù)稱為數(shù)據(jù)原,Chart?Component組件支持的數(shù)據(jù)源有:實(shí)現(xiàn)IDataSource接口的任何數(shù)據(jù)源;ADO?Recordset對(duì)象;XML文件;數(shù)組或者一定格式的文本字符串。在ASP中,我們可以用ADO?Recordset對(duì)象;在.NET的ADO.NET中,由于ADO.NET沒有實(shí)現(xiàn)IDataSource,.NET也沒有提供ADO.NET?DataSet對(duì)象向ADO?Recordset對(duì)象的直接轉(zhuǎn)換,如果你有一個(gè)?DataSet對(duì)象,你要么轉(zhuǎn)換成XML文件,要么生成特殊格式的字符串才可以使用。下面就是本例子的結(jié)果:
[浪子注明:如果出錯(cuò),可能是文件夾權(quán)限的問題,我的就是,要將虛擬目錄的everyone的全部權(quán)限加上!]
下面是實(shí)現(xiàn)這種功能的VB.NET版本的ASP.NET例子與代碼:
OWC.aspx:
<%@?Page?Language="vb"?AutoEventWireup="false"?Codebehind="OWC.aspx.vb"?Inherits="aspxWeb.OWC"%>
<!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.0?Transitional//EN"?>
<HTML>
??<HEAD>
????<title>WebForm1</title>
????<meta?name="GENERATOR"?Content="Microsoft?Visual?Studio?7.0">
????<meta?name="CODE_LANGUAGE"?Content="C#">
????<meta?name="vs_defaultClientScript"?content="javascript">
????<meta?name="vs_targetSchema"?content="http://schemas.microsoft.com/intellisense/ie5";>
??</HEAD>
??<body?MS_POSITIONING="GridLayout">
????<form?id="Form1"?method="post"?runat="server">
??????<asp:placeholder?id="ChartHolder"?runat="server"></asp:placeholder>
????</form>
??</body>
</HTML>
OWC.aspx.vb:
Imports?System
Imports?OWC
Imports?System.Web.UI
Public?Class?OWC
??Inherits?System.Web.UI.Page
??Protected?WithEvents?ChartHolder?As?System.Web.UI.WebControls.PlaceHolder
#Region?"?Web?窗體設(shè)計(jì)器生成的代碼?"
??'該調(diào)用是?Web?窗體設(shè)計(jì)器所必需的。
??<System.Diagnostics.DebuggerStepThrough()>?Private?Sub?InitializeComponent()
??End?Sub
??Private?Sub?Page_Init(ByVal?sender?As?System.Object,?ByVal?e?As?System.EventArgs)?Handles?MyBase.Init
????'CODEGEN:?此方法調(diào)用是?Web?窗體設(shè)計(jì)器所必需的
????'不要使用代碼編輯器修改它。
????InitializeComponent()
??End?Sub
#End?Region
??Private?Sub?Page_Load(ByVal?sender?As?System.Object,?ByVal?e?As?System.EventArgs)?Handles?MyBase.Load
????'在此處放置初始化頁的用戶代碼
????'創(chuàng)建ChartSpace對(duì)象來放置圖表
????Dim?objCSpace?As?ChartSpace?=?New?ChartSpaceClass()
????'在ChartSpace對(duì)象中添加圖表,Add方法返回chart對(duì)象
????Dim?objChart?As?WCChart?=?objCSpace.Charts.Add(0)
????'指定圖表的類型。類型由OWC.ChartChartTypeEnum枚舉值得到
????objChart.Type?=?ChartChartTypeEnum.chChartTypeColumnClustered
????'指定圖表是否需要圖例
????objChart.HasLegend?=?True
????'給定標(biāo)題
????objChart.HasTitle?=?True
????objChart.Title.Caption?=?"1-6說數(shù)據(jù)分布圖"
????'給定x,y軸的圖示說明
????objChart.Axes(0).HasTitle?=?True
????objChart.Axes(0).Title.Caption?=?"Y?軸?:?數(shù)量"
????objChart.Axes(1).HasTitle?=?True
????objChart.Axes(1).Title.Caption?=?"X?軸:?月份"
????'計(jì)算數(shù)據(jù)
????'*categories?和?values?可以用tab分割的字符串來表示*
????Dim?strSeriesName?As?String?=?"圖例?1"
????Dim?strCategory?As?String?=?"1"?+?ControlChars.Tab?+?"2"?+?ControlChars.Tab?_
?+?"3"?+?ControlChars.Tab?+?"4"?+?ControlChars.Tab?+?"5"?+?ControlChars.Tab?_
?+?"6"?+?ControlChars.Tab
????Dim?strvalue?As?String?=?"9"?+?ControlChars.Tab?+?"8"?+?ControlChars.Tab?_
?+?"4"?+?ControlChars.Tab?+?"10"?+?ControlChars.Tab?+?"12"?+?ControlChars.Tab?_
?+?"6"?+?ControlChars.Tab
????'添加一個(gè)series
????objChart.SeriesCollection.Add(0)
????'給定series的名字
????objChart.SeriesCollection(0).SetData(ChartDimensionsEnum.chDimSeriesNames,_
??ChartSpecialDataSourcesEnum.chDataLiteral,?strSeriesName)
????'給定分類
????objChart.SeriesCollection(0).SetData(ChartDimensionsEnum.chDimCategories,_
??ChartSpecialDataSourcesEnum.chDataLiteral,?strCategory)
????'給定值
????objChart.SeriesCollection(0).SetData(ChartDimensionsEnum.chDimvalues,_
??ChartSpecialDataSourcesEnum.chDataLiteral,?strvalue)
????'輸出成GIF文件.
????Dim?strAbsolutePath?As?String?=?(Server.MapPath("."))?+?"\Images\test.gif"
????objCSpace.ExportPicture(strAbsolutePath,?"GIF",?600,?350)
????'創(chuàng)建GIF文件的相對(duì)路徑.
????Dim?strRelativePath?As?String?=?"Images/test.gif"
????'把圖片添加到placeholder.
????Dim?strImageTag?As?String?=?"<IMG?SRC='890_files/"?+?strrelativepath?+?"'/>"
????ChartHolder.Controls.Add(New?LiteralControl(strImageTag))
??End?Sub
??
End?Class
下面是C#版本的OWC.asp.cs
using?System;
using?System.Collections;
using?System.ComponentModel;
using?System.Data;
using?System.Drawing;
using?System.Web;
using?System.Web.SessionState;
using?System.Web.UI;
using?System.Web.UI.WebControls;
using?System.Web.UI.HtmlControls;
using?Microsoft.Office.Interop;?
namespace?Microsoft.Office.Interop.OWC使用指南
{
?///?<summary>
?///?WebForm1?的摘要說明。
?///?</summary>
?public?class?WebForm1?:?System.Web.UI.Page
?{
??protected?System.Web.UI.WebControls.PlaceHolder?ChartHolder;
??private?Microsoft.Office.Interop.OWC.ChartChartTypeEnum?GetChartType(int?typeIndex)
??{
???int?i;
???Microsoft.Office.Interop.OWC.ChartChartTypeEnum?myTE;
???i=typeIndex;
???
???switch(i)
???{
????case?0:
?????myTE=Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypeColumnClustered;
?????return?myTE;
????case?1:
?????myTE=Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypePie;
?????return?myTE;
????case?2:
?????myTE=Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypeSmoothLine;
?????return?myTE;
????case?3:
?????myTE=Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypeArea;
?????return?myTE;
????case?4:
?????myTE=Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypeRadarLine;
?????return?myTE;
????default:
?????myTE=Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypeColumnClustered;
?????return?myTE;
???}
??}
??private?void?Page_Load(object?sender,?System.EventArgs?e)
??{
???//?在此處放置用戶代碼以初始化頁面
???//創(chuàng)建ChartSpace對(duì)象來放置圖表
???Microsoft.Office.Interop.OWC.ChartSpace?objCSpace?=?new?Microsoft.Office.Interop.OWC.ChartSpaceClass();?
???//在ChartSpace對(duì)象中添加圖表,Add方法返回chart對(duì)象
???
???Microsoft.Office.Interop.OWC.ChChart???objChart?=?objCSpace.Charts.Add?(0);?
???//指定圖表的類型。類型由Microsoft.Office.Interop.OWC.ChartChartTypeEnum枚舉值得到
???//objChart.Type?=?Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypeColumnClustered;
???//上面的是畫棒圖的方法
???//objChart.Type?=?Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypeSmoothLine;
???//上面的是畫平滑曲線的方法
???objChart.Type?=Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypeRadarLine;
???//上面的是畫雷達(dá)線的方法
???//objChart.Type?=Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypeArea;
???//上面的是畫區(qū)域線的方法
???//objChart.Type?=Microsoft.Office.Interop.OWC.ChartChartTypeEnum.chChartTypePie;
???//上面的是畫餅圖的方法,但是要關(guān)掉一些參數(shù),比如
???/*//objChart.Axes[0].HasTitle?=?true;
???//objChart.Axes[0].Title.Caption?=?"Y?:?數(shù)量";
???//objChart.Axes[1].HasTitle?=?true;
???//objChart.Axes[1].Title.Caption?=?"X?:?月份";
????*?*/
???//指定圖表是否需要圖例
???objChart.HasLegend?=?true;
???//給定標(biāo)題
???objChart.HasTitle?=?true;
???objChart.Title.Caption=?"上半年分布圖";
???//給定x,y軸的圖示說明
???objChart.Axes[0].HasTitle?=?true;
???objChart.Axes[0].Title.Caption?=?"Y?:?數(shù)量";
???objChart.Axes[1].HasTitle?=?true;
???objChart.Axes[1].Title.Caption?=?"X?:?月份";
???//計(jì)算數(shù)據(jù)
???/*categories?和?values?可以用tab分割的字符串來表示*/
???string?strSeriesName?=?"圖例?1";
???string?strCategory?=?"1"?+?'\t'?+?"2"?+?'\t'?+?"3"?+?'\t'+"4"?+?'\t'?+?"5"?+?'\t'?+?"6"?+?'\t';
???string?strvalue?=?"9"?+?'\t'?+?"8"?+?'\t'?+?"4"?+?'\t'+"10"?+?'\t'?+?"12"?+?'\t'?+?"6"?+?'\t';
???//添加一個(gè)series
???objChart.SeriesCollection.Add(0);
???//給定series的名字
???objChart.SeriesCollection[0].SetData?(Microsoft.Office.Interop.OWC.ChartDimensionsEnum.chDimSeriesNames,
????+?(int)Microsoft.Office.Interop.OWC.ChartSpecialDataSourcesEnum.chDataLiteral,?strSeriesName);
???//給定分類
???objChart.SeriesCollection[0].SetData?(Microsoft.Office.Interop.OWC.ChartDimensionsEnum.chDimCategories,
????+?(int)Microsoft.Office.Interop.OWC.ChartSpecialDataSourcesEnum.chDataLiteral,?strCategory);
??????
???//給定值
???objChart.SeriesCollection[0].SetData
????(Microsoft.Office.Interop.OWC.ChartDimensionsEnum.chDimvalues,
????(int)Microsoft.Office.Interop.OWC.ChartSpecialDataSourcesEnum.chDataLiteral,?strvalue);?
???//輸出成GIF文件.
???string?strAbsolutePath?=?(Server.MapPath("."))?+?"\\test.gif";
???objCSpace.ExportPicture(strAbsolutePath,?"GIF",?600,?350);
???//創(chuàng)建GIF文件的相對(duì)路徑.
???string?strRelativePath?=?"./test.gif";
???//把圖片添加到placeholder.
???string?strImageTag?=?"<IMG?SRC='"?+?strRelativePath?+?"'/>";
???ChartHolder.Controls.Add(new?LiteralControl(strImageTag));
??}
??#region?Web?Form?Designer?generated?code
??override?protected?void?OnInit(EventArgs?e)
??{
???//
???//?CODEGEN:該調(diào)用是?ASP.NET?Web?窗體設(shè)計(jì)器所必需的。
???//
???InitializeComponent();
???base.OnInit(e);
??}
?
??///?<summary>
??///?設(shè)計(jì)器支持所需的方法?-?不要使用代碼編輯器修改
??///?此方法的內(nèi)容。
??///?</summary>
??private?void?InitializeComponent()
??{????
???this.Load?+=?new?System.EventHandler(this.Page_Load);
??}
??#endregion
?}
}
如果用ADO.NET的DataSet對(duì)象,可以生成以TAB分割的字符串:
strvalue?+=?(nodes.Item(j).ChildNodes.Item(0).InnerText?+?'\t');
strCategory?+=?(nodes.Item(j).ChildNodes.Item(1).InnerText?+?'\t');
Microsoft.Office.Interop名稱空間指向Office?XP?PIA,PIA應(yīng)該事先安裝到Web服務(wù)器上。編譯源代碼時(shí)要用到Office?XP?PIA?OWC的DLL文件。如果用VS.NET編譯,只要加入一個(gè)Microsoft.Office.Interop.Owc.dll文件的引用即可(位于解開Office?XP?PIA文件的目錄),如果從命令行編譯,必須按照下列方式使用/r:參數(shù):?
vbc?/t:library?/out:bin\getchart.dll?/r:System.dll?/r:System.Web.dll?
???/r:System.Data.dll?
???/r:C:\oxppia\Microsoft.Office.Interop.Owc.dll?getchart.aspx.vb
?
上面的代碼有許多值得一提的地方。首先,我們假定數(shù)據(jù)源位于MSSQL數(shù)據(jù)庫OWCDEMO,該數(shù)據(jù)庫有一個(gè)OWCDATA表,OWCDATA表有兩個(gè)數(shù)值列,分別是X和Y。getchart.aspx的目標(biāo)就是從數(shù)據(jù)庫獲取記錄,然后用散點(diǎn)圖(XY)描述這些數(shù)據(jù)。?
OWC圖表的數(shù)據(jù)點(diǎn)無法直接從ASP.NET的DataSet獲取,因此,我們首先要把數(shù)據(jù)庫的數(shù)據(jù)裝入數(shù)組,然后用數(shù)組的數(shù)據(jù)填寫OWC圖表的數(shù)據(jù)點(diǎn)。如果要對(duì)本例作改進(jìn)的話,最好開發(fā)一個(gè)ASP.NET服務(wù)器控件,它能夠從抽象的數(shù)據(jù)源(包括DataSet對(duì)象、XML文件或數(shù)組)獲取數(shù)據(jù)并生成XY散點(diǎn)圖。?
DataReader要比DataSet快速、高效,不過,我們首先要確定數(shù)據(jù)庫中的記錄數(shù)量,根據(jù)記錄數(shù)量來調(diào)整數(shù)組的大小。為此,我們先用一個(gè)SQL?Select?count(*)查詢獲取記錄數(shù)量,然后定義數(shù)組大小,最后用第二個(gè)SQL?SELECT查詢獲取數(shù)據(jù)庫記錄。?
如果我們要讓散點(diǎn)圖的各個(gè)點(diǎn)用折線連接起來,記錄必須依照X軸排序,這通過一個(gè)SQL?ORDER?BY子句實(shí)現(xiàn)。?
OWC的圖表建立在“繪圖空間”上。一個(gè)繪圖空間可以包含一個(gè)或多個(gè)圖表,每一個(gè)圖表可以有一個(gè)或多個(gè)數(shù)據(jù)系列。在生成OWC圖表時(shí),我們首先創(chuàng)建一個(gè)繪圖空間,將一個(gè)圖表加入到繪圖空間,設(shè)置圖表的類型,添加數(shù)據(jù)系列,最后用數(shù)組的數(shù)據(jù)填寫數(shù)據(jù)系列。?
另外,我們還可以設(shè)置(可選)各種布局參數(shù),例如顏色、坐標(biāo)標(biāo)題、圖表標(biāo)題、圖例,等等。OWC提供了數(shù)百個(gè)布局參數(shù),我們可以隨心所欲地調(diào)整圖表。當(dāng)然,對(duì)于不同的圖表類型,繪圖模式也略有不同,例如,餅圖和散點(diǎn)圖的參數(shù)設(shè)置方法是不同的。在OWC?10安裝包中有OWC幫助文件,里面詳細(xì)說明了OWC圖表模型。?
最后,Response.BinaryWrite參數(shù)指定了要輸出的圖形類型(GIF),以及圖形的寬度、高度(以像素為單位)。在這里,我們可以根據(jù)需要縮放從OWC圖表生成的圖形。?
對(duì)了,忘了說代碼的位置了,在FTP里的論壇問題解答里,有一個(gè)OWC使用指南的目錄,下面有使用OWC的全部文件和源碼。