博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
热敏打印机编程
阅读量:6794 次
发布时间:2019-06-26

本文共 8202 字,大约阅读时间需要 27 分钟。

      在刚接触热敏打印机的时候,觉得这玩儿意还挺神奇的,这么小个东西,完全摆脱了我之前对打印机笨笨的映像,更神奇的是这东西不需要墨,于是去度娘了下,才发现跟普通的喷墨打印机有本质不同,它是通过打印头加热,使得纸上显示想要的图案,因此这个纸也不一般,表层有特殊的化学涂料,所以以后去超时,饭店吃饭,可不要随随便便的把各种小票放嘴里,其连接方式又可分为网络,蓝牙,USB,串口等等,作为码农来说连接方式与我何干,我只关心如何按照指令打印出我想要的东西,下面逐一介绍。

  1.指令集

  几乎看到的所有的热敏打印机都支持EPSON的ESC POS指令,因此首先可以去度娘上找一份热敏打印机指令集,阅读一番

  2.打印纸宽度

  目前市面上主要有两种宽度的打印机,58mm和80mm,这是指打印纸的宽度,其中80mm对应384pt,80mm对应586pt

  2.打印方式

  (1) 位图模式打印,通过文档发现支持位图打印模式,可以打印图片,就意味着我们可以通过随意定制html模板,然后填充数据,最后渲染成图片,对于打印机来说,就是打印图片,一个接口就可以搞定所有问题,这里只是提供一种思路,具体细节实现不在这里发散,感兴趣可以私信我,通过我们的实践,这种打印方式打印出来的效果最好,字体不受打印机限制,可以打印的特别清楚,这也是最为推荐的一种方式,有几个坑需要注意:

  a.通过渲染成图片打印并不适应于串口打印机,原因是渲染成图片数据量较大,而串口的传输速度明显不能满足,实测完美支持网口和USB打印机,没有测过蓝牙打印机

  b.谨防打印机内存溢出,不停的打印乱码,当图片很长的时候,需要进行截断打印,例如一张图片是576*10240,可以截成10章576*1024

  (2) 通过指令集进行打印,按照指令集文档进行打印,这种打印的优点就是数据量小,非常适合串口打印机,缺点是格式受限制,字体受限制,打出来的小票没有图片打印方式好看,下面是我们在打印过程中的一些常用命令的实现

printerprotocal.h

1 #ifndef PRINTERPROTOCAL_H 2 #define PRINTERPROTOCAL_H 3 #include 
4 #include
5 #define SERIAL_SIZE 8 6 class PrinterProtocal { 7 private: 8 std::vector
data_; 9 std::string tmp_data_;10 PrinterProtocal &writeString(std::string str);11 PrinterProtocal &writeByte(std::initializer_list
);12 public:13 PrinterProtocal();14 enum CharacterSet {15 USA,16 FRANCE,17 GERMANY,18 UK,19 DENMARK,20 SWEDEN,21 ITALY,22 SPAIN,23 JAPAN,24 NORWAY,25 DENMARK2,26 SPAIN2,27 LATINAMERICA,28 KOREA,29 Slovenia,30 Chinese31 };32 33 enum CodeTable {34 PC437,35 PC850,36 CHINESE = 3037 };38 39 enum AlignMode {40 LEFT,41 MIDDLE,42 RIGHT43 };44 45 enum PrintReadable {46 NONE,47 ABOVE,48 BELOW,49 BOTH50 };51 52 enum BarcodeType {53 UPCA,54 UPCE,55 EAN13,56 EAN8,57 CODE39,58 I25,59 CODEBAR,60 CODE93,61 CODE128,62 CODE11,63 MSI64 };65 66 67 PrinterProtocal &write(std::string str, int32_t size = 0, char ch = ' ');68 PrinterProtocal &init();69 PrinterProtocal &reset();70 PrinterProtocal &setFontSize(uint8_t);71 PrinterProtocal &setControlParameter(uint8_t heatingDots = 20,72 uint8_t heatingTime = 255, uint8_t heatingInterval = 250);73 PrinterProtocal &setSleepTime(uint8_t seconds = 0);74 PrinterProtocal &setStatus(bool state = true);75 PrinterProtocal &setPrintDensity(uint8_t printDensity = 14,76 uint8_t printBreakTime = 4);77 78 PrinterProtocal &setDoubleWidth(bool state = false);79 PrinterProtocal &setBold(bool state = false);80 PrinterProtocal &setReverse(bool state = false);81 PrinterProtocal &setUpDown(bool state = false);82 PrinterProtocal &setUnderline(bool state = false);83 PrinterProtocal &setKeyPanel(bool state = false);84 85 PrinterProtocal &setCharacterSet(CharacterSet set = USA);86 PrinterProtocal &setCodeTable(CodeTable table = PC437);87 PrinterProtocal &feed();88 PrinterProtocal &feed(uint8_t lines);89 PrinterProtocal &setLineSpacing(uint8_t spacing = 32);90 PrinterProtocal &setAlign(AlignMode align = LEFT);91 PrinterProtocal &setLeftBlankCharNums(uint8_t space = 0);92 PrinterProtocal &setMarginBottom(uint8_t lines = 100);93 std::vector
getResult();94 PrinterProtocal &done();95 };96 97 #endif // PRINTERPROTOCAL_H

 

printerprotocal.cpp

1 #include "printerprotocal.h"  2 #include 
3 #include "base/string_helper.h" 4 PrinterProtocal::PrinterProtocal() { 5 reset(); 6 } 7 8 9 // write single byte 10 PrinterProtocal &PrinterProtocal::writeByte(std::initializer_list
11 params) { 12 //先清理 13 if ((params.size() + tmp_data_.size()) > SERIAL_SIZE) { 14 done(); 15 } 16 for (auto ch : params) { 17 tmp_data_.push_back(ch); 18 } 19 return *this; 20 } 21 22 // write a string 23 PrinterProtocal &PrinterProtocal::writeString(std::string str) { 24 for (auto ch : str) { 25 if (tmp_data_.size() >= SERIAL_SIZE) { 26 done(); 27 } 28 tmp_data_.push_back(ch); 29 } 30 return *this; 31 } 32 //输入str,如果长度小于size,不足的部分用空格填充 33 PrinterProtocal &PrinterProtocal::write(std::string str, int32_t size, 34 char ch) { 35 std::string gbk_str = StringHelper::GetGBK(str); 36 while (static_cast
(gbk_str.size()) < size) { 37 gbk_str.push_back(ch); 38 } 39 writeString(gbk_str); 40 return *this; 41 } 42 PrinterProtocal &PrinterProtocal::done() { 43 if (tmp_data_.size() > 0) { 44 data_.push_back(tmp_data_); 45 tmp_data_.clear(); 46 } 47 return *this; 48 } 49 50 // initialize the printer 51 PrinterProtocal &PrinterProtocal::init() { 52 writeByte({
27, 64}).done(); 53 return *this; 54 } 55 56 // reset the printer 57 PrinterProtocal &PrinterProtocal::reset() { 58 data_.clear(); 59 return *this; 60 } 61 62 // sets the printer online (true) or ofline (false) 63 PrinterProtocal &PrinterProtocal::setStatus(bool state) { 64 writeByte({
27, 61, (uint8_t)state}).done(); 65 return *this; 66 } 67 68 // set control parameters: heatingDots, heatingTime, heatingInterval 69 PrinterProtocal &PrinterProtocal::setControlParameter(uint8_t heatingDots, 70 uint8_t heatingTime, uint8_t heatingInterval) { 71 writeByte({
27, 55, heatingDots, heatingTime, heatingInterval}).done(); 72 return *this; 73 } 74 75 76 //width,height均表示倍数 77 PrinterProtocal &PrinterProtocal::setFontSize(uint8_t size) { 78 //低4位表示高度,高4位表示宽度 79 uint8_t ret = (0x0f & (2 * size)) | (0xf0 & (16 * size)); 80 writeByte({
29, 33, ret}).done(); 81 return *this; 82 } 83 84 // set the used character set 85 PrinterProtocal &PrinterProtocal::setCharacterSet(CharacterSet set) { 86 writeByte({
27, 82, (uint8_t)set}).done(); 87 return *this; 88 } 89 90 // set the used code table 91 PrinterProtocal &PrinterProtocal::setCodeTable(CodeTable table) { 92 writeByte({
27, 116, (uint8_t)table}).done(); 93 return *this; 94 } 95 96 //打印并换行 97 PrinterProtocal &PrinterProtocal::feed() { 98 writeByte({
10}).done(); 99 return *this;100 }101 102 //打印并换lines行103 PrinterProtocal &PrinterProtocal::feed(uint8_t lines) {104 writeByte({
27, 74, lines}).done();105 return *this;106 }107 108 //设置行间距109 PrinterProtocal &PrinterProtocal::setLineSpacing(uint8_t spacing) {110 writeByte({
27, 51, spacing}).done();111 return *this;112 }113 114 // set Align Mode: LEFT, MIDDLE, RIGHT115 PrinterProtocal &PrinterProtocal::setAlign(AlignMode align) {116 writeByte({
27, 97, (uint8_t)align}).done();117 return *this;118 }119 120 //设置左边空白间距121 PrinterProtocal &PrinterProtocal::setLeftBlankCharNums(uint8_t space) {122 if (space >= 47) {123 space = 47;124 }125 writeByte({
29, 76, space}).done();126 return *this;127 }128 129 130 131 // set Bold Mode: on=true, off=false132 PrinterProtocal &PrinterProtocal::setBold(bool state) {133 writeByte({
27, 69, (uint8_t)state}).done();134 return *this;135 }136 //设定/解除反白打印模式137 // set Reverse printing Mode138 PrinterProtocal &PrinterProtocal::setReverse(bool state) {139 writeByte({
29, 66, (uint8_t)state}).done();140 return *this;141 }142 //设置/解除颠倒打印模式143 // set Up/Down Mode144 PrinterProtocal &PrinterProtocal::setUpDown(bool state) {145 writeByte({
27, 123, (uint8_t)state}).done();146 return *this;147 }148 149 //设置/取消汉字字符下划线模式150 PrinterProtocal &PrinterProtocal::setUnderline(bool state) {151 writeByte({
28, 45, (uint8_t)state}).done();152 return *this;153 }154 155 // enable / disable the key on the frontpanel156 //激活/禁止面板按键157 PrinterProtocal &PrinterProtocal::setKeyPanel(bool state) {158 writeByte({
27, 99, 53, (uint8_t)state}).done();159 return *this;160 }161 162 PrinterProtocal &PrinterProtocal::setMarginBottom(uint8_t lines) {163 writeByte({
27, 74, lines}).done();164 return *this;165 }166 167 std::vector
PrinterProtocal::getResult() {168 return data_;169 }

 

热敏打印机指令集中很多不一定用得到,而且感觉国内生产的这些打印机,对个别指令支持并不是特别好,要想做到完全兼容,还需要个性化的去适配。

 

转载于:https://www.cnblogs.com/polymax/p/6101644.html

你可能感兴趣的文章
checkbox设置复选框的只读效果不让用户勾选
查看>>
Golang 源码阅读 os.File
查看>>
IE 6 下出现 双倍距离 以及解决方案
查看>>
LayaAir 自旋转的小球跟随鼠标移动
查看>>
linux nginx 指定目录不可执行php文件
查看>>
django环境搭建
查看>>
共享 iOS沙盒文件管理
查看>>
MIME
查看>>
CMPopTipView
查看>>
windows系统下安装虚拟机-mac系统-视频教程
查看>>
spring ContentNegotiatingViewResolver---负责调用不同的j
查看>>
嵌入式Linux C编程 03
查看>>
华为聚簇表聚簇索引原理
查看>>
数据挖掘笔记
查看>>
Nginx配置性能优化
查看>>
Ubuntu下安装numpy and matplotlib
查看>>
Spring 统一管理输出
查看>>
LEXUS OPENCART 自适应主题模板 ABC-0019-01 HIGHLIGHTED FEA
查看>>
设置ListView页眉注意事项
查看>>
ubuntu 更新出错
查看>>