25 releases (12 breaking)

0.13.1 Oct 14, 2024
0.12.2 Apr 23, 2024
0.9.0 Mar 29, 2024
0.6.1 Dec 30, 2023
0.6.0 Nov 17, 2023

#112 in Hardware support

Download history 22/week @ 2024-07-24 18/week @ 2024-07-31 132/week @ 2024-08-07 12/week @ 2024-08-14 5/week @ 2024-08-21 15/week @ 2024-09-11 37/week @ 2024-09-18 47/week @ 2024-09-25 27/week @ 2024-10-02 152/week @ 2024-10-09 58/week @ 2024-10-16 15/week @ 2024-10-23 47/week @ 2024-10-30

273 downloads per month

MIT license

310KB
5K SLoC

ESC/POS Rust implementation

Build status Crates.io Documentation

This crate implements a subset of Epson's ESC/POS protocol for thermal receipt printers. It allows you to generate and print documents with basic text formatting, cutting, barcodes, QR codes and raster images on a compatible printer. It also provides a way to check the printer status.

Ticket Receipt
Printed on Aures ODP 333

This project is strongly inspired by recibo (Rust), escposify (Rust) and escpos (Go).

Installation

For standard functionalities (e.g. printing text), no additional dependencies are required:

[dependencies]
escpos = "0.13.1"

If you need all features, you can use the full feature:

[dependencies]
escpos = { version = "0.13.1", features = ["full"] }

Or you can use cargo add command:

cargo add escpos
cargo add escpos -F full

Code coverage

Tool used: tarpaulin

cargo install cargo-tarpaulin
cargo tarpaulin --all-features

Results:

  • [2024-10-14] 57.75% coverage, 1121/1941 lines covered

Features list

Name Description Default
barcodes Print barcodes (UPC-A, UPC-E, EAN8, EAN13, CODE39, ITF or CODABAR)
codes_2d Print 2D codes (QR Code, PDF417, GS1 DataBar, DataMatrix, Aztec, etc.)
graphics Print raster images
usb Enable USB feature
native_usb Enable native USB feature
hidapi Enable HidApi feature
serial_port Enable Serial port feature
full Enable all features

Examples

The examples folder contains various examples of how to use escpos. The docs (will) also provide lots of code snippets and examples.

To launch an example, use the following command:

RUST_LOG=debug cargo run --example full --features full
RUST_LOG=debug cargo run --example receipt -F full
RUST_LOG=debug cargo run --example codes
RUST_LOG=debug cargo run --example debug
RUST_LOG=debug cargo run --example page_codes
RUST_LOG=debug cargo run --example usb --features usb
RUST_LOG=debug cargo run --example native_usb --features native_usb
RUST_LOG=debug cargo run --example hidapi --features hidapi
RUST_LOG=debug cargo run --example serial_port --features serial_port
RUST_LOG=debug cargo run --example status --all-features

Simple text formatting

use escpos::printer::Printer;
use escpos::printer_options::PrinterOptions;
use escpos::utils::*;
use escpos::{driver::*, errors::Result};

fn main() -> Result<()> {
    env_logger::init();

    let driver = NetworkDriver::open("192.168.1.248", 9100, None)?;
    Printer::new(driver, Protocol::default(), Some(PrinterOptions::default()))
        .debug_mode(Some(DebugMode::Dec))
        .init()?
        .smoothing(true)?
        .bold(true)?
        .underline(UnderlineMode::Single)?
        .writeln("Bold underline")?
        .justify(JustifyMode::CENTER)?
        .reverse(true)?
        .bold(false)?
        .writeln("Hello world - Reverse")?
        .feed()?
        .justify(JustifyMode::RIGHT)?
        .reverse(false)?
        .underline(UnderlineMode::None)?
        .size(2, 3)?
        .writeln("Hello world - Normal")?
        .print_cut()?;

    Ok(())
}

EAN13

use escpos::printer::Printer;
use escpos::utils::*;
use escpos::{driver::*, errors::Result};

fn main() -> Result<()> {
    env_logger::init();

    let driver = ConsoleDriver::open(true);
    Printer::new(driver, Protocol::default(), None)
        .debug_mode(Some(DebugMode::Hex))
        .init()?
        .ean13_option(
            "1234567890265",
            BarcodeOption::new(
                BarcodeWidth::M,
                BarcodeHeight::S,
                BarcodeFont::A,
                BarcodePosition::Below,
            )
        )?
        .feed()?
        .print_cut()?;

    Ok(())
}

QR Code

use escpos::printer::Printer;
use escpos::utils::*;
use escpos::{driver::*, errors::Result};

fn main() -> Result<()> {
    env_logger::init();

    let driver = ConsoleDriver::open(true);
    Printer::new(driver, Protocol::default(), None)
        .debug_mode(Some(DebugMode::Hex))
        .init()?
        .qrcode_option(
            "https://www.google.com",
            QRCodeOption::new(QRCodeModel::Model1, 6, QRCodeCorrectionLevel::M),
        )?
        .feed()?
        .print_cut()?;

    Ok(())
}

Bit image (with graphics feature enabled)

use escpos::printer::Printer;
use escpos::utils::*;
use escpos::{driver::*, errors::Result};

fn main() -> Result<()> {
    env_logger::init();

    let driver = ConsoleDriver::open(true);
    let mut printer = Printer::new(driver, Protocol::default(), None);
    printer.debug_mode(Some(DebugMode::Hex))
        .init()?
        .bit_image_option(
            "./resources/images/rust-logo-small.png",
            BitImageOption::new(Some(128), None, BitImageSize::Normal)?,
        )?
        .feed()?
        .print_cut()?;

    Ok(())
}

Check printer status

use escpos::printer::Printer;
use escpos::utils::*;
use escpos::{driver::*, errors::Result};

fn main() -> Result<()> {
    env_logger::init();

    let driver = ConsoleDriver::open(true);
    Printer::new(driver.clone(), Protocol::default(), None)
        .debug_mode(Some(DebugMode::Dec))
        .real_time_status(RealTimeStatusRequest::Printer)?
        .real_time_status(RealTimeStatusRequest::RollPaperSensor)?
        .send_status()?;

    let mut buf = [0; 1];
    driver.read(&mut buf)?;

    let status = RealTimeStatusResponse::parse(RealTimeStatusRequest::Printer, buf[0])?;
    println!(
        "Printer online: {}",
        status.get(&RealTimeStatusResponse::Online).unwrap_or(&false)
    );

    Ok(())
}

Commands list

Status Command Description Feature
init() Initialize printer (ESC @)
print() Print document
reset() Hardware reset (ESC ? LF 0)
cut() Paper cut (GS V A 0)
partial_cut() Partial paper cut (GS V A 1)
print_cut() Print and paper cut
page_code() Select character code table (ESC t)
character_set() Select an international character set (ESC R)
bold() Text bold (ESC E)
underline() Text underline (ESC -)
double_strike() Text double strike (ESC G)
font() Text font (ESC M)
flip() Text flip (ESC V)
justify() Text justify (ESC a)
reserve() Text reserve color (GS B)
size() Text size (GS !)
reset_size() Reset text size (GS !)
smoothing() Smoothing mode (GS b)
feed() Line feed (ESC d)
feeds() Multiple lines feed (ESC d)
line_spacing() Line spacing (ESC 3)
reset_line_spacing() Reset line spacing (ESC 2)
upside_down() Upside-down mode (ESC {)
cash_drawer() Generate pulse (ESC p)
write() Write text
writeln() Write text and line feed
custom() Custom command
custom_with_page_code() Custom command with page code
motion_units() Set horizontal and vertical motion units (GS P)
ean13() Print EAN13 with default option barcode
ean13_option() Print EAN13 with custom option barcode
ean8() Print EAN8 with default option barcode
ean8_option() Print EAN8 with custom option barcode
upca() Print UPC-A with default option barcode
upca_option() Print UPC-A with custom option barcode
upce() Print UPC-E with default option barcode
upce_option() Print UPC-E with custom option barcode
code39() Print CODE 39 with default option barcode
code39_option() Print CODE 39 with custom option barcode
codabar() Print CODABAR with default option barcode
codabar_option() Print CODABAR with custom option barcode
itf() Print ITF with default option barcode
itf_option() Print ITF with custom option barcode
qrcode() Print QR code with default option codes_2d
qrcode_option() Print QR code with custom option codes_2d
bit_image() Print raster bit image with default option graphics
bit_image_option() Print raster bit image with custom option graphics
bit_image_from_bytes() Print raster bit image from bytes with default option graphics
bit_image_from_bytes_option() Print raster bit image from bytes with custom option graphics
gs1_databar_2d Print 2D GS1 DataBar with default option codes_2d
gs1_databar_2d_option Print 2D GS1 DataBar with custom option codes_2d
pdf417 Print PDF417 with default option codes_2d
pdf417_option Print PDF417 with custom option codes_2d
maxi_code Print MaxiCode with default option codes_2d
maxi_code_option Print MaxiCode with custom option codes_2d
data_matrix Print DataMatrix with default option codes_2d
data_matrix_option Print DataMatrix with custom option codes_2d
aztec Print Aztec code with default option codes_2d
aztec_option Print Aztec code with custom option codes_2d
🚧 graphic() Print raster graphic with default option graphics
🚧 graphic_option() Print raster graphic with custom option graphics
  • ✅ Done
  • 🚧 In progress
  • ❌ To do

Page codes list

Code Implemented?
PC437
Katakana
PC850
PC860
PC863
PC865
Hiragana
PC851
PC853
PC857
PC737
ISO8859_7
WPC1252
PC866
PC852
PC858
PC720
WPC775
PC855
PC861
PC862
PC864
PC869
ISO8859_2
ISO8859_15
PC1098
PC1118
PC1119
PC1125
WPC1250
WPC1251
WPC1253
WPC1254
WPC1255
WPC1256
WPC1257
WPC1258
KZ1048

External resources

Dependencies

~3–17MB
~234K SLoC