You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Crystal Report中生成Code 128与QR code?

Crystal Report 集成ZXing生成QR Code/Code128条码实现方案

你已经搭好了DataSet推数的模式,还装了ZXing,直接走后端生成条码字节流推到报表的方案就行,不用折腾Crystal的第三方公式、条码字体那些坑,兼容所有运行时版本,部署也不用额外装东西。

1. 改造现有DataSet

打开你项目里给Crystal Report供数的强类型DataSet,给对应业务DataTable新增2个字段:

  • 字段名:QRCodeImg,类型选System.Byte[](字节数组)
  • 字段名:Code128Img,类型选System.Byte[](字节数组)
    不用设成Image类型,字节数组是Crystal识别图片兼容性最好的格式。

2. 后端用ZXing生成条码字节

先引入必要的命名空间,缺哪个引用直接补就行:

using ZXing;
using ZXing.QrCode;
using ZXing.Code128;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;

直接复用两个生成方法,输出的PNG格式字节流直接能被Crystal识别:

/// <summary>
/// 生成QR Code字节流
/// </summary>
/// <param name="content">编码内容</param>
/// <param name="width">图片宽度</param>
/// <param name="height">图片高度</param>
private byte[] GenerateQRCode(string content, int width = 150, int height = 150)
{
    var barcodeWriter = new BarcodeWriterPixelData
    {
        Format = BarcodeFormat.QR_CODE,
        Options = new QrCodeEncodingOptions
        {
            CharacterSet = "UTF-8",
            Width = width,
            Height = height,
            Margin = 1 // 保留最小白边,保证扫码识别率
        }
    };
    var pixelData = barcodeWriter.Write(content);
    using (var bmp = new Bitmap(pixelData.Width, pixelData.Height, PixelFormat.Format32bppRgb))
    using (var ms = new MemoryStream())
    {
        var bmpLock = bmp.LockBits(new Rectangle(0, 0, pixelData.Width, pixelData.Height), 
            ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb);
        try
        {
            Marshal.Copy(pixelData.Pixels, 0, bmpLock.Scan0, pixelData.Pixels.Length);
        }
        finally
        {
            bmp.UnlockBits(bmpLock);
        }
        bmp.Save(ms, ImageFormat.Png);
        return ms.ToArray();
    }
}

/// <summary>
/// 生成Code128条码字节流
/// </summary>
/// <param name="content">编码内容</param>
/// <param name="width">图片宽度</param>
/// <param name="height">图片高度</param>
private byte[] GenerateCode128(string content, int width = 220, int height = 60)
{
    var barcodeWriter = new BarcodeWriterPixelData
    {
        Format = BarcodeFormat.CODE_128,
        Options = new Code128EncodingOptions
        {
            Width = width,
            Height = height,
            Margin = 1,
            PureBarcode = false // 设为true则不显示条码下方的明文内容
        }
    };
    var pixelData = barcodeWriter.Write(content);
    using (var bmp = new Bitmap(pixelData.Width, pixelData.Height, PixelFormat.Format32bppRgb))
    using (var ms = new MemoryStream())
    {
        var bmpLock = bmp.LockBits(new Rectangle(0, 0, pixelData.Width, pixelData.Height),
            ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb);
        try
        {
            Marshal.Copy(pixelData.Pixels, 0, bmpLock.Scan0, pixelData.Pixels.Length);
        }
        finally
        {
            bmp.UnlockBits(bmpLock);
        }
        bmp.Save(ms, ImageFormat.Png);
        return ms.ToArray();
    }
}

在你原来给DataSet填充业务数据的逻辑里,加一步给条码字段赋值就行,举个例子:

// 假设reportTable是你已经填充完业务数据的DataTable
foreach (DataRow row in reportTable.Rows)
{
    // 替换成你实际要编码的字段,比如订单号、追溯码之类的
    string qrEncodeStr = row["订单ID"].ToString();
    string code128EncodeStr = row["SKU编码"].ToString();
    
    row["QRCodeImg"] = GenerateQRCode(qrEncodeStr);
    row["Code128Img"] = GenerateCode128(code128EncodeStr);
}
// 后面按你原有逻辑把DataSet绑定到Crystal Report报表即可,不用改其他传参代码

3. 报表模板绑定条码字段

  • 打开你的rpt报表文件,刷新字段资源管理器里的DataSet字段,能看到刚才加的两个字节数组字段
  • 直接把这两个字段拖到报表上要放置条码的位置,Crystal会自动识别为图片控件
  • 右键点图片控件选「设置对象格式」,在图片标签页调整等比缩放比例到合适尺寸就行

踩过的坑提醒

  • 别尝试在Crystal的公式字段里直接调用ZXing生成条码,Crystal运行时对第三方DLL的加载权限、版本匹配限制极多,部署到服务器十有八九报加载依赖失败,后端生成传字节流是最稳的方案
  • 条码Margin别设成0,四周留最少1个单位的白边,不然扫码枪/手机扫码识别率极低
  • 调整条码大小优先改生成方法里的width、height参数,别在模板里硬拉图片导致变形,变形后大概率扫不出来
  • Code128不用你手动加起始/停止校验位,ZXing会自动处理,直接传原始编码字符串就行
  • 不用在服务器或者客户端装任何条码字体,生成的是图片,所有环境打开都能正常显示

内容的提问来源于stack exchange,提问作者pankaj babbar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.22 16:15:01