Rust SDK
Rust SDK 适用于 Rust 语言开发,提供类型安全、高性能的打印机控制接口,支持跨平台应用开发。
Rust SDK 使用 Cargo 管理依赖。在 Cargo.toml 中添加:
[dependencies]psdk-father = { path = "path/to/psdk/rust/frame/father" }psdk-cpcl = { path = "path/to/psdk/rust/fruits/cpcl" }psdk-esc = { path = "path/to/psdk/rust/fruits/esc" }psdk-tspl = { path = "path/to/psdk/rust/fruits/tspl" }可用 Crate
Section titled “可用 Crate”| Crate | 说明 |
|---|---|
psdk-father | 核心框架 |
psdk-extension | 扩展功能 |
psdk-toolkit | 工具集 |
psdk-cpcl | CPCL 指令 |
psdk-esc | ESC 指令 |
psdk-tspl | TSPL 指令 |
1. 导入依赖
Section titled “1. 导入依赖”use psdk_father::{ConnectedDevice, Commander};use psdk_cpcl::{CPCL, args::*};2. 创建连接设备
Section titled “2. 创建连接设备”// 实现 ConnectedDevice traitstruct MyDevice { // 设备信息}
impl ConnectedDevice for MyDevice { fn write(&mut self, data: &[u8]) -> Result<usize, std::io::Error> { // 实现写入逻辑 Ok(data.len()) }
fn read(&mut self) -> Result<Vec<u8>, std::io::Error> { // 实现读取逻辑 Ok(Vec::new()) }
fn device_name(&self) -> String { "Printer".to_string() }
fn is_connected(&self) -> bool { true }}3. 使用打印机
Section titled “3. 使用打印机”let device = MyDevice::new();let mut printer = CPCL::generic(device);
// 打印标签printer .page(Page::new(576, 400)) .text(Text::new(50, 50, "商品标签")) .barcode(Barcode::new(50, 150, "1234567890")) .print() .write()?;CPCL 指令使用
Section titled “CPCL 指令使用”CPCL 指令用于便携式标签打印机。详细指令说明请参考 CPCL 指令文档。
use psdk_cpcl::{CPCL, args::*, marks::*};
let device = create_device(); // 创建设备连接let mut printer = CPCL::generic(device);
// 打印简单标签printer .page(Page::new(576, 400)) .text(Text::builder() .x(50) .y(50) .font(Font::TSS24) .content("商品标签") .build()) .barcode(Barcode::builder() .x(50) .y(150) .code_type(CodeType::Code128) .height(50) .content("1234567890") .build()) .print() .write()?;完整标签示例
Section titled “完整标签示例”use psdk_cpcl::{CPCL, args::*, marks::*};
let mut printer = CPCL::generic(device);
// 构建完整标签printer // 页面设置 .page(Page::builder() .width(576) .height(400) .copies(1) .build())
// 标题(居中、加粗) .center() .bold(true) .text(Text::builder() .x(0) .y(30) .font(Font::TSS24MAX1) .content("商品标签") .build()) .bold(false) .left()
// 分隔线 .line(Line::builder() .x1(30).y1(70) .x2(546).y2(70) .width(2) .build())
// 商品信息 .text(Text::builder() .x(30).y(90) .font(Font::TSS24) .content("名称: 有机苹果") .build()) .text(Text::builder() .x(30).y(130) .font(Font::TSS24) .content("规格: 500g/袋") .build()) .text(Text::builder() .x(30).y(170) .font(Font::TSS24) .bold(true) .content("价格: ¥25.90") .build())
// 一维条码 .barcode(Barcode::builder() .x(80).y(220) .code_type(CodeType::Code128) .height(50) .line_width(1) .content("6901234567890") .build())
// 二维码 .qrcode(QRCode::builder() .x(400).y(90) .width(5) .level(CorrectLevel::M) .content("https://example.com") .build())
// 边框 .box_rect(BoxRect::builder() .x1(20).y1(20) .x2(556).y2(380) .width(2) .build())
// 打印 .print() .write()?;// 居中对齐printer.center();printer.text(Text::new(0, 50, "居中文本"));
// 左对齐printer.left();printer.text(Text::new(30, 100, "左对齐文本"));
// 右对齐printer.right();printer.text(Text::new(0, 150, "右对齐文本"));use psdk_cpcl::marks::Font;
// 可用字体Font::TSS16 // 16点阵Font::TSS20 // 20点阵Font::TSS24 // 24点阵(推荐)Font::TSS28 // 28点阵Font::TSS32 // 32点阵Font::TSS24MAX1 // 24点阵2倍放大Font::TSS24MAX2 // 24点阵3倍放大use psdk_cpcl::marks::CodeType;
// 可用条码类型CodeType::Code128 // Code 128(推荐)CodeType::Code39 // Code 39CodeType::Code93 // Code 93CodeType::EAN8 // EAN-8CodeType::EAN13 // EAN-13CodeType::UPCA // UPC-ACodeType::UPCE // UPC-ECodeType::Codabar // CodabarCodeType::I2OF5 // Interleaved 2 of 5// 查询打印机状态printer.status().write()?;
// 查询 SN 号printer.sn().write()?;
// 查询电量printer.battery_volume().write()?;
// 查询型号printer.model().write()?;
// 查询版本printer.version().write()?;ESC 指令使用
Section titled “ESC 指令使用”ESC 指令广泛用于热敏小票打印机。详细指令说明请参考 ESC 指令文档。
use psdk_esc::{ESC, args::*};
let mut printer = ESC::generic(device);
// 完整打印流程printer .wakeup() .enable() .image(Image::builder() .data(image_data) .mode(ImageMode::Normal) .compress(false) .build()) .position() .stop_job() .write()?;完整打印流程
Section titled “完整打印流程”推荐的打印顺序:
- 唤醒打印机
- 使能打印机
- 打印图片
- 打印定位(连续纸不需要)
- 结束打印任务
let mut printer = ESC::generic(device);
// 1. 唤醒打印机printer.wakeup();
// 2. 使能打印机printer.enable();
// 3. 打印图片let image = Image::builder() .data(image_data) .mode(ImageMode::Normal) .compress(false) .threshold(190) .build();printer.image(image);
// 4. 打印定位(标签纸需要)printer.position();
// 5. 结束打印任务printer.stop_job();
// 执行写入let result = printer.write()?;println!("打印成功,写入 {} 字节", result.bytes_written);// 设置打印浓度(0-2)printer.thickness(Thickness::Medium);
// 设置关机时间(分钟)printer.set_shutdown_time(10);
// 设置纸张类型printer.paper_type(PaperType::builder() .paper_type(PaperTypeEnum::Continuous) .build());
// 设置纸张类型(Q系列)printer.paper_type_q3(PaperTypeQ3::builder() .paper_type(PaperTypeQ3Enum::Gap) .build());// 查询打印机信息printer.info().write()?;
// 查询打印机状态printer.state().write()?;
// 查询电量printer.battery_volume().write()?;
// 查询 MAC 地址printer.mac().write()?;
// 查询 SN 号printer.sn().write()?;
// 查询型号printer.model().write()?;
// 查询固件版本printer.printer_version().write()?;TSPL 指令使用
Section titled “TSPL 指令使用”TSPL 指令用于标签条码打印机。详细指令说明请参考 TSPL 指令文档。
use psdk_tspl::{TSPL, args::*, marks::*};
let mut printer = TSPL::generic(device);
// 打印简单标签printer .page(Page::new(60, 40)) .gap(true) .direction(Direction::new(DirectionType::Up, false)) .cls() .text(Text::builder() .x(50).y(50) .font(Font::TSS24) .content("标签内容") .build()) .print(1) .write()?;完整标签示例
Section titled “完整标签示例”let mut printer = TSPL::generic(device);
printer // 页面设置 .page(Page::new(60, 40)) .gap(true) .direction(Direction::new(DirectionType::Up, false)) .density(8) .speed(4) .cls()
// 标题 .text(Text::builder() .x(180).y(30) .font(Font::TSS24) .x_multi(2).y_multi(2) .content("商品标签") .build())
// 分隔线 .bar(Bar::builder() .x(30).y(80) .width(420).height(2) .build())
// 商品信息 .text(Text::builder() .x(30).y(100) .font(Font::TSS24) .content("品名: 有机苹果") .build()) .text(Text::builder() .x(30).y(140) .font(Font::TSS24) .content("规格: 500g/袋") .build()) .text(Text::builder() .x(30).y(180) .font(Font::TSS24) .is_bold(true) .content("价格: ¥25.90") .build())
// 一维条码 .barcode(Barcode::builder() .x(100).y(220) .code_type(CodeType::Code128) .height(60) .show_type(ShowType::Below) .content("6901234567890") .build())
// 二维码 .qrcode(QRCode::builder() .x(380).y(90) .cell_width(4) .correct_level(CorrectLevel::M) .content("https://example.com") .build())
// 边框 .box_rect(BoxRect::builder() .x(20).y(20) .x_end(460).y_end(310) .line_width(2) .build())
// 打印 .print(1) .write()?;// 设置页面尺寸(mm)printer.page(Page::new(60, 40));
// 设置缝隙纸printer.gap(true);
// 设置黑标纸printer.bline();
// 设置连续纸printer.continuous();
// 设置打印方向printer.direction(Direction::new(DirectionType::Up, false));
// 设置浓度(0-15)printer.density(8);
// 设置速度(1-6)printer.speed(4);
// 清除缓冲区printer.cls();// 填充矩形printer.bar(Bar::builder() .x(50).y(100) .width(200).height(2) .build());
// 空心矩形printer.box_rect(BoxRect::builder() .x(50).y(50) .x_end(300).y_end(200) .line_width(2) .build());
// 画线printer.line(Line::builder() .x(50).y(50) .x_end(300).y_end(200) .line_width(2) .build());
// 画圆printer.circle(Circle::builder() .x(200).y(200) .diameter(100) .line_width(2) .build());
// 椭圆printer.ellipse(Ellipse::builder() .x(200).y(200) .width(150).height(80) .line_width(2) .build());
// 反色区域printer.reverse(Reverse::builder() .x(50).y(50) .width(200).height(100) .build());Rust SDK 使用 Result 类型处理错误:
use std::error::Error;
fn print_label(device: impl ConnectedDevice) -> Result<(), Box<dyn Error>> { let mut printer = CPCL::generic(device);
let result = printer .page(Page::new(576, 400)) .text(Text::new(50, 50, "测试标签")) .print() .write()?;
println!("打印成功,写入 {} 字节", result.bytes_written); Ok(())}
// 使用match print_label(device) { Ok(_) => println!("打印完成"), Err(e) => eprintln!("打印失败: {}", e),}Rust SDK 支持异步操作(需要启用 async 特性):
use tokio;
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let device = create_async_device().await?; let mut printer = CPCL::generic(device);
printer .page(Page::new(576, 400)) .text(Text::new(50, 50, "异步打印")) .print() .write() .await?;
Ok(())}CPCL、ESC、TSPL 打印机实例不是 Send 或 Sync 的,如需在多线程环境使用,建议:
use std::sync::{Arc, Mutex};
let printer = Arc::new(Mutex::new(CPCL::generic(device)));
// 在不同线程中使用let printer_clone = Arc::clone(&printer);std::thread::spawn(move || { let mut p = printer_clone.lock().unwrap(); p.page(Page::new(576, 400)) .text(Text::new(50, 50, "线程打印")) .print() .write() .unwrap();});打印商品标签
Section titled “打印商品标签”use psdk_cpcl::{CPCL, args::*, marks::*};use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> { // 创建设备连接 let device = create_bluetooth_device("Printer")?;
// 创建打印机实例 let mut printer = CPCL::generic(device);
// 打印标签 printer .page(Page::new(576, 400)) .center() .bold(true) .text(Text::builder() .x(0).y(30) .font(Font::TSS24MAX1) .content("商品标签") .build()) .bold(false) .left() .line(Line::new(30, 70, 546, 70, 2)) .text(Text::new(30, 90, "名称: 有机苹果")) .text(Text::new(30, 130, "规格: 500g/袋")) .text(Text::new(30, 170, "价格: ¥25.90")) .barcode(Barcode::builder() .x(80).y(220) .code_type(CodeType::Code128) .height(50) .content("6901234567890") .build()) .qrcode(QRCode::builder() .x(400).y(90) .width(5) .level(CorrectLevel::M) .content("https://example.com") .build()) .box_rect(BoxRect::new(20, 20, 556, 380, 2)) .print() .write()?;
println!("打印成功"); Ok(())}Builder 模式
Section titled “Builder 模式”使用 Builder 模式构建复杂参数:
let text = Text::builder() .x(50) .y(50) .font(Font::TSS24) .rotation(Rotation::Rotate0) .bold(true) .underline(true) .content("复杂文本") .build();
printer.text(text);for i in 0..10 { printer .page(Page::new(576, 400)) .text(Text::new(50, 50, &format!("标签 #{}", i + 1))) .print() .write()?;
// 短暂延迟避免打印机缓冲区溢出 std::thread::sleep(std::time::Duration::from_millis(100));}FFI 接口
Section titled “FFI 接口”Rust SDK 提供 C/JNI FFI 接口,可在其他语言中调用:
use psdk_extension::export_c::*;
#[no_mangle]pub extern "C" fn psdk_cpcl_print( device_ptr: *mut ConnectedDevice, width: i32, height: i32, text: *const c_char,) -> i32 { // FFI 实现}JNI 接口
Section titled “JNI 接口”use psdk_extension::export_jni::*;
#[no_mangle]pub extern "system" fn Java_com_printer_psdk_CPCL_print( env: JNIEnv, class: JClass, device: JObject, width: jint, height: jint, text: JString,) -> jint { // JNI 实现}完整示例请参考: