我正在使用 SQL Server 2008 和 C#,我将图像路径存储在我的数据库表(员工详细信息)中,并通过数据集将此表与 Crystal Report 绑定。现在,如何将照片与 Crystal Report 中的每条记录绑定?
2 回答
在意识到有多少人无法让用户将图像上传到他们的水晶报表时,我决定写这篇文章。举例来说,如果用户想要更改或上传他们的徽标到水晶报表上。你怎么能做到这一点?开发人员如何向用户提供此功能?
我们都知道,用户无法自定义水晶报表。一旦生成了水晶报表,用户就没有太多的选择来随意更改字段。本文将演示用户如何在水晶报表上上传或更改图像。
这实际上是一个非常简单的例子。即使您对 Crystal 报表有一些新手知识,您也将能够理解它是如何工作的。我正在使用 Crystal 报表 11 进行此演示。
要从头开始,创建一个新的 windows 应用程序并添加一个水晶报表查看器和一个浏览按钮。
此浏览按钮将允许用户将图像添加到报告中。将水晶报表添加到您的项目中。
报告架构:
我们都知道,我们需要为水晶报表提供一个架构。这是我们将为报告提供的报告模式的 XML 视图。
<?xml version="1.0" standalone="yes"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-
microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="en-AU">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="Images">
<xs:complexType>
<xs:sequence>
<xs:element name="path" type="xs:string" minOccurs="0" />
<xs:element name="image" type="xs:base64Binary" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
BLOB 字段:
为了将图像添加到水晶报表(考虑到图像字段来自数据库),我们需要在模式中有一个 BLOB 字段。当您想在数据库中存储图像、文档或不同的自定义类型时,您可以使用 BLOB 字段。BLOB 代表二进制大对象。
<xs:element name="path" type="xs:string" minOccurs="0" />
<xs:element name="image" type="xs:base64Binary" minOccurs="0" />
如果您检查此模式,我们可以看到我们有一个名为的表Images
和两列path
和image
。image
列是 Base64 二进制类型。这是我们的 BLOB 字段。我们在程序中要做的是,当用户选择要上传的图像时,我们将该图像作为字节流存储在 BLOB 字段中,然后将该数据集提供给报告。
CreateTable()
方法将说明如何在程序中生成此模式。
为报告生成架构:
还有其他方法可以创建模式,但这会让您更清楚地了解列字段。
创建表:
private void CreateTable()
{
//create a new data set.
this.DsImages = new DataSet();
//create a new table with two columns and add the table to the dataset
DataTable ImageTable = new DataTable("Images");
//in here the "path" column is not really needed. Image column is just enough.
ImageTable.Columns.Add(new DataColumn("path",typeof(string)));
//Important note
//Note the type of the image column. You want to give this column as a blob field to the crystal report.
//therefore define the column type as System.Byte[]
ImageTable.Columns.Add(new DataColumn("image",typeof(System.Byte[])));
this.DsImages.Tables.Add(ImageTable);
}
如果您注意到该image
列,您可以看到该列的类型是System.Byte[]
. 这很简单。只需创建一个包含两列的表。然后将其添加到数据集。现在您可以使用以下行创建架构:
this.DsImages.WriteXmlSchema(@"c:\temp\ImagesSchem a.xsd");
一旦我们准备好模式,我们就可以将它提供给水晶报表。
在字段资源管理器中,我们可以看到图像表和两列路径和图像。当您将图像列拖到报表上时,您可以看到该字段的类型是IBlobFieldObject
。这些字段将读取字节流并将其转换回图像。这样我们的任务就差不多完成了。下面的代码向您展示了它如何将图像保存为 BLOB 字段中的字节流。
private void openFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
{
try
{
//get the image file into a stream reader.
FileStream FilStr = new FileStream(this.openFileDialog1.FileName, FileMode.Open);
BinaryReader BinRed = new BinaryReader(FilStr);
//Adding the values to the columns
// adding the image path to the path column
DataRow dr = this.DsImages.Tables["images"].NewRow();
dr["path"] = this.openFileDialog1.FileName;
//Important:
// Here you use ReadBytes method to add a byte array of the image stream.
//so the image column will hold a byte array.
dr["image"] = BinRed.ReadBytes((int)BinRed.BaseStream.Length);
this.DsImages.Tables["images"].Rows.Add(dr);
FilStr.Close();
BinRed.Close();
//create the report object
DynamicImageExample DyImg = new DynamicImageExample();
// feed the dataset to the report.
DyImg.SetDataSource(this.DsImages);
this.crystalReportViewer1.ReportSource = DyImg;
}
catch(Exception er)
{
MessageBox.Show(er.Message,"Error");
}
}
你FileOk
在openFileDialog
. 您使用该BinaryReader.ReadBytes
方法读取字节数组。
dr["image"] = BinRed.ReadBytes((int)BinRed.BaseStream.Length);
如果您检查这行代码,您可以看到我们在image
表的列中分配了一个字节数组。这个字节数组是用户选择的图像。因此,当您将此数据集提供给水晶报表IBlobFieldObject
时,报表中的会将此字节数组转换回图像。
这就是你在这个程序中需要了解的全部内容。下面我列出了您需要了解的所有重要步骤。
- 用户选择图像。
- 我们将图像作为字节流保存在 blob 字段中。
- 将数据集提供给包含 BLOB 字段的报表。
- 报告会将字节流转换回图像并显示它。
结论:
使用这个例子,我们可以让用户自定义他们想要上传到报告中的图像。如果用户想要更改报告上的图像或自己上传他们的徽标,这将是一个很好的实现。用户不必在每次想要更改报告上的图像时联系他们的软件开发团队。在报表中移动字段或添加新字段时,无法在用户端自定义水晶报表。本文仅帮助您了解如何在运行时上传图像。它没有告诉您如何在运行时自定义水晶报表。我希望你理解这篇文章的概念。
只需下载此程序并尝试一下。确保您拥有 Crystal Reports 11。我在这里编写的代码是基本的。理解这一点应该没有任何问题。 原始来源