You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter新手求助:如何通过蓝牙打印机打印购物小票?

Hey there! As someone who’s tackled Flutter Bluetooth receipt printing before, let me break this down for you clearly—since you’re already using flutter_blue, we’ll build directly on that.

整体流程 Overview

Your workflow will look like this:

  1. Scan and connect to your Bluetooth receipt printer via flutter_blue
  2. Fetch order data from MySQL, calculate totals, and format it into a receipt layout
  3. Convert that receipt text into ESC/POS commands (the standard language most receipt printers understand)
  4. Send the formatted command data to the connected printer via Bluetooth

1. First: Get Bluetooth Connection Working

First, you need to discover the printer, connect to it, and find the correct BLE characteristic to send data to. Here’s a simplified code snippet for that:

import 'package:flutter_blue/flutter_blue.dart';

FlutterBlue flutterBlue = FlutterBlue.instance;
BluetoothDevice? connectedPrinter;
BluetoothCharacteristic? writeCharacteristic;

// Scan for Bluetooth devices
void scanForPrinters() {
  flutterBlue.startScan(timeout: Duration(seconds: 4));
  
  flutterBlue.scanResults.listen((results) {
    for (ScanResult result in results) {
      // Replace with your printer's name or MAC address
      if (result.device.name.contains("ReceiptPrinter")) {
        connectToPrinter(result.device);
        flutterBlue.stopScan();
        break;
      }
    }
  });
}

// Connect to the printer and find writable characteristic
Future<void> connectToPrinter(BluetoothDevice device) async {
  try {
    await device.connect();
    connectedPrinter = device;
    
    // Discover services and characteristics
    List<BluetoothService> services = await device.discoverServices();
    for (BluetoothService service in services) {
      for (BluetoothCharacteristic char in service.characteristics) {
        // Look for a characteristic that allows write operations
        if (char.properties.write || char.properties.writeWithoutResponse) {
          writeCharacteristic = char;
          print("Found writable characteristic!");
          return;
        }
      }
    }
  } catch (e) {
    print("Connection error: $e");
  }
}

2. Format Receipt Data into ESC/POS Commands

Most receipt printers use ESC/POS (Escape/POS) commands to control formatting (bold, alignment, line breaks, cutting). You’ll need to convert your order data into this format. Here’s a helper function to do that:

// Convert order data to ESC/POS byte list
Uint8List formatReceipt(Map<String, dynamic> orderData) {
  String receiptText = "";
  
  // Header (bold, centered)
  receiptText += "\x1B\x45\x01"; // Turn bold on
  receiptText += "===== YOUR STORE NAME =====\n";
  receiptText += "\x1B\x45\x00"; // Turn bold off
  receiptText += "Order ID: ${orderData['orderId']}\n";
  receiptText += "Date: ${DateTime.now().toString().split(" ")[0]}\n";
  receiptText += "-------------------------\n";
  
  // Item list
  for (var item in orderData['items']) {
    receiptText += "${item['name']} x${item['quantity']}\n";
    receiptText += "  \$${item['price'].toStringAsFixed(2)}\n";
  }
  
  // Total
  receiptText += "-------------------------\n";
  receiptText += "\x1B\x45\x01"; // Bold for total
  receiptText += "TOTAL: \$${orderData['total'].toStringAsFixed(2)}\n";
  receiptText += "\x1B\x45\x00";
  receiptText += "-------------------------\n";
  receiptText += "Thank you for your purchase!\n";
  
  // Add cut paper command (adjust based on your printer)
  receiptText += "\x1B\x69"; // Full cut (some printers use \x1B\x4A\x00)
  
  // Convert string to Uint8List (printer expects bytes)
  return Uint8List.fromList(receiptText.codeUnits);
}

3. Send Data to the Printer

Once you have the formatted receipt bytes and a connected printer, send the data:

// Print the receipt
Future<void> printReceipt(Map<String, dynamic> orderData) async {
  if (connectedPrinter == null || writeCharacteristic == null) {
    print("No printer connected!");
    return;
  }
  
  try {
    Uint8List receiptBytes = formatReceipt(orderData);
    await writeCharacteristic!.write(receiptBytes, withoutResponse: true);
    print("Receipt sent to printer!");
  } catch (e) {
    print("Print error: $e");
  }
}

Quick Notes to Avoid Headaches

  • Test ESC/POS Commands: Different printers might use slightly different commands (e.g., cut paper). Check your printer’s manual for exact codes.
  • MySQL Data Fetch: You’ll need to add an API (like a Node.js/PHP backend) to fetch order data from MySQL—call this API from Flutter using http or dio package, then pass the response to printReceipt().
  • Bluetooth Permissions: Don’t forget to add Bluetooth permissions in your AndroidManifest.xml and Info.plist (for iOS).

Here’s how you’d tie it all together when the user submits an order:

// Example: After user submits order
void onOrderSubmitted() async {
  // 1. Fetch order data from your MySQL-backed API
  // var orderData = await fetchOrderFromAPI();
  
  // For testing, use sample data
  var sampleOrder = {
    'orderId': 'ORD-1234',
    'items': [
      {'name': 'Coffee', 'quantity': 2, 'price': 3.50},
      {'name': 'Croissant', 'quantity': 1, 'price': 2.00}
    ],
    'total': 9.00
  };
  
  // 2. Ensure printer is connected
  if (connectedPrinter == null) {
    await scanForPrinters();
    // Wait a bit for connection (better to use a state management solution in real app)
    await Future.delayed(Duration(seconds: 2));
  }
  
  // 3. Print the receipt
  await printReceipt(sampleOrder);
}

内容的提问来源于stack exchange,提问作者GNM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:36:55