Browse Source

initial commit

master
munir ishak 4 years ago
commit
c3338a649e
6 changed files with 458 additions and 0 deletions
  1. 1
    0
      .gitignore
  2. 29
    0
      README.md
  3. 44
    0
      buffer-helper.js
  4. 311
    0
      index.js
  5. 45
    0
      package-lock.json
  6. 28
    0
      package.json

+ 1
- 0
.gitignore View File

@@ -0,0 +1 @@
1
+node_modules/

+ 29
- 0
README.md View File

@@ -0,0 +1,29 @@
1
+# escpos-printer-toolkit
2
+
3
+A printer command toolkit for translate text to ESC/POS command. 
4
+
5
+e.g.  Text "<C>这是一段打印测试文字</C>"
6
+
7
+will be translate to esc/pos command with the text align center.
8
+
9
+## Installation
10
+
11
+```
12
+npm install escpos-printer-toolkit --save
13
+```
14
+
15
+## Usage
16
+
17
+```javascript
18
+import EPToolkit from 'escpos-printer-toolkit';
19
+let options = {
20
+  beep: true, 
21
+  cut: true, 
22
+  tailingLine: true,
23
+  encoding: 'GBK'
24
+}
25
+EPToolkit.exchange_text("<C>这是一段打印测试文字</C>", options)
26
+
27
+```
28
+
29
+

+ 44
- 0
buffer-helper.js View File

@@ -0,0 +1,44 @@
1
+const Buffer = require('buffer').Buffer
2
+
3
+var BufferHelper = function () {
4
+  this.buffers = [];
5
+  this.size = 0;
6
+  Object.defineProperty(this, 'length', {
7
+    get: function () {
8
+      return this.size;
9
+    }
10
+  });
11
+};
12
+
13
+BufferHelper.prototype.concat = function (buffer) {
14
+  this.buffers.push(buffer);
15
+  this.size += buffer.length;
16
+  return this;
17
+};
18
+
19
+BufferHelper.prototype.empty = function () {
20
+  this.buffers = [];
21
+  this.size = 0;
22
+  return this;
23
+};
24
+
25
+BufferHelper.prototype.toBuffer = function () {
26
+  return Buffer.concat(this.buffers, this.size);
27
+};
28
+
29
+BufferHelper.prototype.toString = function (encoding) {
30
+  return this.toBuffer().toString(encoding);
31
+};
32
+
33
+BufferHelper.prototype.load = function (stream, callback) {
34
+  var that = this;
35
+  stream.on('data', function (trunk) {
36
+    that.concat(trunk);
37
+  });
38
+  stream.on('end', function () {
39
+    callback(null, that.toBuffer());
40
+  });
41
+  stream.once('error', callback);
42
+};
43
+
44
+module.exports = BufferHelper;

+ 311
- 0
index.js View File

@@ -0,0 +1,311 @@
1
+const BufferHelper  = require("./buffer-helper");
2
+// const fs = require('fs');
3
+// const Jimp = require("jimp");
4
+// const request = require('request');
5
+const iconv = require("iconv-lite");
6
+// const Deasync = require("deasync");
7
+const Buffer = require('buffer').Buffer
8
+
9
+var exchange_text_with_times = exports.exchange_text_with_times = function exchange_text_with_times(text, times, options){
10
+    times = (times === undefined ? 1 : times);
11
+    var bytes = new BufferHelper();
12
+    var text_buffer = exchange_text(text, options)
13
+    for(var i=0;i<times;i++){
14
+        bytes.concat(text_buffer);
15
+    }
16
+    return bytes.toBuffer()
17
+}
18
+
19
+var exchange_text = exports.exchange_text = function exchange_text(text, options){
20
+    options = options || {
21
+        beep: false,
22
+        cut: true,
23
+        tailingLine: true,
24
+        encoding: 'UTF8',
25
+    }
26
+    // 初始化打印机
27
+    var init_printer_bytes = new Buffer([27, 64]);
28
+    // 读取设备状态
29
+    var check_state_bytes = new Buffer([29, 153]);
30
+    // 返回字符 1D 99 XX FF
31
+    // 其中XX的每位表示的意义
32
+    // 0  0:有纸 1:缺纸
33
+    // 1  0:合盖 1:开盖
34
+    // 2  0:温度正常 1:机芯过热
35
+    // 3  0:电量正常 1:电量低
36
+    // 4  0:未打印状态 1:打印状态
37
+    // 5  未定义
38
+    // 6  未定义
39
+    // 7  未定义
40
+
41
+    // 正常打印模式
42
+    var init_bytes = new Buffer([27, 33, 0]);
43
+    // 放大字体
44
+    //<M></M>      中号字体(2倍高)
45
+    //<D></D>      中号字体(2倍宽)
46
+    //<B></B>      大号字体(2倍高宽)
47
+    //<C></C>      居中
48
+    //<CM></CM>    中号字体居中
49
+    //<CD></CD>    中号字体居中
50
+    //<CB></CB>    大号字体居中
51
+    //<QR></QR>  二维码图片地址
52
+    //<QRI></QRI>  二维码图片地址
53
+    //<PCN></PCN>  公众号
54
+    // var m_start_bytes       = new Buffer([27, 50, 27, 97, 0, 29, 33, 1]);
55
+    // var m_end_bytes         = new Buffer([29, 33, 0]);
56
+    // var b_start_bytes       = new Buffer([27, 50, 27, 97, 0, 29, 33, 17]);
57
+    // var b_end_bytes         = new Buffer([29, 33, 0]);
58
+    var c_start_bytes       = new Buffer([27, 97, 1]);
59
+    var c_end_bytes         = new Buffer([]); // [ 27, 97, 0 ];
60
+    // var d_start_bytes       = new Buffer([27, 50, 27, 97, 0, 29, 33, 16]);
61
+    // var d_end_bytes         = new Buffer([29, 33, 0]);
62
+    // var cm_start_bytes      = new Buffer([27, 50, 29, 33, 1, 27, 97, 1]);
63
+    // var cm_end_bytes        = new Buffer([29, 33, 0]);
64
+    // var cd_start_bytes      = new Buffer([27, 50, 29, 33, 16, 27, 97, 1]);
65
+    // var cd_end_bytes        = new Buffer([29, 33, 0]);
66
+    // var cb_start_bytes      = new Buffer([27, 50, 29, 33, 17, 27, 97, 1]);
67
+    // var cb_end_bytes        = new Buffer([29, 33, 0]);
68
+    var reset_bytes         = new Buffer([27, 97, 0, 29, 33, 0, 27, 50]);
69
+    //针对针式调整后
70
+    var m_start_bytes       = new Buffer([27, 33, 16, 28, 33, 8]);
71
+    var m_end_bytes         = new Buffer([27, 33, 0, 28, 33, 0]);
72
+    var b_start_bytes       = new Buffer([27, 33, 48, 28, 33, 12]);
73
+    var b_end_bytes         = new Buffer([27, 33, 0, 28, 33, 0]);
74
+    var cm_start_bytes      = new Buffer([27, 97, 1, 27, 33, 16, 28, 33, 8]);
75
+    var cm_end_bytes        = new Buffer([27, 33, 0, 28, 33, 0]);
76
+    var cb_start_bytes      = new Buffer([27, 97, 1, 27, 33, 48, 28, 33, 12]);
77
+    var cb_end_bytes        = new Buffer([27, 33, 0, 28, 33, 0]);
78
+    var cd_start_bytes      = new Buffer([27, 97, 1, 27, 33, 32, 28, 33, 4]);
79
+    var cd_end_bytes        = new Buffer([27, 33, 0, 28, 33, 0]);
80
+    var d_start_bytes       = new Buffer([27, 33, 32, 28, 33, 4]);
81
+    var d_end_bytes         = new Buffer([27, 33, 0, 28, 33, 0]);
82
+
83
+    // 居中
84
+    var align_center_bytes  = new Buffer([27, 97, 1]);
85
+    var align_left_bytes    = new Buffer([27, 97, 0]);
86
+    // 设置行间距 默认值为8即1mm
87
+    var default_space_bytes = new Buffer([27, 50]);
88
+    var none_space_bytes    = new Buffer([27, 51, 0]);
89
+    var b_space_bytes       = new Buffer([27, 51, 120]);
90
+    // 切纸
91
+    var cut_bytes           = new Buffer([27, 105]);
92
+    // 弹钱箱
93
+    var moneybox_bytes      = new Buffer([27, 112, 7]);
94
+    // 蜂鸣 { 27, 66, 次数, 时长 * 50ms }
95
+    var beep_bytes          = new Buffer([ 27, 66, 3, 2 ])
96
+
97
+    var bytes = new BufferHelper();
98
+    bytes.concat(init_printer_bytes);
99
+    bytes.concat(default_space_bytes);
100
+    var temp = "";
101
+    for (var i = 0; i < text.length; i++)
102
+    {
103
+        var ch = text[i];
104
+        var index;
105
+        if (ch == '<')
106
+        {
107
+            bytes.concat(iconv.encode(temp, options.encoding));
108
+            temp = "";
109
+            if (text.substring(i, i+3) == "<M>")
110
+            {
111
+                bytes.concat(m_start_bytes); i += 2;
112
+            }
113
+            else if (text.substring(i, i+4) == "</M>")
114
+            {
115
+                bytes.concat(m_end_bytes); i += 3;
116
+            }
117
+            else if (text.substring(i, i+3) == "<B>")
118
+            {
119
+                bytes.concat(b_start_bytes); i += 2;
120
+            }
121
+            else if (text.substring(i, i+4) == "</B>")
122
+            {
123
+                bytes.concat(b_end_bytes); i += 3;
124
+            }
125
+            else if (text.substring(i, i+3) == "<D>")
126
+            {
127
+                bytes.concat(d_start_bytes); i += 2;
128
+            }
129
+            else if (text.substring(i, i+4) == "</D>")
130
+            {
131
+                bytes.concat(d_end_bytes); i += 3;
132
+            }
133
+            else if (text.substring(i, i+3) == "<C>")
134
+            {
135
+                bytes.concat(c_start_bytes); i += 2;
136
+            }
137
+            else if (text.substring(i, i+4) == "</C>")
138
+            {
139
+                bytes.concat(c_end_bytes); i += 3;
140
+            }
141
+            else if (text.substring(i, i+4) == "<CM>")
142
+            {
143
+                bytes.concat(cm_start_bytes); i += 3;
144
+            }
145
+            else if (text.substring(i, i+5) == "</CM>")
146
+            {
147
+                bytes.concat(cm_end_bytes); i += 4;
148
+            }
149
+            else if (text.substring(i, i+4) == "<CD>")
150
+            {
151
+                bytes.concat(cd_start_bytes); i += 3;
152
+            }
153
+            else if (text.substring(i, i+5) == "</CD>")
154
+            {
155
+                bytes.concat(cd_end_bytes); i += 4;
156
+            }
157
+            else if (text.substring(i, i+4) == "<CB>")
158
+            {
159
+                bytes.concat(cb_start_bytes); i += 3;
160
+            }
161
+            else if (text.substring(i, i+5) == "</CB>")
162
+            {
163
+                bytes.concat(cb_end_bytes); i += 4;
164
+            }
165
+            else if (text.substring(i, i+4) == "<QR>")
166
+            {
167
+                index = text.indexOf("</QR>", i + 4);
168
+                if (index != -1)
169
+                {
170
+                    var url = text.substring(i + 4, index);
171
+                    bytes.concat(align_center_bytes);
172
+                    bytes.concat(none_space_bytes);
173
+                    bytes.concat(change_image_url_to_bytes(url));
174
+                    bytes.concat(default_space_bytes);
175
+                    bytes.concat(align_left_bytes);
176
+                    i = index + 4;
177
+                }
178
+                else
179
+                {
180
+                    temp = temp + ch;
181
+                }
182
+            }
183
+            else if (text.substring(i, i+5) == "<QRI>")
184
+            {
185
+                index = text.indexOf("</QRI>", i + 5);
186
+                if (index != -1)
187
+                {
188
+                    var url = text.substring(i + 5, index);
189
+                    bytes.concat(align_center_bytes);
190
+                    bytes.concat(none_space_bytes);
191
+                    bytes.concat(change_image_url_to_bytes(url));
192
+                    bytes.concat(default_space_bytes);
193
+                    bytes.concat(align_left_bytes);
194
+                    i = index + 5;
195
+                }
196
+                else
197
+                {
198
+                    temp = temp + ch;
199
+                }
200
+            }
201
+            else if (text.substring(i, i+5) == "<PCN>")
202
+            {
203
+                index = text.indexOf("</PCN>", i + 5);
204
+                if (index != -1)
205
+                {
206
+                    var url = "http://open.weixin.qq.com/qr/code/?username=" + text.substring(i + 5, index);
207
+                    bytes.concat(align_center_bytes);
208
+                    bytes.concat(none_space_bytes);
209
+                    bytes.concat(change_image_url_to_bytes(url));
210
+                    bytes.concat(default_space_bytes);
211
+                    bytes.concat(align_left_bytes);
212
+                    i = index + 5;
213
+                }
214
+                else
215
+                {
216
+                    temp = temp + ch;
217
+                }
218
+            }
219
+        }
220
+        else if(ch == "\n"){
221
+            temp = temp + ch;
222
+            bytes.concat(iconv.encode(temp, options.encoding));
223
+            bytes.concat(reset_bytes);
224
+            temp = "";
225
+        }
226
+        else
227
+        {
228
+            temp = temp + ch;
229
+        }
230
+    }
231
+    if (temp.length > 0)
232
+    {
233
+        bytes.concat(iconv.encode(temp, options.encoding));
234
+    }
235
+    var line_bytes = new Buffer([10, 10, 10, 10, 10])
236
+    if (options.tailingLine){
237
+        bytes.concat(line_bytes);
238
+    }
239
+    if (options.cut){
240
+        bytes.concat(cut_bytes);
241
+    }
242
+    if (options.beep){
243
+        bytes.concat(beep_bytes)
244
+    }
245
+    return bytes.toBuffer();
246
+}
247
+
248
+var change_image_url_to_bytes = exports.change_image_url_to_bytes = function change_image_url_to_bytes(url, options){
249
+    options = options||{
250
+        encoding: 'UTF8'
251
+    };
252
+    var buffer = new Buffer(iconv.encode(url, options.encoding));
253
+
254
+    // var buffer = new Buffer(0);
255
+    // var sync = true;
256
+    // Jimp.read(url, function (err, img) {
257
+    //     if(err) {
258
+    //         console.error(err.message)
259
+    //     }else{
260
+    //         img.resize(250, 250).quality(60).greyscale();
261
+    //         buffer = exchange_image(img, 130);
262
+    //     }
263
+    //     sync = false
264
+    // });
265
+    // while(sync){ Deasync.sleep(100)}
266
+    return buffer;
267
+}
268
+
269
+// var download_image = exports.download_image = function download_image(url, path){
270
+//     try{
271
+//         request(url).pipe(fs.createWriteStream(path));
272
+//         return true
273
+//     }catch(e){
274
+//         return false
275
+//     }
276
+// }
277
+
278
+// var exchange_image = exports.exchange_image = function exchange_image(img, threshold){
279
+//     var hex;
280
+//     var nl = img.bitmap.width % 256;
281
+//     var nh = parseInt(img.bitmap.width / 256);
282
+//     var bytes = new BufferHelper();
283
+//     // data
284
+//     var data = new Buffer([0, 0, 0]);
285
+//     var line = new Buffer([10]);
286
+//     for (var i = 0; i < parseInt(img.bitmap.height / 24) + 1; i++)
287
+//     {
288
+//         // ESC * m nL nH 点阵图
289
+//         var header = new Buffer([27, 42, 33, nl, nh]);
290
+//         bytes.concat(header);
291
+//         for (var j = 0; j < img.bitmap.width; j++)
292
+//         {
293
+//             data[0] = data[1] = data[2] = 0; // Clear to Zero.
294
+//             for (var k = 0; k < 24; k++)
295
+//             {
296
+//                 if (((i * 24) + k) < img.bitmap.height)   // if within the BMP size
297
+//                 {
298
+//                     hex = img.getPixelColor(j, (i * 24) + k);
299
+//                     if (Jimp.intToRGBA(hex).r <= threshold)
300
+//                     {
301
+//                         data[parseInt(k / 8)] += (128 >> (k % 8));
302
+//                     }
303
+//                 }
304
+//             }
305
+//             var dit = new Buffer([data[0], data[1], data[2]])
306
+//             bytes.concat(dit);
307
+//         }
308
+//         bytes.concat(line);
309
+//     } // data
310
+//     return bytes.toBuffer();
311
+// }

+ 45
- 0
package-lock.json View File

@@ -0,0 +1,45 @@
1
+{
2
+  "name": "escpos-printer-toolkit",
3
+  "version": "1.0.6",
4
+  "lockfileVersion": 1,
5
+  "requires": true,
6
+  "dependencies": {
7
+    "base64-js": {
8
+      "version": "1.2.1",
9
+      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
10
+      "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw=="
11
+    },
12
+    "buffer": {
13
+      "version": "5.0.7",
14
+      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.0.7.tgz",
15
+      "integrity": "sha512-NeeHXWh5pCbPQCt2/6rLvXqapZfVsqw/YgRgaHpT3H9Uzgs+S0lSg5SQzouIuDvcmlQRqBe8hOO2scKCu3cxrg==",
16
+      "requires": {
17
+        "base64-js": "1.2.1",
18
+        "ieee754": "1.1.8"
19
+      }
20
+    },
21
+    "emitter-component": {
22
+      "version": "1.1.1",
23
+      "resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz",
24
+      "integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY="
25
+    },
26
+    "iconv-lite": {
27
+      "version": "0.4.19",
28
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
29
+      "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
30
+    },
31
+    "ieee754": {
32
+      "version": "1.1.8",
33
+      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
34
+      "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q="
35
+    },
36
+    "stream": {
37
+      "version": "0.0.2",
38
+      "resolved": "https://registry.npmjs.org/stream/-/stream-0.0.2.tgz",
39
+      "integrity": "sha1-f1Nj8Ff2WSxVlfALyAon9c7B8O8=",
40
+      "requires": {
41
+        "emitter-component": "1.1.1"
42
+      }
43
+    }
44
+  }
45
+}

+ 28
- 0
package.json View File

@@ -0,0 +1,28 @@
1
+{
2
+  "name": "escpos-printer-toolkit",
3
+  "version": "1.0.8",
4
+  "description": "点单宝打印机指令定义",
5
+  "main": "index.js",
6
+  "scripts": {
7
+    "test": "echo \"Error: no test specified\" && exit 1"
8
+  },
9
+  "repository": {
10
+    "type": "git",
11
+    "url": "git+ssh://git@github.com/wanxsb/escpos-printer-toolkit.git"
12
+  },
13
+  "keywords": [
14
+    "printer",
15
+    "esc/pos"
16
+  ],
17
+  "author": "shenzhen candongli corp.",
18
+  "license": "ISC",
19
+  "bugs": {
20
+    "url": "https://github.com/wanxsb/escpos-printer-toolkit/issues"
21
+  },
22
+  "homepage": "https://github.com/wanxsb/escpos-printer-toolkit#readme",
23
+  "dependencies": {
24
+    "buffer": "^5.0.7",
25
+    "iconv-lite": "^0.4.19",
26
+    "stream": "0.0.2"
27
+  }
28
+}

Loading…
Cancel
Save