printer_data_utils.dart 5.0 KB
Newer Older
houziyu's avatar
houziyu committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
import 'package:blue_thermal_printer/blue_thermal_printer.dart';

class PrintData {
  static double printPageWidth = 50; // 打印纸宽度 50mm
  static double printTextWidth = 3; // 打印文字的宽度 3mm
  static double printBaseUnitValue = 0.125; // 打印基准值 0.125mm

  /// 初始化打印机
  static initPrinter() {
    return PrinterCommands.initPrinter;
  }

  /// 设置左边距
  static printMarginLeft(int left) {
    return PrinterCommands.printMarginLeft(left: left);
  }

  /// 空行
  static printNewLine() {
    return PrinterCommands.FEED_LINE;
  }

  /// 打印文字
  /// message 文本
  /// size 文字放大倍数
  /// bold 是否加粗
  /// charset 文本编码
  /// space 文本间隙
  static printText(String message,
      {int size = 1,
      bool bold = false,
      CHARSET charset = CHARSET.GBK,
      int space = 0}) {
    List<int> data = [];
    var textList = splitText(message, size, space);
    for (var value in textList) {
      data.addAll(_printLineText(value, size, bold, charset, space));
    }
    return data;
  }

  /// 打印一行
  static List<int> _printLineText(
      String text, int size, bool bold, CHARSET charset, int space) {
    List<int> data = [];
    // 左边距 = 打印纸宽度 - 文字宽度 ~/ 2
    var left = getLeftMargin(text, size, space);
    var textLeftMargin = PrinterCommands.printMarginLeft(left: left);
    var textBold = PrinterCommands.bold(bold: bold);
    var textSize = PrinterCommands.fontSizeSetBig(size: size);
    var textSpace = PrinterCommands.setCharHSpace(charSpace: space);
    List<int> content = [];
    if (charset == CHARSET.GBK) {
      content.addAll(gbk.encode(text));
    } else {
      content.addAll(utf8.encode(text));
    }
    var feedLine = PrinterCommands.FEED_LINE;
    data.addAll(textLeftMargin);
    data.addAll(textSize);
    data.addAll(textBold);
    data.addAll(textSpace);
    data.addAll(content);
    data.addAll(feedLine);
    return data;
  }

  // 文字内容拆分多行
  static List splitText(String text, int size, int space) {
    var list = [];
    var lineTextCount = getLineTextCount(size, space);
    for (var i = 0; i < text.length; i = i + lineTextCount) {
      list.add(text.substring(i, min(text.length, i + lineTextCount)));
    }
    return list;
  }

  // 一行显示的字数
  // 字数 = 打印纸宽度 ~/ (打印字字宽度 * 字体放大倍数)
  static int getLineTextCount(sizeMul, space) {
    var textHSpace = 2 * space * printBaseUnitValue; // 字符左右边距
    return printPageWidth ~/ ((printTextWidth + textHSpace) * sizeMul);
  }

  // 左边距 = 打印纸宽度 - 文字宽度 ~/ 2
  static int getLeftMargin(String text, sizeMul, int space) {
    return (printPageWidth - getLineTextWidth(text, sizeMul, space)) ~/ 2 - 1;
  }

  // 一行字的宽度
  // 一行字的总宽度 = 字数 * 打印字字宽度(字符宽度+字间距宽度) * 字体放大倍数
  static double getLineTextWidth(String text, sizeMul, int space) {
    var textHSpace = 2 * space * printBaseUnitValue; // 字符左右边距
    var doubleCharCount = matchDoubleCharCount(text); // 双字节字符数量
    var doubleCharWidth = doubleCharCount * (printTextWidth + textHSpace);
    var singleCharWidth =
        (text.length - doubleCharCount) * (printTextWidth / 2 + textHSpace);
    // 字节宽度(单字节+双字节) * 字体放大倍数
    return (doubleCharWidth + singleCharWidth) * sizeMul;
  }

  // 双字节字符个数
  static matchDoubleCharCount(String text) {
    int count = 0;
    RegExp regDoubleChar = RegExp("[^\x00-\xff]");
    for (var i = 0; i < text.length; i++) {
      var char = text.substring(i, i+1);
      if (regDoubleChar.hasMatch(char)) {
        count++;
      }
    }
    return count;
  }

  // 打印条形码
  static printBarCode(String info, {CHARSET charset = CHARSET.UTF_8}) {
    Uint8List infoByte;
    if (charset == CHARSET.GBK) {
      infoByte = Uint8List.fromList(gbk.encode(info));
    } else {
      infoByte = Uint8List.fromList(utf8.encode(info));
    }
    return PrinterCommands.createBarCode(infoByte);
  }

  /// 打印二维码
  static printQRCode(String info, {CHARSET charset = CHARSET.UTF_8}) {
    List<int> data = [];
    ///设置二维码模块大小
    var QRCodeSize = [0x1D,0x28,0x6B,0x03,0x00,0x31,0x43,8];

    ///将二维码数据存储到符号存储区
    //第一步
    String str = info.toString();
    var kLength = str.length + 3;
    var pL = kLength % 256;
    var pH = kLength ~/ 256;
    var QRCodeInfo = [0x1D,0x28,0x6B,pL,pH,0x31,0x50,48];
    //第二步
    Uint8List infoByte;
    if (charset == CHARSET.GBK) {
      infoByte = Uint8List.fromList(gbk.encode(info));
    } else {
      infoByte = Uint8List.fromList(utf8.encode(info));
    }
    ///打印之前存储的二维码信息
    var printStoredQRData = [0x1D,0x28,0x6B,0x03,0x00,0x31,0x51,48];
    ///组装
    data.addAll(QRCodeSize);
    data.addAll(QRCodeInfo);
    data.addAll(infoByte);
    data.addAll(printStoredQRData);
    return data;
  }
}

/// 字体
enum CHARSET {
  UTF_8,
  GBK,
}