Monday, April 20, 2009

How to load an image from disk into Crystal Reports?

Introduction
One of the missing parts when it comes to reporting via .NET and Crystal Reports is the lack of support of image support.
It’s not directly possible to load an image based on a provided filepath in the report at runtime.
This feature is now available in the new Crystal Reports 11, but the bundled version of Visual Studio lack the possibility.

But Crystal Reports in Visual Studio supports datasets, and we’ll load an image in the report via a dataset!

Tools
-Visual Studio professional or Enterprise architect. You could also use any Visual Studio version with a separate Crystal Reports version (one that does support datasets!).
-10 minutes of time.
-Some general concepts about Crystal Reports and datasets

Tasks
-create a dataset that supports images
-create a report that support this dataset
-load data in the dataset
-use the dataset as datasource for the report and show the report in the viewer

In the attachment you’ll find a fully working sample. Feel free to experiment with it and spread it around the world!

Ready?

Create a new winforms project and a dataset (dsImageReport) to it. You’ll need to include 1 table (Image) with two columns:

Table Image
Name: string
Photo: base64Binary

The names of the columns don’t matter that much, it’s important that you use the base64Binary datatype for the second column! We will load the image from disk as a bytearray.

Creating the report is easy. Create a new report, when choosing the datasource go for the ADO.NET option and browse for the dsImageReport.xsd file in your project directory.

Now drag the two fields from your fieldexplorer in your report.
You’ll notice that the Photo field is of a BLOB datatype. This is exactly like we need. You don’t need to insert a picture in your report. Just drag the Photo field in the report. This field will be a square (1 inch x 1 inch). Don’t resize it but right click it and select Format Graphic. In the format editor check the ‘can grow’ checkbox. This will make it possible to load images of different sizes in the report!

We need to load the data in the dataset based on a given filepath, use that dataset as datasource for the report and show the report in the viewer.

Here’s the code:


Code:
Private Sub btnLoadImage_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnLoadImage.Click

Dim ofdImage As New OpenFileDialog

If ofdImage.ShowDialog = DialogResult.OK Then

Try

'Create a new instance of the dataset
Dim dsImgRpt As New dsImageReport

'Create a new instance of the report
Dim m_imagereport As New rptImage

'Create a new row in the dataset
Dim dr As dsImageReport.ImageRow = _
dsImgRpt.Image.NewImageRow

'Set the various elements of the row
dr.Name = ofdImage.FileName
'fill this field with a byte array
dr.Photo = GetImageData(ofdImage.FileName)

'Add the new row to the dataset
dsImgRpt.Image.Rows.Add(dr)

'Use the dataset as datasource for the report
m_imagereport.SetDataSource(dsImgRpt)

'Show the report in the reportviewer
Me.crystalReportViewer1.ReportSource = m_imagereport

Catch ex As Exception

MessageBox.Show("Something went wrong: " & ex.Message)

End Try

End If

End Sub

Private Function GetImageData(ByVal fileName As String) As Byte()

'Method to load an image from disk and return it as a bytestream
Dim fs As System.IO.FileStream = _
New System.IO.FileStream(fileName, _
System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim br As System.IO.BinaryReader = New System.IO.BinaryReader(fs)
Return (br.ReadBytes(Convert.ToInt32(br.BaseStream.Length)))

End Function

You see that it isn’t that difficult to load an image from file in a dataset. There are a lot of possibilities when it comes to reporting when you’re using a dataset as datasource. The biggest advantage is that you can manipulate the data in your dataset the way you want. Crystal isn’t that flexible when it comes to data manipulating but datasets are excellent for this!

Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home