蛙蛙推荐:利用OWC创建图表的完美解决方案
摘要:因为公司一个项目需要动态生成图表,所以我就想到了OWC,一般我们都是把数据传送到客户端,然后利用客户浏览器的OWC Activex控件来显示图表,但是这样的缺点是需要在客户端部署这个dll。我这里演示的是在服务段生成图表图片,然后输出显示到浏览器后自动删除临时图片。我在对OWC构建报表的代码里做了很多详细的注释,几乎OWC常用的功能都涉及到了,也许能帮助你更多的了解一下OWC。示例中用的nwind.mdb数据库,如过你装了office或者vb6的话,在它们的安装目录里可以找到。这里有个技巧就是怎么用客户端的JS执行服务段的方法。我现在正在把这个示例移植到我正在开发的一个CRM系统上。
代码:
<%
'禁止浏览器缓存
Response.Buffer=true
Response.Expires = 0
Response.ExpiresAbsolute = NewDate = DateAdd("d", 1, now())
Response.AddHeader "pragma","no-cache"
Response.AddHeader "cache-control","private"
Response.CacheControl="no-cache"
'这是创建图表并生成临时图片的过程
sub CreateOwcChart
'定义图表控件和数据源控件
Dim ChartSpace1,DataSourceControl1
Set ChartSpace1 = server.CreateObject("OWC.Chart")
Set DataSourceControl1 = server.CreateObject("OWC.DataSourceControl")
'为图表控件设置数据源控件
Dim rsd, chConstants
Set chConstants = ChartSpace1.Constants '创建一个允许脚本用户使用命名常量的对象
DataSourceControl1.ConnectionString = _
"DRIVER={Microsoft Access Driver (*.mdb)}; " & _
"DBQ="&server.mappath("nwind.mdb")
Set rsd = DataSourceControl1.RecordsetDefs.AddNew( _
"Select * from [Category Sales for 1995]", 3)
With ChartSpace1
.Clear '删除图表工作区的所有图表,并将所有格式恢复为默认值。
.Refresh '刷新指定对象(重载源数据或重绘对象)。
.DataSource = DataSourceControl1 '设置图表控件的数据源控件
.DataMember = rsd.Name '指定控件将从数据源请求获取的记录集名称
End With
'因为图表控件要显示两个图表,所以我们安排这两个图表水平排列
ChartSpace1.ChartLayout = chConstants.chChartLayoutHorizontal
'根据查询创建新的条形图
Dim oBarChart
Set oBarChart = ChartSpace1.Charts.Add '添加一个图表
With oBarChart
'利用OWC常量指定新添加的图表为条形图,也可以选择ChartChartTypeEnum的其它枚举
.Type = chConstants.chChartTypeBarClustered
'SetData方法第一个参数ChartDimensionsEnum 常量,指定设置的数据维。
'第二个参数ChartSpecialDataSourcesEnum 常量,指定数据源类型
'最后一个参数指定提取数据源的数据范围,是可选的
.SetData chConstants.chDimCategories, 0, 0 '设置用作分类的值
.SetData chConstants.chDimValues, 0, 1 '设置绘制图表的值
'设置底部坐标轴的一些信息
With .Axes(chConstants.chAxisPositionBottom)
.NumberFormat = "0" '设置坐标轴刻度的数字格式为没有小数点的整数
.MajorUnit = 25000 '设置坐标轴的主要单位,就相当于间隔的大小
.HasMajorGridlines = False '指定这个坐标轴没有网格线,因为是x轴嘛
End With
'改变条形块儿的颜色
'SeriesCollection返回的是图表控件上所有图表的集合,索引0就是指定
'第一个图表,就是刚刚新加的柱形图,interior表示图表的内部
.SeriesCollection(0).Interior.Color = RGB(150, 0, 150)
'改变绘图区域的背景色
'PlotArea返回表示图表的绘图区(绘制图表数据的区域)。
.PlotArea.Interior.Color = RGB(240, 240, 10)
End With
'根据查询创建一个新的爆炸饼图
Dim oPieChart
Set oPieChart = ChartSpace1.Charts.Add
With oPieChart
.Type = chConstants.chChartTypePie '指定新添加的图表为饼图
.SetData chConstants.chDimCategories, 0, 0 '先设置类别数据域
.SetData chConstants.chDimValues, 0, 1 '再设置数值数据域
'设置指定饼图或圆环图扇面的分离程度值,使用该属性可突出特定扇面
.SeriesCollection(0).Explosion = 20
'创建一个图例并把它放在图表的下部分
.HasLegend = True '指定饼形图有图例
.Legend.Position = chConstants.chLegendPositionBottom '指定图例的位置为图表底部
'给图表添加标题
.HasTitle = True '指定图表有标题
.Title.Caption = "1995年的销售记录" '指定标题的标签
.Title.Font.Bold = True '粗体
.Title.Font.Size = 11 '字体大小为11
'指定这个饼形图占据整个图表工作区的50%,
'若要使该属性生效,图表工作区中必须有多个图表
.WidthRatio = 50
'显示百分比标签
'DataLabelsCollection表示图表的数据标志,这里就是显示百分比的标签
With .SeriesCollection(0).DataLabelsCollection.Add
.HasValue = False '因为并行图没有Y轴数据,所以把这个值设置成False
.HasPercentage = True '指定数据标志当前显示其百分比值,该属性只适用于饼图、圆环图和堆积图
.Font.Size = 8 '设置数据标志字体为8象素
.Interior.Color = RGB(255, 255, 255) '数据标志标签背景色为白色
End With
End With
'生成临时图片,并销毁OWC对象,不知道OWC会不会自动启用对象池
ChartSpace1.ExportPicture Server.MapPath(m_sFilePath), "gif",800,300
Set ChartSpace1 = nothing
Set DataSourceControl1= nothing
End Sub
'这是删除临时文件的过程
sub delimg(imgname)
Set fsoTemp = CreateObject("Scripting.FileSystemObject")
fsoTemp.DeleteFile Server.MapPath(imgname), True
set fsoTemp = nothing
end sub
Function GetGuid
Dim TypeLib,guid
Set TypeLib = CreateObject("Scriptlet.TypeLib")
guid = TypeLib.Guid
GetGuid = Left(guid,(Len(guid) - 2))
End Function
'定义临时图片名称
Dim m_sFilePath
m_sFilePath = GetGuid & ".gif"
'如果传递的delimg的查询字符串为true的话
'就执行delimg过程来删除临时图片
'因为当客户端的图片加载完后会利用xmlhttp
'发送一个delimg=true的查询字符串上来,这时候可以删除临时图片了
if request("delimg") <>"" then
delimg(trim(request("delimg")))
else
CreateOwcChart
end if
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> owc图表 </TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
function delimg(imgsrc)
{
imgsrc = imgsrc.replace(/(.*)({.*})/g,"$2")
var Http = new ActiveXObject("Microsoft.XMLHTTP");
var url = window.location + "?delimg=" + imgsrc;
Http.open("GET",url,false);
Http.send()
}
//-->
</SCRIPT>
</HEAD>
<BODY>
<img src="<%= m_sFilePath %>" onload="delimg(this.src)">
</BODY>
</HTML>
小结:关于更多的OWC的介绍就不写了,如果安装了office的话,搜索一下office的目录会找到OWC手册的,其实网上流行的好多OWC显示的图表的方案,有的是在一个目录里生成临时图片,然后在session_end里删除这些图片,但是session_end触发的时间不确定,也不可靠。而有的是生成临时图片后把图片加载到一个内存流里,然后把流以gif方式输出,随后删除临时图片。总之都是为了及时删除临时图片,我这个用的是xmlhttp执行服务器方法来达到同样目的的,代码很少,而且也很方便。
代码下载:
https://files.cnblogs.com/onlytiancai/owcchart.rar
其它说明:
如果你禁止了FSO,注册FSO组件的方法如下
regsvr32.exe scrrun.dll
另外注意一下OWC组件的版本,一般在C:\WINDOWS\system32目录下有个MSOWC.DLL,它可以单独部署。
XmlHttp异步获取网站数据的例子
http://www.52z.com/info/ArticleView/2004-11-7/Article_View_35764.Htm
利用OWC服务器端组件动态生成图表
http://www.daima.com.cn/Info/4/Info26297/
客户端回调
http://gigabyte.cnblogs.com/archive/2004/09/07/40633.aspx
如何查找 Office Web 组件 (OWC) 编程文档和示例
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;319793
HOW TO:在 Visual Basic .NET 中处理 Windows 窗体中的 Office XP 电子表格组件的事件
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;319342
HOW TO:在 Visual C# .NET 中处理 Windows 窗体中 Office XP 电子表格组件的事件
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;319341
HOW TO:在 Visual Studio .NET 中处理 Office 2003 Web 组件的事件
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;823982
Office 2003 安装程序删除了 Office 2000 Web 组件
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;831590
如何在 Office 2003 程序中部署 Office 2003 Web Components
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;828950
Microsoft Office 2000 Web 组件基础
http://www.microsoft.com/china/MSDN/library/archives/library/techart/msowcBasics.asp
INFO:使用 Visual Studio .NET 开发 Microsoft Office 解决方案
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;311452
在 Access 2002 中进行 Web 开发
http://www.microsoft.com/china/MSDN/library/archives/library/DNAcc2k2/html/odc_adap.asp
在 Microsoft Access 2002 中对数据透视表进行编程
http://www.microsoft.com/china/msdn/archives/library/dnacc2k2/html/odc_acprogpvt.asp
为了简单起见,我用VBS和ASP来演示OWC对象的一些操作,在.NET下面这些属性是不变的,只要引用一下MSOWC.DLL就可以操作了,而且有智能感知可用.文章把重点放在演示思路上了.
我又改进了一下代码,生成的图片是用guid做名称的,保证在并发请求的时候不会误删别人正在查看的图片,而且还加了一些关于OWC编程的链接。