Browse Source

A8型号打印文本完成

周素华 10 months ago
parent
commit
d7e5f90c63

+ 23 - 0
android/app/src/main/java/io/flutter/plugins/BluetoothPlugin.java

@@ -170,6 +170,10 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
170 170
                 Log.d("ble", "startBluetoothPrint :" + methodCall.arguments);
171 171
                 startBluetoothPrintBitMap(methodCall, result);
172 172
                 break;
173
+            case "startBluetoothPrintText":
174
+                Log.d("ble", "startBluetoothPrintText :" + methodCall.arguments);
175
+                startBluetoothPrintText(methodCall, result);
176
+                break;
173 177
             case "startBluetoothPrintBarCode":
174 178
                 Log.d("ble", "startBluetoothPrintBarCode :" + methodCall.arguments);
175 179
                 startBluetoothPrintBarCode(methodCall, result);
@@ -333,6 +337,25 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
333 337
         }
334 338
     }
335 339
 
340
+    void startBluetoothPrintText(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
341
+
342
+        ArrayList<String> textList = (ArrayList<String>) methodCall.arguments;
343
+//
344
+//        Log.d("ble", "imageByte:" + imageByte);
345
+//        Bitmap bitmap = Bytes2Bimap(imageByte);
346
+
347
+        BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(itemPosition.getDeviceHardwareAddress());
348
+        if (ActivityCompat.checkSelfPermission(_applicationContext, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
349
+            return;
350
+        }
351
+        BlueDeviceInfo blueDeviceInfo = new BlueDeviceInfo(bluetoothDevice.getName(), bluetoothDevice.getAddress(), itemPosition.getConnectState());
352
+        if(blueDeviceInfo.getDeviceName().contains("BTP")) {
353
+//            BTPPrintUtil.printBitMap(bitmap, blueDeviceInfo.getDeviceName(), result);
354
+        } else {
355
+            PrintUtil.printText(textList, result);
356
+        }
357
+    }
358
+
336 359
     void startBluetoothPrintBarCode(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
337 360
 
338 361
         byte[] imageByte = (byte[]) methodCall.arguments;

+ 192 - 0
android/app/src/main/java/io/flutter/plugins/utils/PrintUtil.java

@@ -297,4 +297,196 @@ public class PrintUtil {
297 297
     }
298 298
 
299 299
 
300
+    public static void printText(ArrayList<String> textList, @NonNull MethodChannel.Result result) {
301
+        // 检查是否连接了打印机
302
+        if (PrintUtil.isConnection() != 0) {
303
+            result.success(false);
304
+            return;
305
+        }
306
+
307
+        // 重置错误和取消打印状态
308
+        //重置错误状态变量
309
+        final boolean[] isError = {false};
310
+        //重置取消打印状态变量
311
+        final boolean[] isCancel = {false};
312
+        // 初始化打印数据
313
+        ArrayList<String> jsonList = new ArrayList<>();
314
+        ArrayList<String> infoList = new ArrayList<>();
315
+
316
+        // 在每次打印任务前初始化生成的打印数据页数
317
+        int generatedPrintDataPageCount = 0;
318
+        // 设置打印的总页数和份数
319
+        int pageCount = 1;
320
+        int quantity = 1;
321
+        int totalQuantity = pageCount * quantity;
322
+        //setTotalQuantityOfPrints已废弃,使用方法含义更明确的setTotalPrintQuantity
323
+        PrintUtil.getInstance().setTotalPrintQuantity(totalQuantity);
324
+        // 打印参数设置
325
+        /*
326
+         * 参数1:打印浓度 ,参数2:纸张类型 参数3:打印模式
327
+         * 打印浓度 B50/B50W/T6/T7/T8 建议设置6或8,Z401/B32建议设置8,B3S/B21/B203/B1建议设置3
328
+         */
329
+        PrintUtil.getInstance().startPrintJob(3, 3, 1, new PrintCallback() {
330
+            @Override
331
+            public void onProgress(int pageIndex, int quantityIndex, HashMap<String, Object> hashMap) {
332
+                // 更新打印进度
333
+                String progressMessage = "打印进度:已打印到第" + pageIndex + "页,第" + quantityIndex + "份";
334
+                Log.d("ble", "测试:" + progressMessage);
335
+
336
+                // 处理打印完成情况
337
+                if (pageIndex == pageCount && quantityIndex == quantity) {
338
+                    Log.d("ble", "测试:onProgress: 结束打印");
339
+                    //endJob,使用方法含义更明确的endPrintJob
340
+                    if (PrintUtil.getInstance().endPrintJob()) {
341
+                        Log.d("ble", "结束打印成功");
342
+                    } else {
343
+                        Log.d("ble", "结束打印失败");
344
+                    }
345
+                    result.success(true);
346
+                }
347
+            }
348
+
349
+
350
+            @Override
351
+            public void onError(int i) {
352
+
353
+            }
354
+
355
+
356
+            @Override
357
+            public void onError(int errorCode, int printState) {
358
+                Log.d("ble", "测试:onError");
359
+                isError[0] = true;
360
+                result.success(false);
361
+            }
362
+
363
+            @Override
364
+            public void onCancelJob(boolean isSuccess) {
365
+                //取消打印成功回调
366
+                isCancel[0] = true;
367
+            }
368
+
369
+            /**
370
+             * SDK缓存空闲回调,可以在此处传入打印数据
371
+             *
372
+             * @param pageIndex 当前回调函数处理下一页的打印索引
373
+             * @param bufferSize 缓存空间的大小
374
+             */
375
+            @Override
376
+            public void onBufferFree(int pageIndex, int bufferSize) {
377
+                // 如果出现错误、已取消打印,或 pageIndex 超过总页数,则返回
378
+                if (isError[0] || isCancel[0] || pageIndex > pageCount) {
379
+                    return;
380
+                }
381
+
382
+                Log.d(TAG, "测试-空闲数据回调-数据生成判断-总页数 " + pageCount + ",已生成页数:" + generatedPrintDataPageCount + ",空闲回调数据长度:" + bufferSize);
383
+                // 生成打印数据
384
+                generatePrintDataIfNeeded(textList, bufferSize, generatedPrintDataPageCount, pageCount, jsonList, infoList, quantity);
385
+            }
386
+        });
387
+    }
388
+
389
+
390
+    /**
391
+     * 根据需要生成打印数据,确保不超过总页数限制。
392
+     *
393
+     * @param bufferSize 当前缓存空间的大小。
394
+     */
395
+    private static void generatePrintDataIfNeeded(ArrayList<String> textList,int bufferSize, int generatedPrintDataPageCount, int pageCount, ArrayList<String> jsonList, ArrayList<String> infoList, int quantity) {
396
+        // 如果已生成的打印数据页数小于总页数,则继续生成
397
+        if (generatedPrintDataPageCount < pageCount) {
398
+            // 计算本次要生成的数据长度,以免超过总页数
399
+            int commitDataLength = Math.min((pageCount - generatedPrintDataPageCount), bufferSize);
400
+            // 生成数据
401
+            generateMultiPagePrintData(textList,generatedPrintDataPageCount, generatedPrintDataPageCount + commitDataLength, jsonList, infoList, quantity);
402
+            // 提交打印数据
403
+            PrintUtil.getInstance().commitData(jsonList.subList(generatedPrintDataPageCount, generatedPrintDataPageCount + commitDataLength), infoList.subList(generatedPrintDataPageCount, generatedPrintDataPageCount + commitDataLength));
404
+            // 更新已生成的打印数据页数
405
+            generatedPrintDataPageCount += commitDataLength;
406
+        }
407
+    }
408
+
409
+    /**
410
+     * 生成多页的打印数据。
411
+     *
412
+     * @param index      起始索引,生成数据的起始页。
413
+     * @param cycleIndex 结束索引,生成数据的结束页。
414
+     */
415
+    private static void generateMultiPagePrintData(ArrayList<String> textList, int index, int cycleIndex, ArrayList<String> jsonList, ArrayList<String> infoList, int quantity) {
416
+
417
+
418
+        while (index < cycleIndex) {
419
+
420
+            // 设置打印参数
421
+            float width = 70;
422
+            float height = 72.5F;
423
+            int orientation = 0;
424
+            float marginX = 2.0F;
425
+            float marginY = 10.0F;
426
+            //矩形框类型
427
+            float rectangleWidth = width - marginX * 2;
428
+            float rectangleHeight = height - marginY * 2;
429
+            float lineWidth = 0.5F;
430
+            //1.圆 2.椭圆 3.矩形 4.圆角矩形
431
+            int graphType = 3;
432
+            float lineHeight = rectangleHeight / 6.0F;
433
+//            float titleWidth = rectangleWidth * 2 / 5.0F;
434
+//            float contentWidth = rectangleWidth * 3 / 5.0F;
435
+
436
+            float titleWidth = rectangleWidth / 2.0F;
437
+            float contentWidth = rectangleWidth / 2.0F;
438
+
439
+            float fontSize = 3.0F;
440
+            // 设置初始偏移量
441
+            float offsetY = 0F;
442
+            float offsetX = 0F;
443
+            // 计算绘制线条的 y 坐标
444
+            float secondLineY = marginY + lineHeight * 2 - lineWidth + offsetY;
445
+            float thirdLineY = marginY + lineHeight * 3 - lineWidth + offsetY;
446
+            float fourthLineY = marginY + lineHeight * 4 - lineWidth + offsetY;
447
+            float fiveLineY = marginY + lineHeight * 5 - lineWidth + offsetY;
448
+            List<String> fonts = new ArrayList<>();
449
+            fonts.add("ZT008.ttf");
450
+            // 设置画布大小
451
+            PrintUtil.getInstance().drawEmptyLabel(width, height, orientation, fonts);
452
+
453
+            int textAlignHorizontal = 0; // 左对齐
454
+            // 绘制小标题
455
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + offsetX, marginY + offsetY, titleWidth - marginX * 3, lineHeight, textList.get(0), "宋体", fontSize, 0, textAlignHorizontal, 1, 6, 0, 1, new boolean[]{false, false, false, false});
456
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + titleWidth + offsetX, marginY + offsetY, contentWidth - marginX * 3, lineHeight, textList.get(1), "宋体", fontSize, 0, 0, 1, 6, 0, 1, new boolean[]{false, false, false, false});
457
+
458
+
459
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + offsetX, marginY + lineHeight - lineWidth + offsetY, rectangleWidth - marginX * 3, lineHeight, textList.get(2), "宋体", fontSize, 0, textAlignHorizontal, 1, 6, 0, 1, new boolean[]{false, false, false, false});
460
+
461
+
462
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + offsetX, secondLineY, rectangleWidth - marginX * 3, lineHeight, textList.get(3), "宋体", fontSize, 0, textAlignHorizontal, 1, 6, 0, 1, new boolean[]{false, false, false, false});
463
+
464
+
465
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + offsetX, thirdLineY, titleWidth - marginX * 3, lineHeight, textList.get(4), "宋体", fontSize, 0, textAlignHorizontal, 1, 6, 0, 1, new boolean[]{false, false, false, false});
466
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + titleWidth + offsetX, thirdLineY, contentWidth - marginX * 3, lineHeight, textList.get(5), "宋体", fontSize, 0, 0, 1, 6, 0, 1, new boolean[]{false, false, false, false});
467
+
468
+
469
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + offsetX, fourthLineY, titleWidth - marginX * 3, lineHeight, textList.get(6), "宋体", fontSize, 0, textAlignHorizontal, 1, 6, 0, 1, new boolean[]{false, false, false, false});
470
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + titleWidth + offsetX, fourthLineY, contentWidth - marginX * 3, lineHeight, textList.get(7), "宋体", fontSize, 0, 0, 1, 6, 0, 1, new boolean[]{false, false, false, false});
471
+
472
+
473
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + offsetX, fiveLineY, titleWidth - marginX * 3, lineHeight, textList.get(8), "宋体", fontSize, 0, textAlignHorizontal, 1, 6, 0, 1, new boolean[]{false, false, false, false});
474
+            PrintUtil.getInstance().drawLabelText(marginX * 2.5f + titleWidth + offsetX, fiveLineY, contentWidth - marginX * 3, lineHeight, textList.get(9), "宋体", fontSize, 0, 0, 1, 6, 0, 1, new boolean[]{false, false, false, false});
475
+
476
+            //生成打印数据
477
+            byte[] jsonByte = PrintUtil.getInstance().generateLabelJson();
478
+
479
+            //转换为jsonStr
480
+            String jsonStr = new String(jsonByte);
481
+
482
+
483
+            jsonList.add(jsonStr);
484
+            //除B32/Z401/T8的printMultiple为11.81,其他的为8
485
+            String jsonInfo = "{  " + "\"printerImageProcessingInfo\": " + "{    " + "\"orientation\":" + orientation + "," + "   \"margin\": [      0,      0,      0,      0    ], " + "   \"printQuantity\": " + quantity + ",  " + "  \"horizontalOffset\": 0,  " + "  \"verticalOffset\": 0,  " + "  \"width\":" + width + "," + "   \"height\":" + height + "," + "\"printMultiple\":" + 8 + "," + "  \"epc\": \"\"  }}";
486
+            infoList.add(jsonInfo);
487
+
488
+            index++;
489
+        }
490
+    }
491
+
300 492
 }

+ 4 - 2
lib/page/print/print_page.dart

@@ -20,9 +20,10 @@ import 'dart:ui' as ui;
20 20
 
21 21
 class PrintPageArgs {
22 22
   /// 二维码数据
23
-  Uint8List? bytes;
23
+  Uint8List bytes;
24
+  List<String> textList;
24 25
 
25
-  PrintPageArgs({this.bytes});
26
+  PrintPageArgs({required this.bytes, required this.textList});
26 27
 
27 28
   @override
28 29
   String toString() {
@@ -99,6 +100,7 @@ class _PrintPageState extends BaseLifecycleState<PrintPage> {
99 100
 
100 101
     MyNavigator.showLoading(msg: '打印中...');
101 102
     await PrintService.startBluetoothPrintBitMap(smallUint8List!);
103
+    await PrintService.startBluetoothPrintText(widget.args.textList);
102 104
     MyNavigator.dismiss();
103 105
     MyNavigator.showToast('打印成功');
104 106
   }

+ 12 - 1
lib/page/sample_task/reap_sample_detail/reap_sample_basic_detail_page.dart

@@ -7,6 +7,8 @@ import 'package:card_swiper/card_swiper.dart';
7 7
 import 'package:flutter/material.dart';
8 8
 import 'package:image_gallery_saver/image_gallery_saver.dart';
9 9
 import 'package:lszlgl/main.dart';
10
+import 'package:lszlgl/page/print/print_page.dart';
11
+import 'package:lszlgl/service/print_service.dart';
10 12
 import 'package:lszlgl/utils/input_formatter.dart';
11 13
 import 'package:lszlgl/utils/location_utils.dart';
12 14
 import 'package:lszlgl/widget/button.dart';
@@ -15,6 +17,7 @@ import '../../../config/colors.dart';
15 17
 import '../../../model/rsp/dict_rsp.dart';
16 18
 import '../../../model/rsp/sample_task_rsp.dart';
17 19
 import '../../../network/my_api.dart';
20
+import '../../../service/dict_service.dart';
18 21
 import '../../../service/user_service.dart';
19 22
 import '../../../utils/file_utils.dart';
20 23
 import '../../../widget/card_item.dart';
@@ -359,7 +362,7 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
359 362
             ),
360 363
             Row(
361 364
               children: [
362
-                const Expanded(child: MyButton('打印')),
365
+                Expanded(child: MyButton('打印', onTap: () => printPic(picInfo.name))),
363 366
                 const SizedBox(width: 16),
364 367
                 Expanded(child: MyButton('保存图片', onTap: () => savePic(picInfo.name))),
365 368
               ],
@@ -370,6 +373,14 @@ class _ReapSampleBasicDetailPageState extends BaseLifecycleState<ReapSampleBasic
370 373
     );
371 374
   }
372 375
 
376
+  Future<void> printPic(String? name) async {
377
+
378
+    Uint8List? bytes = await FileUtils.getBitmapFromContext(ewmKey.currentContext);
379
+    List<String> textList = PrintService.getPrintTextListWithSampleTaskItem(data);
380
+    var args = PrintPageArgs(bytes: bytes!, textList: textList);
381
+    await MyRouter.startPrint(args);
382
+  }
383
+
373 384
   void savePic(String? name) async {
374 385
     MyNavigator.showLoading(msg: '保存中...');
375 386
     Uint8List? bytes = await FileUtils.getBitmapFromContext(ewmKey.currentContext);

+ 5 - 3
lib/page/sample_task/reap_sample_detail/reap_sample_task_page.dart

@@ -19,6 +19,7 @@ import 'package:lszlgl/page/signature/signature_page.dart';
19 19
 import '../../../base/base_vm.dart';
20 20
 import '../../../main.dart';
21 21
 import '../../../network/my_api.dart';
22
+import '../../../service/print_service.dart';
22 23
 import '../../../utils/file_utils.dart';
23 24
 import '../../../widget/button.dart';
24 25
 import '../../../widget/page_widget.dart';
@@ -216,10 +217,11 @@ class _ReapSampleTaskPageState extends BaseLifecycleState<ReapSampleTaskPage> wi
216 217
 
217 218
   Future<void> printPic(String? name) async {
218 219
 
220
+    SampleTaskItem? req = pageStatus.value.data;
219 221
     Uint8List? bytes = await FileUtils.getBitmapFromContext(ewmKey.currentContext);
220
-
221
-    var args = PrintPageArgs(bytes: bytes);
222
-    await MyRouter.startPrint(args: args);
222
+    List<String> textList = PrintService.getPrintTextListWithSampleTaskItem(req);
223
+    var args = PrintPageArgs(bytes: bytes!, textList: textList);
224
+    await MyRouter.startPrint(args);
223 225
   }
224 226
 
225 227
   void savePic(String? name) async {

+ 9 - 0
lib/plugin/bluetooth_plugin.dart

@@ -91,6 +91,15 @@ class BluetoothPlugin {
91 91
   }
92 92
 
93 93
   //开始打印
94
+  Future<bool> startBluetoothPrintText(List<String> textList) async {
95
+
96
+    if (Platform.isIOS) {
97
+      return false;
98
+    }
99
+    return _channel.invokeMethod('startBluetoothPrintText', textList).then<bool>((d) => d);
100
+  }
101
+
102
+  //开始打印
94 103
   Future<bool> startBluetoothPrintBarCodeWithText(String barCode, String text) async {
95 104
 
96 105
     if (Platform.isIOS) {

+ 2 - 2
lib/router/my_router.dart

@@ -117,8 +117,8 @@ class MyRouter {
117 117
   }
118 118
 
119 119
   /// 打印任务
120
-  static Future<dynamic> startPrint({PrintPageArgs? args}) {
121
-    return MyNavigator.push(rPrintPage, args: args ?? PrintPageArgs());
120
+  static Future<dynamic> startPrint(PrintPageArgs args) {
121
+    return MyNavigator.push(rPrintPage, args: args);
122 122
   }
123 123
 
124 124
   /// 打印任务

+ 28 - 0
lib/service/print_service.dart

@@ -6,11 +6,14 @@ import 'package:device_info_plus/device_info_plus.dart';
6 6
 import 'package:lszlgl/utils/permission_utils.dart';
7 7
 import 'package:permission_handler/permission_handler.dart';
8 8
 
9
+import '../model/rsp/sample_task_rsp.dart';
9 10
 import '../plugin/bluetooth_plugin.dart';
10 11
 import '../router/my_navigator.dart';
11 12
 import 'package:flutter/material.dart';
12 13
 import 'package:flutter/services.dart';
13 14
 
15
+import 'dict_service.dart';
16
+
14 17
 class PrintService {
15 18
   PrintService._();
16 19
 
@@ -146,6 +149,18 @@ class PrintService {
146 149
     }
147 150
   }
148 151
 
152
+  //开始打印文字
153
+  static Future<bool> startBluetoothPrintText(List<String> textList) async {
154
+
155
+    //
156
+
157
+    if(await canExecAction()) {
158
+      return await BluetoothPlugin.instance.startBluetoothPrintText(textList);
159
+    } else {
160
+      return false;
161
+    }
162
+  }
163
+
149 164
   //开始打印二维码和文本
150 165
   static Future<bool> startBluetoothPrintBarCodeWithText(String barCode, String text) async {
151 166
 
@@ -156,6 +171,19 @@ class PrintService {
156 171
     }
157 172
   }
158 173
 
174
+  static List<String> getPrintTextListWithSampleTaskItem(SampleTaskItem? data) {
175
+
176
+    List<String> textList = [];
177
+    textList.addAll(["采样品种:${data?.cypzName ?? ''}","种植品种:${data?.jtpzmc ?? ''}"]);
178
+    textList.addAll(["${data?.shengXzqhName ?? ''}${data?.shiXzqhName ?? ''}${data?.quXzqhName ?? ''}${data?.xiangXzqhName ?? ''}${data?.cunXzqhName ?? ''}"]);
179
+    textList.addAll(["扦样人员:${data?.dgryName ?? ''}"]);
180
+    textList.addAll(["收获时间:${data?.shsj ?? ''}","扦样时间:${data?.qysj ?? ''}"]);
181
+    textList.addAll(["扦样数量:${data?.qysl ?? ''}kg","样品层级:${DictService.getLabel(DictType.ypdj, value: data?.ypdj)}"]);
182
+    textList.addAll(["种植面积:${data?.zzmj ?? ''}亩","代表数量:${(data?.qydbsl ?? '').toString()}公斤"]);
183
+
184
+    return textList;
185
+  }
186
+
159 187
 
160 188
 
161 189