Flutter 熱敏列印 模板化實現

莫在逍遙發表於2021-08-30

前言:

手機端列印一直是一個讓人很頭疼的問題,用圖片列印,圖片過大,效能太差.指令列印,可維護性差,除錯麻煩.

於是我編寫了一個渲染列印指令的庫
GitHub連結
具有以下優點

  1. 支援資料繫結
  2. 模板化編寫,採用Xml作為設計語言,可閱讀性強,無需寫死在程式碼裡面,可以熱替換
  3. 可預覽效果
  4. 支援CPCL與TSL兩種指令集
  5. 有Xml Schema,可以檢測出編寫錯誤

模板效果

<?xml version="1.0"?>
<page width="640" height="640" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/Im-Kevin/rare_print/master/schema/schema.xsd">
    <font-type fontType="YaHei24" fontBaseWidth="32" fontBaseHeight="41"></font-type>
    <printer-config fontType="YaHei24" fontSize="1">
        <page-info gapmMM="2"/>
    </printer-config>
    <column x="30">
        <stack height="126">
            <image binding="data.brandImage" y="20"/>
            <text align="center" fontSize="2" y="76">產品標識卡</text>
        </stack>
        <column>
            <row height="50" y="30">
                <text width="90">品名:</text>
                <text binding="data.familyName"></text>
            </row>
            <row height="50" y="18">
                <row width="310">
                    <text width="90">型號:</text>
                    <text binding="data.familyStyleName"></text>
                </row>
                <row width="310">
                    <text width="90">顏色:</text>
                    <text binding="data.colorName"></text>
                </row>
            </row>
            <row height="50" y="18">
                <text width="90">規格:</text>
                <text binding="data.specName"></text>
            </row>
            <row>
                <column width="400">
                    <row height="50" y="18">
                        <text width="90">數量:</text>
                        <text binding="data.qty" width="auto"></text>
                        <text binding="data.um" width="100"></text>
                    </row>
                    <row height="50" y="18">
                        <text width="150">生產部門:</text>
                        <text binding="data.productionOu"></text>
                    </row>
                    <row height="50" y="18">
                        <text width="150">檢 驗 員:</text>
                        <text binding="data.inspectors"></text>
                    </row>
                    <row height="50" y="18">
                        <text width="150">生產日期:</text>
                        <text binding="data.date" format="yyyy年MM月dd日"></text>
                    </row>
                </column> 
                <column>
                    <qrcode 
                        binding="'123213' + data.uniqueCode"
                        width="200"
                        height="200" 
                        imagePaint="true"></qrcode>
                    <text width="200" height="50" y="22" align="center" binding="data.uniqueCode"></text>
                </column>
            </row>
        </column>
    </column>
</page>

複製程式碼

使用方法:

安裝依賴

dependencies:
  rare_print: ^0.1.2
複製程式碼

匯入包

import 'package:rare_print/rare_print.dart';
複製程式碼

編寫自己的列印模板

實現列印功能

    final demoXml = '<page width="880">...</page>' // 模板
    var control = ControlBase.create(demoXml); // 解析模板

    var jsonData = json.decode(dataSource); // 將json資料來源轉換成 Map

    control.setDataSource(DataSource(jsonData)); // 設定資料來源

    control.performLayout(PrinterConstraints(maxWidth: 837)); // 計算佈局樣式
    CPCLCanvas canvas = CPCLCanvas(); // 建立畫布
    canvas.pageSize = control.actualSize; // 設定畫布大小
    canvas.reset(); // 重置畫布

    control.paint(canvas, PrinterOffset.zero); // 渲染畫布

    canvas.end(); // 標記畫布渲染結束

    io.send(canvas.toCommand); // 輸出具體指令
複製程式碼

實現預覽功能

    ControlBase control;
    @override
    void initState() {
        super.initState();
        final demoXml = '<page width="880">...</page>' // 模板
        control = ControlBase.create(demoXml); // 解析模板

        var jsonData = json.decode(dataSource); // 將json資料來源轉換成 Map

        control.setDataSource(DataSource(jsonData)); // 設定資料來源
    }

    @override
    Widget build(BuildContext context) {
        return PreviewWidget( // 使用PreviewWidget展示效果
            control: control
        );
    }
複製程式碼

相關文章