摘要
本文介绍一个免费的、完整的、very easy 的在Web页和RDLC报表中呈现、打印条码的解决方案。
效果
笔者最近遇到了一个B/S结构的项目,需要在报表中打印条码。效果如下
恰巧,笔者不久前在网上找到了一个免费的条码控件,请见下图
这是由昆明科本软件有限公司推出的一款十分不错的条码控件,支持十余种国际通用的条码格式,生成的图片的大小和样式可调。可以由此下载
科本条形码主页,现在已经升级到了1.5版,附带示例工程。(我使用的时候还是1.0版,包括本篇文章的示例代码所使用的也是1.0版控件)。
可惜这个控件只支持Windows程序。我想在Web程序中使用,能办到么?答案是肯定的,因为这个控件非常体贴地提供了一个 MakeImage() 函数,直接使用这个函数就能获得条码图片。哈哈,看过本系列第三篇《动态生成图片》的朋友可能已经心中雪亮了,没错,使用同样的路数就可以将它用在Web程序中了。我为制作了一个示例程序,可以在本文的最后下载。
示例程序详解
MyHandler.cs与第三篇看起来差不多,只不过生成图片的工具由 GDI+ 变成了条码控件。为了使用条码控件,需要在 mylib.system.web 类库里添加对条码控件(“barcode.dll”)和System.Windows.Form的引用
为了使用RDLC报表,我们的数据源由第三篇中的数组改成了一个Domain Object:
VisitorTraffic.cs
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1usingSystem;
2usingSystem.Data;
3usingSystem.Configuration;
4usingSystem.Web;
5usingSystem.Web.Security;
6usingSystem.Web.UI;
7usingSystem.Web.UI.WebControls;
8usingSystem.Web.UI.WebControls.WebParts;
9usingSystem.Web.UI.HtmlControls;
10usingSystem.Collections.Generic;
11
12///<summary>
13///VisitorTraffic的摘要说明
14///</summary>
15publicclassVisitorTraffic
16{
17privatestring_website_name;
18privatestring_visitor_traffic;
19
20publicstaticList<VisitorTraffic>find_all()
21{
22List<VisitorTraffic>result=newList<VisitorTraffic>();
23result.Add(newVisitorTraffic("1.使用分治法实现的全排列算法","50"));
24result.Add(newVisitorTraffic("2.让Ruby的数组支持任意起始下标","16"));
25result.Add(newVisitorTraffic("3.输出二叉树的方法","14"));
26
27returnresult;
28}
29
30publicVisitorTraffic(stringwebsite_name,stringvisitor_traffic)
31{
32_website_name=website_name;
33_visitor_traffic=visitor_traffic;
34}
35
36publicstringwebsite_name
37{
38get{return_website_name;}
39set{_website_name=value;}
40}
41
42publicstringvisitor_traffic
43{
44get{return_visitor_traffic;}
45set{_visitor_traffic=value;}
46}
47}
48
VisitorTraffic 类的两个属性 website_name 和 visitor_traffic 分别表示网页名称和访问量。静态函数 find_all() 通过硬编码的方式返回3条有用的数据。VisitorTraffic 类放置在Web应用程序的 App_Code 文件夹下。
Default.aspx 中放置一个 GridView 控件和和一个 ReportViewer 控件。在Page_Load() 时初始化这两个控件。
Default.aspx
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1<%@PageLanguage="C#"AutoEventWireup="true"CodeFile="Default.aspx.cs"Inherits="_Default"%>
2
3<%@RegisterAssembly="Microsoft.ReportViewer.WebForms,Version=8.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a"
4Namespace="Microsoft.Reporting.WebForms"TagPrefix="rsweb"%>
5<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
6<htmlxmlns="http://www.w3.org/1999/xhtml">
7<headrunat="server">
8<title>无标题页</title>
9</head>
10<body>
11<formid="form1"runat="server">
12<div>
13<asp:LabelID="Label2"runat="server"Font-Bold="True"ForeColor="#0000C0"Text="GridView:"></asp:Label>
14<asp:GridViewID="GridView1"runat="server"AutoGenerateColumns="False"CellPadding="3"
15GridLines="Vertical"BackColor="White"BorderColor="#999999"BorderStyle="None"
16BorderWidth="1px">
17<FooterStyleBackColor="#CCCCCC"ForeColor="Black"/>
18<Columns>
19<asp:TemplateFieldHeaderText="网址">
20<ItemTemplate>
21<asp:LabelID="Label1"runat="server"Text='<%#Eval("website_name")%>'></asp:Label>
22</ItemTemplate>
23</asp:TemplateField>
24<asp:TemplateFieldHeaderText="访问量">
25<ItemTemplate>
26<asp:ImageID="Image1"runat="server"ImageUrl='<%#"~/MyHandler.jxd?data="+Eval("visitor_traffic")%>'/>
27</ItemTemplate>
28</asp:TemplateField>
29</Columns>
30<RowStyleBackColor="#EEEEEE"ForeColor="Black"/>
31<SelectedRowStyleBackColor="#008A8C"Font-Bold="True"ForeColor="White"/>
32<PagerStyleBackColor="#999999"ForeColor="Black"HorizontalAlign="Center"/>
33<HeaderStyleBackColor="#000084"Font-Bold="True"ForeColor="White"/>
34<AlternatingRowStyleBackColor="#DCDCDC"/>
35</asp:GridView>
36<br/>
37<asp:LabelID="Label3"runat="server"Font-Bold="True"ForeColor="#0000C0"Text="RDLC报表:"></asp:Label>
38<rsweb:ReportViewerID="ReportViewer1"runat="server"Width="443px">
39</rsweb:ReportViewer>
40</div>
41</form>
42</body>
43</html>
44
Default.aspx.cs
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->1usingSystem;
2usingSystem.Data;
3usingSystem.Configuration;
4usingSystem.Web;
5usingSystem.Web.Security;
6usingSystem.Web.UI;
7usingSystem.Web.UI.WebControls;
8usingSystem.Web.UI.WebControls.WebParts;
9usingSystem.Web.UI.HtmlControls;
10
11usingSystem.Collections.Generic;
12usingMicrosoft.Reporting.WebForms;
13
14publicpartialclass_Default:System.Web.UI.Page
15{
16protectedvoidPage_Load(objectsender,EventArgse)
17{
18//为GridView设置数据源
19GridView1.DataSource=VisitorTraffic.find_all();
20GridView1.DataBind();
21
22//初始化报表
23ReportViewer1.LocalReport.ReportPath=Server.MapPath("~/Report.rdlc");
24ReportViewer1.LocalReport.EnableExternalImages=true;//允许使用外部图片
25
26//获取MyHandler.jxd的完整路径
27stringbarcode_url=Request.Url.Scheme+"://"
28+Request.Url.Authority
29+Request.ApplicationPath
30+"/MyHandler.jxd?data=";//->"http://localhost:6344/HttpHandlerDemo/MyHandler.jxd?data="
31
32//将MyHandler.jxd的完整路径通过报表参数传给报表
33ReportViewer1.LocalReport.SetParameters(newReportParameter[]{newReportParameter("barcode_url",barcode_url)});
34
35//为报表设置数据源
36ReportViewer1.LocalReport.DataSources.Add(
37newMicrosoft.Reporting.WebForms.ReportDataSource("VisitorTraffic",VisitorTraffic.find_all()));
38}
39}
40
GridView 的设置基本保持第三篇的样子没变,在此就不在赘述了。下面着重介绍一下在RDLC报表里呈现条码的方法。在RDLC报表里使用外部图片,需要
- 在代码中将报表对象的 EnableExternalImages 属性设为 true。
- 将“图像”控件放置在表控件中。
- 将“图像”控件的“Source”属性设为“External”。
- 将“图像”控件的“Value”属性设为图片的地址。
在进行到上面的第四步(将“图像”控件的“Value”属性设为图片的地址)时,麻烦出现了。天杀的比尔居然要求在“Source”属性为“External”的情况下,“Value”必须以 http://, https://, ftp://, file:, mailto:, 或 news: 之一开头。换句话说,不允许我将Value设成 "~/MyHandler.jxd?data="+ Fields!visitor_traffic.Value 这种相对路径。可是我在RDLC里如何能得到 MyHandler.jxd 的完整路径呀?!我曾经试过不用图像控件,直接在“访问量”字段中写 "<img src='~/MyHandler.jxd?data=" + Fields!visitor_traffic.Value + "' />"。期望能骗过RDLC,直接输出IMG标记,结果RDLC十分智能地把所有的“ <”字符全部替换成了< 痛哭十分钟...
最后只好用了比较龌龊的方法:先在 Default.aspx.cs 中取得 MyHandler.jxd 的完整URL,然后通过报表参数(参数名为barcode_url)传递给RDLC报表对象(Default.aspx.cs 第26~33行)。而图像控件的Value属性就变成:Parameters!barcode_url.Value + Fields!visitor_traffic.Value
下载本篇全部源代码
本系列到此就结束了。我们并没有介绍太多HTTP处理程序的理论知识,对HTTP Handler的利用也仅仅局限于将它作为一个“虚拟页面”,您看得一定十分不过瘾吧 ?HTTP 处理程序的另外一个重要的应用是实现URL重写,Scott Mitchell 的
《URL Rewriting in ASP.NET》对这个主题进行了深入的探讨,并给出了一个完整的解决方案。《
ASP.NET 2.0高级编程》一书有对HTTP模块的详细描述,可以
在线免费试读。希望本系列可以作为您通往精通HTTP处理技术之路的第一块垫脚石,再见。