本文对指令打印和驱动打印做了一个简要的介绍,分享了在开发客户端打印组件时的一些过程并提出了一个新轮子用于解决老的问题并引出更多的新问题。全文大概 3500 字无图,阅读大概需要 7 分钟。

驱动打印是指:使用 PrintDocument 进行打印。通过注册其 PrintPage 方法拿到 Graphics 对象使用 GDI+ 画图打印。

指令打印是指:利用打印机厂商提供的指令协议控制打印机直接打印。

驱动打印和 Windows 平台关联紧密,所以不能做到跨平台。驱动打印大部分情况不能即插即用,在第一次将某打印机链接到电脑时,可能需要安装对应的驱动程序系统才能正确的识别到该打印机。

绝大部分小票打印机都支持 ESC 指令,除了 ESC 外常见的还有 TSC、TSPL,PPLA等这与打印机厂商和型号相关。指令打印可以跨平台,且在不同的平台要向硬件发出的指令是相同的,无论链接方式是 USB、串口还是蓝牙。

从开发的角度来说,如果我们想兼容市面上大多数打印机并且想支持跨平台,那么这就会是一件需要仔细斟酌和权衡的事情:

1、仅采用驱动打印。那么我们不得不放弃对跨平台的支持。如果遇到过老的设备,它很可能没有提供对最新的操作系统(比如 Windows 10)的支持,所以单纯的驱动打印是玩儿不赢的。

2、仅采用指令打印。我们可以做到跨平台,无惧系统升级,但仍有无解的情况:如果客户的打印机没有指令打印或者指令协议很小众没必要做支持怎么办?这是真实发生的事情,有客户需要用传统的办公用打印机打印小票,真·谜一般的操作。

3、驱动打印和指令打印并行。这当然会解决上述问题,但同时会引入新的问题:你不得不写出多套不同的代码去完成一件相同的事情,更可怕的是在修改一个问题时很可能会改了这一套忘了那一套。

在项目起初,因为对各种打印方案并不熟悉所以带你部分经过了上述三个阶段的演变。当支持的打印机和打印格式越来越多,维护这部分代码就成为一件苦力活儿,而且非常容易出错。接手这部分代码的人会被怀疑是否能力有问题,毕竟开始的时候时那么的简单。

大概 2019 年 7 月份时,项目组对驱动打印进行了封装,该封装参考了网上的开源组件,构建出了一个名为 TicketDocument 的类型,并添加了一些基础操作:

TicketDocument 可以序列化为 JSON 字符串用于在网络间传输。所以可以将 TicketDocument 的生成放置在服务端,这样对打印格式进行微调时不需要更新客户端。

项目中对 TicketDocument 的调用类似如下,其中 doc 变量即 TicketDocument 实例:

doc.AddText($"来源:{g.SName}");doc.AddNewRow();doc.AddText($"出厂时间:{g.CommandDate:yyyy/MM/dd}");doc.AddNewRow();doc.AddText($"产品:{g.Items.Count(i => i.FXashId == 0)}件", width: 0.4f);doc.AddText($"附件:{g.Items.Count(i => i.FXashId != 0)}件", width: 0.3f, offset: 0.4f,alignment: StringAlignment.Center);doc.AddText($"共计:{g.Items.Count}件", width: 0.3f, offset: 0.7f, alignment: StringAlignment.Far);

当项目不得不支持指令打印时, TicketDocument 的抽象定义就不能满足需求了:因为指令打印并不能提供类似于 GDI+ 这种强大的控制力。

驱动打印和指令打印并行的事情必须上马。因为指令各不相同,所以就编写了不同的代码对应不同的打印机,业务应用调用打印宿主时也采用多种不同的协议格式,因项目不同没有使用 TicketDocument 。这对驱动打印部分造成了影响,满天飞的硬编码,写死的数组下标,接着在对打印格式进行调整时,驱动打印罢工了。

于是,我们需要一个新的轮子:

  1. 它应该满足跨平台打印的需求,在 Windows、Android、iOS 中有相同的行为表现。

  2. 它应该同时支持驱动打印和指令打印。

  3. 在满足前两条的同时,它应该尽量减少新增格式时的工作量。

All problems in computer science can be solved by another level of indirection .

计算机科学中的所有问题都可以通过间接的另一个层次来解决。

出自:David Wheeler

这是软件工程学中的一个真理,我们可以引入一种新的自定义指令来决绝上述的问题:

  1. 这种指令是一种高级指令,它对驱动打印和大部分目前受支持的指令打印行为进行了封装。

  2. 这种高级指令最终会被翻译成对 Graphics 的操作或打印机指令。

  3. 这种高级指令由业务系统生成并可以在网络中进行传播。

  4. 这种高级指令可以使用目前的主流编程语言生成,比如 C#、Java、Python、PHP、JavaScript 等。

  5. 这种高级指令应该易于识别,并尽量减少在网络传输中的流量消耗。

TicketDocument 似乎是一个不错的先驱者,目前为止它满足了 3、4、5 这三个条件。但设计一种高级指令并不是唯一需要的事情,仍有许多工作要做比如这种高级指令的解析和转换等。

目前为止我并没有完成对这个轮子的全部设计,以上是对这个轮子的设想。这个轮子在设计上还不完整,有许多空白的部分需要填上。如果您对这个轮子感兴趣,可以收藏本站,在文章下留言或打赏作者,谢谢支持!

单片机 驱动 标签打印机tsc_指令打印与驱动打印随笔相关推荐

  1. 指令打印与驱动打印随笔

    本文对指令打印和驱动打印做了一个简要的介绍,分享了在开发客户端打印组件时的一些过程并提出了一个新轮子用于解决老的问题并引出更多的新问题.全文大概 3500 字无图,阅读大概需要 7 分钟. 驱动打印是 ...

  2. Windows打印体系结构之打印驱动框架

    庐山烟雨浙江潮,未到千般恨不消.到得原来无别事,庐山烟雨浙江潮. 1.2.Windows打印驱动框架 Windows的打印驱动从总体架构上来说,包括一个渲染组件和一个配置组件.我们可以回想一下最开始的 ...

  3. 单片机:STM32F4x HAL库软硬SPI驱动ST7735s 1.8寸LCD屏幕

    单片机:STM32F4x HAL库软硬SPI驱动ST7735s 1.8寸LCD屏幕 说明:此篇为学习记录.可能存在错误或者不足.如有问题请指出. 硬件环境 主控芯片:STM32F411CEU6 主控开 ...

  4. 博思得标签打印机驱动_惠普LaserJet 5200n驱动-惠普HP LaserJet 5200n打印机驱动下载 v61.074.561.43官方版...

    软件标签: 惠普LaserJet 5200n驱动可以帮助用户解决同型号打印机无法被电脑识别或者打印异常的问题,支持Windows XP / Windows 7 / Windows 10 32/64位操 ...

  5. 昆仑通态人机界面与单片机通信实战教程二:脚本驱动的设计

    大家好,我是『芯知识学堂』的SingleYork,前面给大家介绍了"昆仑通态人机界面与单片机通信实战教程一:工程界面的设计",今天笔者就要来给大家介绍"昆仑通态人机界面与 ...

  6. 昆仑通态人机界面与单片机通信实战教程三:脚本驱动与HDMI工程的关联

    大家好,我是『芯知识学堂』的SingleYork,前面给大家介绍了"昆仑通态人机界面与单片机通信实战教程二:脚本驱动的设计",今天笔者就要来给大家介绍"昆仑通态人机界面与 ...

  7. UGREEN 绿联 USB 2.0转串口DB9 打印线 驱动安装教程

    UGREEN 绿联 USB 2.0转串口DB9 打印线 驱动安装教程 访问网址https://www.lulian.cn  鼠标停留在 下载/支持 选择USB转串口驱动 三.选中 绿联USB转串口DB ...

  8. 计算机打印要先安装驱动吗,打印机驱动怎么安装,教您打印机驱动怎么安装

    小编发现好像小伙伴们都在找打印机驱动的安装方法,于是小编就来帮助小伙伴们解决问题啦,来来来,我们便往下看边说.因为小编的安装打印机驱动的操作方法就在文章的末尾呢.所以小伙伴们,快接着往下看吧. 小伙伴 ...

  9. 佳能c3320如何u盘打印_佳能c3320驱动|佳能ir adv c3320打印/扫描驱动下载 v21.75 官方版 - 比克尔下载...

    佳能ir adv c3320打印/扫描驱动包含了打印驱动和扫描驱动,是专为佳能ir adv c3320复印机用户打造的,能够解决佳能c3320复印机的一些驱动问题,你只需将复印机电缆断开后安装驱动程序 ...

最新文章

  1. puppet cert maintain
  2. 对Xml文档进行操作(修改,删除)
  3. qgraphicsitem 复制副本_删除/删除/替换QGraphicsTextItem中的选定文本
  4. windows mobile 上面固定比例图像缩放
  5. 使用严格模式的坏处_再见面试官:单例模式有几种写法?
  6. ios安全机制不支持antofocus
  7. Windows 必备纯净软件
  8. python移动文件,将一个文件夹里面的文件移动到另一个文件夹
  9. 软件注册机查找常用几个网址
  10. python设计教务管理系统_python实现教务管理系统
  11. 什么是全国大学生电子设计大赛?如何备战?
  12. 赵小楼《天道》《遥远的救世主》深度解析(16)丁元英停止私募基金不可言说的原因
  13. Android开发丶调用百度地图进行导航
  14. c++语言杨辉三角,杨辉三角 (C++代码)
  15. 附032.Kubernetes实现蓝绿发布
  16. 深入理解安卓Activity
  17. Centos7安装libreoffice
  18. 3、vue-路由、拦截器和嵌套路由
  19. Age Estimation
  20. PHP+Laravel+Fpdi+Fpdf 在PDF模板上编辑自定义文字并输出新PDF文件示例

热门文章

  1. python ssl socket_Python使用Socket(Https)Post登录百度的实现代码
  2. impala的substr从第几位截到最后一位_冰雪奇缘2彩蛋:片名内含深意,艾莎是第13位公主象征着背叛...
  3. miniblink载入html,(转)miniblink跨线程异步JS回调,及miniblink提升首屏加载速度的代码...
  4. hdfs是nas_HDFS 协议是怎么回事
  5. pg库和mysql的优缺点_MySQL与PostgreSQL的实际性能比较
  6. 联通突然从4g变成3g了_联通正式关闭2G、3G服务?官方回应:是用户手机的问题...
  7. jq 获取引入页面url_jqURL获取页面URL及参数
  8. webstorm 创建react组件_webstorm的下载以及React环境搭建
  9. Cannot add or update a child row: a foreign key constraint
  10. 记一次线上coredump事故