C#使用Bartender实现高效的批量数据打印

应用场景:大量变化且不规律的数据需要实现连续打印输出

需求:Bartender 10.0专业版以上,注意:商业使用请使用正版软件

安装避坑:电脑如果安装过某些条码打印机附送的免费版的Bartender(不带SDK版本),可能会出现无法成功安装更高版本的情况,即卡在安装界面,解决办法目前只有重装系统,直接安装高版本

Bartender API引用有两种方式,一种是引用其自带的.NET SDK,路径是Bartender安装目录\SDK\Assemblies\Seagull.BarTender.Print.dll

该方法优点是操作友好度高,有完整的示例程序,自带了例如生成标签模板的thumbnail缩略图等封装好的功能,缺点是只支持.NET Framework,无法支持.NET Core

另一种方式是引用Bartender COM文件,方法是工程中添加COM引用,搜索Bartender,勾选引用即可。该方法优点是适用性强,可以支持.NET版本调用,缺点定制度较低,几乎所有方法都需要自己进行设置,本例中推荐使用此方法,因为其适用性更强。

思路:

通过创建数据实体类的列表,序列化成JSON文件,在Bartender模板中映射数据库字段,再将数据库字段连接到具名数据源,各类Bartender对象(例如文本,条码,二维码等)就可以引用具名数据源,建立数据实体类列表到Bartender对象的映射关系,调用Bartender打印功能就会自动将列表中的数据全部打印出来,从而实现批量打印。

重点:Bartender模板引用的Json数据文件必须由数据实体类列表构成,例如创建如下的实体类

/// <summary>
/// 用于示例的实体类
/// </summary>
public class ExampleJsonEntity
{
    public string Name { get; set; }
    public int Age { get; set; }
    public DateTime JoinDate { get; set; }
    public SubExample SubExample { get; set; }
}
/// <summary>
/// 用于测试实体类中多层数据结构的次实体类
/// </summary>
public class SubExample
{
    public int Number { get; set; }
    public string BookName { get; set; }
}

通过System.Text.Json库将其序列化并保存到文件:

using System.Text.Json;

var entity = new ExampleJsonEntity();
entity.Name = "张三";
entity.Age = 15;
entity.JoinDate = DateTime.Now;
entity.SubExample = new SubExample() { BookName = "西游记", Number = 1 };
var entityList = new List<ExampleJsonEntity> { entity };
var jsonString = JsonSerializer.Serialize(entityList);
var path = Path.Join(Directory.GetCurrentDirectory(), "TestEntity.Json");
File.WriteAllText(path, jsonString);

运行代码会在程序文件夹下生成一个TestEntity.Json文件。

运行Bartender Designer,新建一个空白项目模板

数据库类型选择JSON,下一步选择“数据库文件”,接着在文件夹中选择TestEntity.Json文件,下一步到最后一个页面:

在可用节点选择框内把你要用到的数据库字段名称勾上,默认子类型中的字段并未勾选,如果要使用到就需要手动进行勾选 ,点击完成

接下来需要对应数据库字段创建具名数据源:

点击创建具名数据源,给一个名称(方便起见通常可以和数据库字段同名) ,下一步类型选择“数据库字段”,再下一步,在字段名下拉框中选择你要关联的字段,可以输入样本数据(未加载时显示的填充数据),点击完成。依次创建具名数据源,关联全部数据库字段。

接下来可以试验Bartender对象对数据源的引用了,选择创建一个基本文本对象:

 

 创建完成后右键选择属性,数据源下会有一个默认的样本文本,选择这个样本文本,点击名称框右边的小按钮

选择“链接到现有的具名数据源” ,右边列表框中可以选择具名数据源的名称,确定即可实现对数据源的映射。(注意如果上一步没创建需要使用的具名数据源,这里也可以进行创建,但需要手动修改类型为数据库字段,并关联相应字段)

至此已实现Bartender模板对数据实体类的映射,接下来可以测试填充数据并打印,我已经对打印方法进行了封装,参照说明可以直接使用进行打印:
 

using BarTender;

public static class BartenderPrintUtil
{
    private static Application? _btdApp;
    private static Format? _btdFormat;

    /// <summary>
    /// 读取Bartender模板和Json文件并进行打印
    /// </summary>
    /// <param name="templatePath">Bartender模板.btw文件存放路径</param>
    /// <param name="jsonPath">Json实体类序列化文件存放路径</param>
    /// <param name="printerName">使用的打印机名称</param>
    /// <param name="exactlySameCopies">复制打印的份数</param>
    /// <param name="printTimeOutMs">打印超时的时间(毫秒),-1为一直等待</param>
    /// <returns>Bartender错误列表</returns>
    public static async Task<List<string>> PrintFromJsonAsync(
        string templatePath,
        string jsonPath,
        string printerName,
        int exactlySameCopies = 1,
        int numberSerializedLabels = 1,
        int printTimeOutMs = -1
    )
    {
        return await Task.Run(() =>
        {
            try
            {
                OpenBtwFile(templatePath);

                try
                {
                    //验证给定的Json路径是否合法
                    var checkFile = new FileInfo(jsonPath);
                    //指定Json数据库路径
                    _btdFormat!.Databases.GetDatabase(1).JSONDatabase.FileName = jsonPath;
                    _btdFormat.Save();
                }
                catch
                {
                    //如果给定的Json路径不合法则返回错误信息
                    throw new FileNotFoundException("InValid Json Path");
                }
                //将要使用的打印机名称
                _btdFormat.PrintSetup.Printer = printerName;
                //拷贝份数,即完全一样内容打印的数量
                _btdFormat.IdenticalCopiesOfLabel = exactlySameCopies;
                //模板中自增序列号的自增数量,默认为1
                _btdFormat.NumberSerializedLabels = numberSerializedLabels;
                //定义字符串列表准备接受Bartender产生的错误信息
                var errorList = new List<string>();
                //定义一个Bartender错误信息集合变量
                Messages errorMsg;
                //进行打印作业,产生的错误信息会归集到errorList中
                _btdFormat.Print("PrintFromJson", true, printTimeOutMs, out errorMsg);
                if (errorMsg.Count > 0)
                {
                    errorList.AddRange(from Message msg in errorMsg select msg.Message);
                }
                return errorList;
            }
            catch (Exception ex)
            {
                return [ex.Message];
            }
        });
    }

    private static void StartApp()
    {
        if (_btdApp is null)
        {
            _btdApp = new BarTender.Application();
        }
    }

    private static void CloseApp()
    {
        if (_btdApp is not null)
        {
            _btdApp.Quit(BarTender.BtSaveOptions.btDoNotSaveChanges);
            _btdApp = null;
        }
    }

    private static bool OpenBtwFile(string templatePath)
    {
        try
        {
            StartApp();
            var checkFile = new FileInfo(templatePath);
            if (_btdFormat is null)
            {
                _btdFormat = _btdApp!.Formats.Open(templatePath);
                return true;
            }

            if (_btdFormat.FileName == templatePath)
                return true;
            _btdFormat.Close(BtSaveOptions.btDoNotSaveChanges);
            _btdFormat = _btdApp!.Formats.Open(templatePath);
            return true;
        }
        catch
        {
            return false;
        }
    }
}

 本方法的特点:

这个方法利用Bartender内部实现的机制对实体类列表进行连续打印,具体表现来说就是打印机不需要每次都初始化,而是进行连续输出,对大量数据来说极大提高了打印效率,而如果你在C#内部实现一个打印循环,则每次都需要初始化打印机序列,效率较低。这个方法的关键在于Bartender模板的创建上,只要模板做好了数据库映射,接下来的工作会非常简单。

  • 38
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: C是最常用的编程语言之一,它由丹尼斯·里奇在20世纪70年代初在贝尔实验室开发。C具有广泛的应用领域,包括系统编程、嵌入式系统开发、游戏开发、应用软件开发等。 C语言具有简单、高效和可移植的特性。它的语法简洁明了,易于学习和理解,使得开发者能够快速地掌握和应用它。C语言的高效性使得它成为一种非常适合开发底层系统和性能敏感的应用的选择。此外,C语言还具有很强的可移植性,可以在不同的平台上运行,这对于跨平台应用开发来说非常重要。 C语言是现代编程语言的基础之一,它的设计和语法影响了之后许多编程语言的发展,包括C++、Java和C#等。学习C语言可以帮助开发者更好地理解和掌握其他编程语言。此外,C语言还提供了丰富的标准库,使得开发者可以方便地进行各种操作和功能的实现。 尽管C语言有许多优点,但它也存在一些限制。由于C语言是一种低级语言,开发者需要手动管理内存,这可能会导致内存泄漏和悬挂指针等问题。此外,C语言相对较底层,需要开发者自行处理许多底层的细节,这可能会增加开发的复杂性。 总结来说,C语言是一种强大而广泛应用的编程语言,具有简单、高效和可移植的特性。它为开发者提供了丰富的功能和灵活性,使得它成为许多领域首选的编程语言。尽管它也有一些限制,但C语言仍然是学习和掌握的重要编程语言之一。 ### 回答2: c 是英文字母表中的第三个字母,也是拉丁字母表中常见的一个字母。c的发音是/k/,它可以单独作为字母出现,也可以与其他字母组合成为词汇的一部分。 在数学中,c可以表示很多不同的值。如果代表一个常数,它可以表示光速,也就是约等于每秒30万公里。c也是复数域中的一个符号,表示复数单位1元素的平方根。 在计算机科学中,c是一种编程语言,由贝尔实验室的Dennis Ritchie在20世纪70年代开发。C语言是一种通用的编程语言,对于编写系统软件、嵌入式系统和各种应用程序都非常适用。 另外,c也可以表示一些概念,例如:c型人格特征,代表平易近人、友善和善良;在化学中,c代表摄氏度;在音乐领域,C调是一个常见的音调。 总的来说,c是一个非常常见的字母和符号,它在数学、计算机科学和其他领域中有着重要的意义。无论是代表常数、编程语言,还是代表不同的属性和单位,c都是我们日常生活中接触到的一个字母。 ### 回答3: c是一个比较通用的字母,既可以代表英语中的单词,也可以代表数字。在英语中,c常常用于表示一些常见的词汇,比如can、cat、car、city等。同时,在某些情况下,c还可以表示一些特定的词汇,比如courage(勇气)、communication(沟通)等。 此外,在数学中,c也常常用来表示数字,特别是罗马数字中的100。比如,C表示100,CC表示200,CD表示400等。另外,小写的c也可以表示十进制数中的百分之一,比如0.01。 除了单词和数字,c还有一些其他的用途。比如,在计算机科学中,c是一种编程语言的名称,这是一种很常见的高级编程语言,广泛用于开发各种应用程序。此外,c还是一种音符,在音乐中用来表示音高。同时,在物理中,c是光速(光在真空中传播的速度)的代号,约为每秒3×10^8米。 综上所述,c是一个多功能的字母,既可以表示英语中的一些常见词汇,也可以表示数字、音符、编程语言等。它的用途十分广泛,无论是在日常生活中还是在学术领域中,c都扮演着重要的角色。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值