图片转ODBC参数传入Crystal Reports时字段空白无显示
Crystal Reports 查询返回图片字段显示空白问题
问题相关代码
Dim conn As New OdbcConnection("dsn=localhost") Dim cmd As OdbcCommand Dim trans As New OdbcTransaction Dim da As OdbcDataAdapter Dim ds As New DataSet Dim query = "SELECT @img as imgblob;" cmd = New OdbcCommand(query,conn,trans) Dim params = cmd.Parameters.Add("@img",OdbcType.Binary) If File.Exists(Application.StartupPath & "\sample.png") Then Dim img As Image = Image.FromFile(Application.StartupPath & "\sample.png") Dim ms As New MemoryStream img.Save(ms, ImageFormat.Png) Dim binaryimg As Byte() = ms.GetBuffer() params.Value = binaryimg End If da = New OdbcDataAdapter(cmd) da.Fill(ds,"rpt_header")
已验证成立的前提条件
- 目标图片文件存在,
File.Exists判断返回true - 读取得到的
img对象不为null - ODBC参数
params已成功赋值 ms.GetBuffer()返回的二进制数据存在有效值
已尝试的无效排查操作
- 在查询语句中对
@img参数执行cast/convert类型转换 - 将查询语句中的参数占位符替换为
? - 切换图片保存格式为Jpg、Png、Gif等多种格式
- 将查询内容替换为普通文本时,可正常显示预期输出
解决方法
问题由两处错误共同导致,按顺序修改即可:
- 修正二进制图片的取值逻辑
MemoryStream.GetBuffer()返回的是流初始化时分配的全量缓冲区,包含大量未写入有效数据的空字节,会破坏图片文件头结构,导致Crystal Reports无法识别为合法图片。替换为MemoryStream.ToArray()即可,该方法仅返回实际写入流的有效二进制内容:
' 原错误写法 ' Dim binaryimg As Byte() = ms.GetBuffer() ' 修正后写法 Dim binaryimg As Byte() = ms.ToArray()
注意Image和MemoryStream对象使用完成后要主动调用Dispose()释放资源,避免出现文件锁、内存泄漏问题。
- 修正报表字段的绑定配置
- 不要使用普通文本框、二进制字段框承载图片,必须从Crystal Reports控件库拖入Blob字段图片对象,再将该对象绑定到返回的
imgblob字段 - 运行时确认填充到数据集的
rpt_header表中,imgblob字段的类型为System.Byte[],避免被ODBC适配器隐式转换为字符串或其他非二进制类型 - 如果使用强类型报表,需要提前在数据集XSD定义中将对应字段的数据类型设置为
System.Byte[],基类选择Binary
完成以上修改后不需要调整SQL语法、更换图片格式即可正常显示图片。
内容的提问来源于stack exchange,提问作者Kulotskie Gaming
相关产品推荐
相关产品推荐

