Visual Studio 2003/2005 does not readily allow you to
load an image file on a Crystal Report dynamically unless you use
"Dynamic Image Location" feature which is available in Crystal Reports
Developer XI. But there is a cheaper work around for this. The solution
is to dynamically add an binary column to the XSD dataset and in the
dataset containing the data to be printed. Then load the image file as
binary data into the dataset.
1. In a column in
your database table store the path to the image that needs to be
displayed in a crystal report document, in this example the image path
column name is "ImagePath".
2. Create a new
Dataset/XML schema(xsd) in VS.Net that maps the fields in the database
table. This should be the normal procedure when creating a report. In
this XSD DataSet add an additional field that is not in the table and
which is of type base64Binary :
xs:element name="Image" type="xs:base64Binary" minOccurs="0"
Note
that the opening and closing tags are missing above since it won't be
printed on this site. Just add enclose the above in "< />"
3. When designing the report based on this DataSet, drag and drop the "Image" field in the region where you want it to appear.
3. When designing the report based on this DataSet, drag and drop the "Image" field in the region where you want it to appear.
4. Add the following procedures to your code:
Private Sub AddImageColumn(ByVal objDataTable As DataTable, ByVal strFieldName As String)
Try
'create the column to hold the binary image
Dim objDataColumn As DataColumn = New DataColumn(strFieldName, Type.GetType("System.Byte[]"))
objDataTable.Columns.Add(objDataColumn)
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
'*... and this one to load the image in the above added field:
Private Sub LoadImage(ByVal objDataRow As DataRow, ByVal strImageField As String, ByVal FilePath As String)
Try
Dim fs As System.IO.FileStream = New System.IO.FileStream(FilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim Image() As Byte = New Byte(fs.Length-1) {}
fs.Read(Image, 0, CType(fs.Length, Integer))
fs.Close()
objDataRow(strImageField) = Image
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
Try
'create the column to hold the binary image
Dim objDataColumn As DataColumn = New DataColumn(strFieldName, Type.GetType("System.Byte[]"))
objDataTable.Columns.Add(objDataColumn)
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
'*... and this one to load the image in the above added field:
Private Sub LoadImage(ByVal objDataRow As DataRow, ByVal strImageField As String, ByVal FilePath As String)
Try
Dim fs As System.IO.FileStream = New System.IO.FileStream(FilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim Image() As Byte = New Byte(fs.Length-1) {}
fs.Read(Image, 0, CType(fs.Length, Integer))
fs.Close()
objDataRow(strImageField) = Image
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Sub
5. Before assigning the dataset to the "SetDataSource" of your report, add the following code:
' Fill the dataset "DS" as required with data to be displayed on the report'* Begin code to add
AddImageColumn(DS.Tables(0), "Image")
' Loop to load the image for each row
For index As Integer = 0 To DS.Tables(0).Rows.Count - 1
If Not String.IsNullOrEmpty(DS.Tables(0).Rows(index).Item("ImagePath").ToString) Then
LoadImage(DS.Tables(0).Rows(index), "Image", _
DS.Tables(0).Rows(index).Item("ImagePath").ToString)
Else
'* You could load a default image here, like "no image to display"
'* if you have a standard one then un-comment the code below and change the image path
'LoadImage(DS.Tables(0).Rows(index), "Image", "c:\MyDefaultImage.JPG")
End If
Next
'* End code to add
rptDoc.SetDataSource(DS.Tables(0))
' Display report in a report viewer control
No comments:
Post a Comment