Crystal Report動態顯示圖片

引子

水晶報表以其強大的功能占距了強大的開發市場,其列印出的報表美觀、大方,深得用戶喜愛,然而其某些功能上不免有些瑕疵。例如,當資料庫中只存放了圖片的路徑時,當你在設計報表時,卻沒有提供將其列印成圖片的功能。當然,新版本
XI R2是有提供這些功能的,然,你總不會因為這個功能就要求你老闆去買最新版的CrystalReport? 既然選擇了程式員這一行業,我想沒有最新的工具,我們也能做出漂亮的帶圖片的報表來的。跟我來

環境

1VS05 + SQL Server2000 + VS2005自帶的CrystalReport 10.2
2VS2005 + SQL Server2000 + Crystal Report XI R2(11.5)

索引

1、版本11以下的動態圖片的顯示
1-1、     數據庫中圖片字段的顯示
1-2、     動態顯示字段
1-3、     設計顯示水晶模板
1-4、     編碼獲取水晶數據源

2、版本11以上的動態圖片的顯示
2-1、版本的獲得
2-2、版本的升級
2-3、升級注意事項

內容

1版本11以下的動態圖片的顯示
        1-1、數據庫中圖片字段的顯示
    這個其實就是數據庫中某一個字段保存了圖片的二進制流。跟普通的水晶報表設計沒有什么兩樣的。唯一需要註意的是如何將二進制流寫入數據庫中,或如何從數據庫的相關字段中取出來。就可以了。我這里貼出一段讀寫數據庫中二進制字段的代碼出來。讀者朋友們參考自行修改。

CodeViaDbBinaryField
    Private Sub Button1_Click()Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        
Dim bytePws As Byte() = Encoding.UTF8.GetBytes(CryptoFunc.Encrypt("admin"))
        
Using conn As New SqlConnection("Initial Catalog='Northwind';user id='sa';data source='localhost'")
            
Using comm As New SqlCommand("Update t set Pws=@Pws", conn)
                
Dim parameter As SqlParameter = New SqlParameter("@Pws", _
                                                    SqlDbType.Binary, _
                                                    bytePws.Length, _
                                                    ParameterDirection.Input, _
                                                    
False00Nothing, DataRowVersion.Current, bytePws)
                comm.Parameters.Add(parameter)
                conn.Open()
                comm.ExecuteNonQuery()
            
End Using
        
End Using
    
End Sub


    
Private Sub Button2_Click()Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        
Using conn As New SqlConnection("Initial Catalog='Northwind';user id='sa';data source='localhost'")
            
Using comm As New SqlCommand("Select top 1 * from  t ", conn)
                
Dim adapter As SqlDataAdapter = New SqlDataAdapter(comm)
                
Dim ds As New DataSet()
                adapter.Fill(ds, 
"t")
                
Dim bytePws As Byte() = CType(ds.Tables("t").Rows(0)("Pws"), Byte())
                
Dim str As String = Encoding.UTF8.GetString(bytePws)
                
str = str.Replace(Chr(0), "")
                MessageBox.Show(CryptoFunc.Decrypt(
str))
            
End Using
        
End Using
    
End Sub

2-2、動態顯示字段
    關於這一點。我們首先應該自定義一個xsd的文件,VS2005操作圖片依次為:
Crystal Report動態顯示圖片_第1张图片Crystal Report動態顯示圖片_第2张图片Crystal Report動態顯示圖片_第3张图片
  建立完如最后一張圖示的數據后,我們就可以開始設計水晶模板了。
    3-3、設計水晶模板,也就是我們常見的水晶報表文件的設計.
這一步注意數據庫專家選新建一個新的連接。如圖示

有了數據源之后,我想你的報表要如何擺放布局,就不需要教了吧。自行調整,我這里為了演示,布局如下

      4-4、這可能就是大家關心的地方的。
這里代碼主要是參考后面的后記里的部份代碼,在那篇文章中,只能顯示JPG和BMP格式的文件,制約了部分格式圖片的顯示.
而本篇所介紹的圖片是任意格式的均可顯示。先貼最終圖出來。

最后放出代碼

CodeofCRDynamicPic
Imports System.IO
Imports System.Data
Imports System.Drawing.Imaging

Public Class Form1Class Form1

    
Private Sub btnGenerate_Click()Sub btnGenerate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGenerate.Click
        
Dim crReportDocument As New CrystalReport1
        
Dim myDataSet As New DataSet
        
Dim PicPath As String

        myDataSet.Tables.Add(
"Table1")
        myDataSet.Tables(
0).Columns.Add("LastName", System.Type.GetType("System.String"))
        myDataSet.Tables(
0).Columns.Add("FirstName", System.Type.GetType("System.String"))
        myDataSet.Tables(
0).Columns.Add("Photo", System.Type.GetType("System.Byte[]"))

        PicPath 
= tbxPath.Text & "\"
        AddOneRow(myDataSet.Tables(
0), "Sunnet""JPG File", PicPath & "Sunset.jpg")
        AddOneRow(myDataSet.Tables(
0), "Jin""Gif File", PicPath & "1.gif")
        AddOneRow(myDataSet.Tables(
0), "Zhang""Gif File", PicPath & "2.gif")
        AddOneRow(myDataSet.Tables(
0), "Wang""JPG File", PicPath & "1.jpg")
        AddOneRow(myDataSet.Tables(
0), "Liu""JPG File", PicPath & "2.jpg")
        AddOneRow(myDataSet.Tables(
0), "VS2005""BMP File", PicPath & "vs2005.bmp")

        crReportDocument.SetDataSource(myDataSet)
        CrystalReportViewer1.ReportSource 
= crReportDocument
    
End Sub


    
Private Sub Form1_Load()Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        tbxPath.Text 
= Directory.GetCurrentDirectory() & "\Pics"
    
End Sub



    
Private Sub AddOneRow()Sub AddOneRow(ByRef tbl As DataTable, ByVal c1 As StringByVal c2 As StringByVal c3 As String)
        
Dim row As DataRow
        row 
= tbl.NewRow()
        row(
0= c1
        row(
1= c2
        row(
2= ConvertImage(c3)
        tbl.Rows.Add(row)
    
End Sub


    
Private Function ConvertImage()Function ConvertImage(ByVal path As StringAs Byte()
        
Dim stream As FileStream = Nothing
        
Try
            stream 
= File.OpenRead(path)
            
Return ConvertImage(stream)
        
Finally
            
If stream IsNot Nothing Then
                stream.Close()
            
End If
        
End Try
    
End Function


    
Private Function ConvertImage()Function ConvertImage(ByVal stream As Stream) As Byte()
        
Dim image As Image = image.FromStream(stream)
        
Dim myImage As Byte() = Nothing
        
If image.RawFormat.Guid <> ImageFormat.Jpeg.Guid AndAlso image.RawFormat.Guid <> ImageFormat.Bmp.Guid Then
            
Dim memStream As New MemoryStream()
            image.Save(memStream, ImageFormat.Jpeg)
            myImage 
= memStream.GetBuffer()
            memStream.Close()
        
Else
            stream.Position 
= 0
            myImage 
= New Byte(stream.Length) {}
            stream.Read(myImage, 
0, stream.Length)
        
End If
        
Return myImage
    
End Function

End Class

 

2版本11以上的動態圖片的顯示

2-1、版本的獲得
以下兩個鏈接,我不保証長期有效,我也是從網上找的。呵呵
File 1 - EXE 700MB(http://ftp1.businessobjects.com/webprod/crxi/crxir2sp1/crxir2.part1.exe)*
File 2 - RAR 386MB(http://ftp1.businessobjects.com/webprod/crxi/crxir2sp1/crxir2.part2.rar)*
2-2、版本的升級
安裝完之后,打開VS2005,我們發現版本就變了。

而且我們在11.5版本的水晶文件中,可以利用公式來動態指定圖片的位置的。如圖示:
Crystal Report動態顯示圖片_第4张图片

2-3、升級布署注意事項
我這里主要針對是WEB的,如果是Winform,建立打包的時候,將相關的合并模組打包發布出去。如果不行,請在你的本機C:"Program Files"Microsoft Visual Studio 8"SDK"v2.0"BootStrapper"Packages"CrystalReports下的CrystalRedist115_x86.msi拿到你的服務器上安裝一下。自然,如果是10.2的自帶版本,安裝CrystalRedist_x86.msi就可以了。只是不明白,網上似乎很多朋友說會出錯,我試過,卻是沒有問題的。如果是Web的話,本人建議你的Web.Config如下:


補充  

     關於水晶報表的兩種模式,pull和push模式,優劣各有,如有興趣,可自行在網站查閱相關文章評論,我這裡隻是記錄一下這兩種模式需要注意的地方:pull模式,由水晶報表自己獲取數據,但需要提供登陸信息。也就是TableLogOnInfo,列舉一下相關的代碼:

C#TableLogOnInfo
      private void SetLogOnInfo (string server, string database, string userID, string password, ReportDocument rd)
      {
         TableLogOnInfo logOnInfo 
= new TableLogOnInfo ();
       
         logOnInfo.ConnectionInfo.ServerName 
= server;
         logOnInfo.ConnectionInfo.DatabaseName 
= database;
         logOnInfo.ConnectionInfo.UserID 
= userID;
         logOnInfo.ConnectionInfo.Password 
= password;
         
         
foreach(CrystalDecisions.CrystalReports.Engine.Table dt in rd.Database.Tables)
        {
          dt.ApplyLogOnInfo(logOnInfo);
        }
      }
      
      

VB.NET_TableLogOnInfo
Private Sub SetLogOnInfo(ByVal server As StringByVal database _ 
      
StringByVal userID As StringByVal password As StringByVal _ 
      rd 
As ReportDocument)
      
         
Dim logOnInfo As New TableLogOnInfo()
               
         logOnInfo.ConnectionInfo.ServerName 
= server
         logOnInfo.ConnectionInfo.DatabaseName 
= database
         logOnInfo.ConnectionInfo.UserID 
= userID
         logOnInfo.ConnectionInfo.Password 
= password

         
For Each dt As CrystalDecisions.CrystalReports.Engine.Table In rd.Database.Tables
            dt.ApplyLogOnInfo(logOnInfo)
        
Next
      
End Sub

 如果報表文件本身帶有參數, 就需要指定這些參數字段的ParameterFieldDefinition對象集及對象和ParameterValue對象集及對象(一般是ParameterDiscreteValue離散值),舉一段VB.NET代碼吧:

VB.NET_ AddCrystalParameter
    Private Sub AddCrystalParameter(ByVal rd As ReportDocument, ByVal strParameterName As StringByVal strParameterValue As String)
        
Dim pfds As ParameterFieldDefinitions = rd.DataDefinition.ParameterFields
        
Dim pfd As ParameterFieldDefinition = pfds(strParameterName)
        
Dim pvs As ParameterValues = New ParameterValues()
        
Dim pdv As ParameterDiscreteValue = New ParameterDiscreteValue()        
        pvs 
= pfd.CurrentValues        
        pdv.Value 
= strParameterValue
        pvs.Add(pdv)
        pfd.ApplyCurrentValues(pvs)
    
End Sub

還是提供C#代碼吧,

C#_AddCrystalParameter
public void AddCrystalParameter(ReportDocument rd, string strParameterName, string strParameterValue)
    {
        ParameterFieldDefinitions pfds 
= rd.DataDefinition.ParameterFields;
                ParameterFieldDefinition pfd 
= pfds(strParameterName);
        ParameterValues pvs 
= new ParameterValues();
        ParameterDiscreteValue pdv 
= new ParameterDiscreteValue();
        pvs 
= pfd.CurrentValues;        
        pdv.Value 
= strParameterValue;
        pvs.Add(pdv);
        pfd.ApplyCurrentValues(pvs);
    }

push推模就是程序編程得到一個DataSet,推給報表文件,故名。最後使用SetDataSource給報表文件賦值就可以了,似乎沒有很多要講,但這種個人還是認為值得推薦。 

寫到這裡,又發現了一個網上的CrystalHelper的類,貼出地址吧:http://www.cnblogs.com/pccai/articles/895169.html 

我自己沒有試過,還有一篇文章,應該是蠻好,隻是頁面顏色不太協調,看著眼睛不舒服,也沒有完全看完,有興趣的可以看看:

http://hi.baidu.com/yaoyan0421/blog/item/cc6bcbcb9d5a8040f31fe756.html


后記

1、文在成形之前,參考了網上阿泰實用主義的<<水晶报表中如何动态加载图片(图片文件版本及数据库版本)>>地址是:http://www.cnblogs.com/babyt/archive/2005/04/21/142789.html
2、余皆原創,轉載請註明來自http://jinliangliu.cnblogs.com/
3、專案源碼下載一http://files.cnblogs.com/jinliangliu/CrytalReport.rar(版本11以下)
4、專案源碼下載二http://files.cnblogs.com/jinliangliu/WebSite1.rar(版本11.5以上)



 

你可能感兴趣的:(Crystal Report動態顯示圖片)