阿泰的软件实用主义

水晶报表/BOE

博客园 首页 新随笔 联系 订阅 管理
  176 Posts :: 9 Stories :: 2046 Comments :: 38 Trackbacks

 

开发环境: VS2003(VB.Net) + 水晶报表10高级专业开发版 + Win2003

Step1:数据库文件版本

如果你在数据库中采用了二进制字段存储图片文件
微软 Access 里这些字段叫作 OLE 字段,而Oracle和SQL Server把它们称作 BLOB (二进制大型对象) 字段
那么在报表上显示出来就非常之简单
因为之前我没有做过类似的显示图片文件的报表,等我做出来之后,我自己都乐了
其实对这种二进制形式来说,跟普通的字段是一样的,拖到模板上就行了,呵呵



Setp2:下面我们来做一下加载磁盘上的图片的程序

其实有了上次《在水晶报表中实现任意选择指定字段显示》的实践,这次的思路就很明了了
就是先创建一个跟数据库版本一致的报表,当然是使用人见人爱的Ado.Net的方式
自己构造一个DataSet,把本地图片读成二进制流写进去
然后将这个DataSet推给报表就行了

我使用了水晶报表自己带的示例数据库里面的"雇员表"

看一下结构,主要是看一下各字段的格式,因为我们在创建DataSet的时候进行对应

特别注意下那个图片字段的格式,在VB.Net里我们可以用Byte来与之呼应

模板文件如下,没啥特别


代码如下,有详尽注释。

  1'************************************************************************* 
  2'**模 块 名:CR_DynLoadPics
  3'**说 明:Facesun.cn 版权所有2005 - 2006(C) 
  4'**创 建 人:Babyt(阿泰) http://www.cnblogs.com/babyt 
  5'**日 期:2005-04-21 
  6'**修 改 人: 
  7'**日 期: 
  8'**描 述:从本地磁盘获取图片文件进行显示
  9'          本程序为原型程序,未进行完整保护
 10'**版 本:V1.0.0 
 11'************************************************************************* 
 12
 13Imports System.Data
 14'注意此处IO的加入是为了读取图片文件
 15Imports System.IO
 16Public Class Form1
 17    Inherits System.Windows.Forms.Form
 18
 19#Region " Windows 窗体设计器生成的代码 "
 20
 21    Public Sub New()
 22        MyBase.New()
 23
 24        '该调用是 Windows 窗体设计器所必需的。
 25        InitializeComponent()
 26
 27        '在 InitializeComponent() 调用之后添加任何初始化
 28
 29    End Sub

 30
 31    '窗体重写 dispose 以清理组件列表。
 32    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
 33        If disposing Then
 34            If Not (components Is NothingThen
 35                components.Dispose()
 36            End If
 37        End If
 38        MyBase.Dispose(disposing)
 39    End Sub

 40
 41    'Windows 窗体设计器所必需的
 42    Private components As System.ComponentModel.IContainer
 43
 44    '注意: 以下过程是 Windows 窗体设计器所必需的
 45    '可以使用 Windows 窗体设计器修改此过程。
 46    '不要使用代码编辑器修改它。
 47    Friend WithEvents Button1 As System.Windows.Forms.Button
 48    Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
 49    Friend WithEvents CrystalReportViewer1 As CrystalDecisions.Windows.Forms.CrystalReportViewer
 50    Friend WithEvents Label1 As System.Windows.Forms.Label
 51    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
 52        Me.Button1 = New System.Windows.Forms.Button
 53        Me.TextBox1 = New System.Windows.Forms.TextBox
 54        Me.CrystalReportViewer1 = New CrystalDecisions.Windows.Forms.CrystalReportViewer
 55        Me.Label1 = New System.Windows.Forms.Label
 56        Me.SuspendLayout()
 57        '
 58        'Button1
 59        '
 60        Me.Button1.Location = New System.Drawing.Point(52040)
 61        Me.Button1.Name = "Button1"
 62        Me.Button1.TabIndex = 0
 63        Me.Button1.Text = "生成报表"
 64        '
 65        'TextBox1
 66        '
 67        Me.TextBox1.Location = New System.Drawing.Point(4040)
 68        Me.TextBox1.Name = "TextBox1"
 69        Me.TextBox1.Size = New System.Drawing.Size(39221)
 70        Me.TextBox1.TabIndex = 1
 71        Me.TextBox1.Text = "E:\myNet\CR_DynLoadPics\Pics"
 72        '
 73        'CrystalReportViewer1
 74        '
 75        Me.CrystalReportViewer1.ActiveViewIndex = -1
 76        Me.CrystalReportViewer1.AutoScroll = True
 77        Me.CrystalReportViewer1.DisplayBackgroundEdge = False
 78        Me.CrystalReportViewer1.DisplayGroupTree = False
 79        Me.CrystalReportViewer1.Location = New System.Drawing.Point(2480)
 80        Me.CrystalReportViewer1.Name = "CrystalReportViewer1"
 81        Me.CrystalReportViewer1.ReportSource = Nothing
 82        Me.CrystalReportViewer1.Size = New System.Drawing.Size(616320)
 83        Me.CrystalReportViewer1.TabIndex = 2
 84        '
 85        'Label1
 86        '
 87        Me.Label1.Location = New System.Drawing.Point(408)
 88        Me.Label1.Name = "Label1"
 89        Me.Label1.Size = New System.Drawing.Size(43223)
 90        Me.Label1.TabIndex = 3
 91        Me.Label1.Text = "请正确输入图片文件所在的目录,最后面不要带\,此处未进行校验!"
 92        '
 93        'Form1
 94        '
 95        Me.AutoScaleBaseSize = New System.Drawing.Size(614)
 96        Me.ClientSize = New System.Drawing.Size(664429)
 97        Me.Controls.Add(Me.Label1)
 98        Me.Controls.Add(Me.CrystalReportViewer1)
 99        Me.Controls.Add(Me.TextBox1)
100        Me.Controls.Add(Me.Button1)
101        Me.Name = "Form1"
102        Me.Text = "Form1"
103        Me.ResumeLayout(False)
104
105    End Sub

106
107#End Region

108
109    Private Sub Button1_Click(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles Button1.Click
110        '查看CrystalReport1的定义可以查看对应的报表类
111        Dim crReportDocument As New CrystalReport1
112        Dim myDataSet As New DataSet
113        Dim PicPath As String
114        Dim myColume As System.Data.DataColumn
115        Dim myRow As DataRow
116
117        '--------------------------------------------------------------------- 
118        '构造一个表,对应xsd文件
119        myDataSet.Tables.Add("雇员")
120        '构造表结构,可以只构造部分字段
121        myDataSet.Tables(0).Columns.Add("", System.Type.GetType("System.String"))
122        myDataSet.Tables(0).Columns.Add("", System.Type.GetType("System.String"))
123        myDataSet.Tables(0).Columns.Add("雇员照片", System.Type.GetType("System.Byte[]"))
124
125        '--------------------------------------------------------------------- 
126        '写入数据
127        '注意此处没有进行校验
128        PicPath = TextBox1.Text & "\"
129        '写数据行(分别用了3种图片格式)
130        '提示:
131        '   在这里你就可以使用你的数据库中保存的文件路径了
132        '   用你的DataSet来填充这个将推给报表的DataSet
133        '   如:
134        AddOneRow(myDataSet.Tables(0), "Babyt""JPG文件", PicPath & "BBT_042105_04.jpg")
135        AddOneRow(myDataSet.Tables(0), "FaceSun""Gif文件", PicPath & "Image49.gif")
136        AddOneRow(myDataSet.Tables(0), """Gif文件", PicPath & "Image5.gif")
137        AddOneRow(myDataSet.Tables(0), """JPG文件", PicPath & "1.jpg")
138        AddOneRow(myDataSet.Tables(0), "燕子""JPG文件", PicPath & "2.jpg")
139        AddOneRow(myDataSet.Tables(0), "Cnblogs.com/babyt""BMP文件", PicPath & "Coup30.bmp")
140
141        '将这个DataSet推给报表
142        crReportDocument.SetDataSource(myDataSet)
143
144        ''将报表传递给浏览器
145        CrystalReportViewer1.ReportSource = crReportDocument
146    End Sub

147    '*************************************************************************
148    '**函 数 名:AddOneRow
149    '**输    入:
150    '        ByRef tbl As DataTable 要操作的表,注意是Byref
151    '        ByVal c1 As String  第一个字段的值
152    '        ByVal c1 As String  第二个字段的值
153    '        ByVal c1 As String  第三个字段的值,注意传入的是完整的图片文件名
154    '**输    出:无
155    '**功能描述: 在DataTable中增加一个数据行
156    '               该过程的主要是封装根据文件名提取本地文件写入到DataSet中
157    '**全局变量:
158    '**调用模块:
159    '**作    者:Babyt(阿泰) 
160    '**日    期:2005-04-21
161    '**修 改 人:
162    '**日    期:
163    '**版    本:V2.0.0
164    '*************************************************************************
165    Public Sub AddOneRow(ByRef tbl As DataTable, ByVal c1 As StringByVal c2 As StringByVal c3 As String)
166        Dim fs As New FileStream(c3, FileMode.Open)   ' 获取文本流
167        Dim br As New BinaryReader(fs)                ' 创建Binary Reader
168        Dim row As DataRow
169
170        '创建一个新行
171        row = tbl.NewRow()
172
173        '赋值
174        row(0= c1
175        row(1= c2
176        '注意此处的写入方式
177        row(2= br.ReadBytes(br.BaseStream.Length)
178
179        '将该行增加到目标表
180        tbl.Rows.Add(row)
181
182        ' 释放
183        br = Nothing
184        fs = Nothing
185    End Sub

186
187    Private Sub Form1_Load(ByVal sender As System.ObjectByVal e As System.EventArgs) Handles MyBase.Load
188        TextBox1.Text = Directory.GetCurrentDirectory() & "\Pics"
189    End Sub

190End Class

191



运行效果

后记1:
我参考了海波的《利用数据集在水晶报表中显示图像的 .NET 程序教程 》
http://blog.csdn.net/haibodotnet/archive/2004/04/12/21570.aspx
里面是用子报表实现的,比较巧妙
大家可以参考一下,其中也有个VB.Net的例子
http://ftp1.businessobjects.com/outgoing/products/Devzone/vbnet_win_DynamicImage.zip

后记2:
经过实验,这个方法只能正常显示BMP/JPG图片,Gif就显示不出来
而且其大小似乎是固定的,不能随着图片的大小自动变化
所以这就要求你的图片尺寸一致

本文中的完整代码请在此处下载
http://files.cnblogs.com/babyt/CR_DynLoadPics.rar


-------Over------------------
希望这篇文章对你有所帮助。
阿泰 200504201

posted on 2005-04-21 16:23 阿泰 阅读(8701) 评论(28)  编辑 收藏 网摘 所属分类: CR我的原创

Feedback

那如果我在数据库中存储的不是二进制的文件,而是该图片在服务器上的路径呢?
要怎么样才能实现??
虚心请教,有急用!

请尽快回复,等候消息!


我用的是VS.NET2003和水晶报表9.1.5,以及Oracle9.X
谢谢
  回复  引用    

#2楼 [楼主] 2005-08-11 13:03 阿泰      
这篇文章的后半部分说的就是加载磁盘图片的,请耐心看完。
  回复  引用  查看    

#3楼  2005-08-11 14:08 ask [未注册用户]
阿泰,如果我用两个表,一个是专门存储数据,另一个专门存储图片,请问是否可以在同一个报表浏览器上显示呢?
  回复  引用    

#4楼 [楼主] 2005-08-11 14:15 阿泰      
两个表关联一下不就行了吗?呵呵
  回复  引用  查看    

#5楼  2005-08-12 15:58 ask [未注册用户]
问题是这两个表没有任何的关联,你说怎么办?不允许修改数据库了。
  回复  引用    

#6楼 [楼主] 2005-08-12 16:41 阿泰      
1:如果两个表有关系的话,在水晶报表里可以手动对两个表进行关联
2:如果两个表没有任何关系的话,可以在主报表里挂个子报表

  回复  引用  查看    

阿泰,我向討教一個問題,我的報表圖片顯示方式是調用數據庫中某一字段的路径,顯示圖片沒有問題,問題出在有的圖片有失真現象,因圖片的大小不一,可否做到不失真,也就是按圖片比例進行縮放,我發現Picture控件本身沒有按比例縮放這一設置,現在是無從下手,請你指點一二,在線等!!謝謝!

VB6+水晶报表10+SQL2000

  回复  引用    

#8楼  2005-08-15 14:30 ask [未注册用户]
阿泰,我试过使用子报表,可是不管怎么样弄 就是挂不上去阿,他总是说找不到表。我单独做一个子报表就可以显示图片,或者我单独使用你的方法都可以,就是将他们合到我的报表上就是不行。我的报表里面还有参数和公式,要不我发email给你,你帮我看看,指点一下如何?
  回复  引用    

#9楼 [楼主]