プリンターに印刷ジョブを送る

Recipe ID: hw-010

Rust から特定のファイルをプリンターに送信して印刷します。最も一般的なユースケースは PDF ファイルの印刷です。

1. 依存関係の追加

src-tauri ディレクトリに移動して、以下のコマンドを実行します。

cargo add printers

2. 実装コード(PDF印刷)

printers クレートを使用して、Rust 側で印刷ジョブを作成・送信します。

#[tauri::command]
fn print_pdf(printer_name: String, file_path: String) -> Result<String, String> {
    // system_name または name でプリンターを検索
    let system_printers = printers::get_printers();
    let printer = system_printers.iter()
        .find(|p| p.system_name == printer_name || p.name == printer_name)
        .ok_or("Printer not found")?;

    // ファイルを読み込み
    let bytes = std::fs::read(&file_path).map_err(|e| e.to_string())?;

    // 印刷ジョブを実行
    // printers クレートの仕様により、深い階層にある PrinterJobOptions を指定する必要があります
    let mut options = printers::common::base::job::PrinterJobOptions::none();
    options.name = Some("My Job Name");

    printer.print(&bytes, options).map_err(|e| e.to_string())?;

    Ok("Print job queued".to_string())
}

3. 実装(フロントエンド側)

import { invoke } from '@tauri-apps/api/core';

async function printDocument(printerName: string, filePath: string) {
  try {
    const result = await invoke<string>('print_pdf', {
      printerName,
      filePath
    });
    console.log('印刷結果:', result);
  } catch (error) {
    console.error('印刷エラー:', error);
  }
}

4. 補足

もし printers クレートでの印刷が環境によって上手くいかない場合や、印刷設定(用紙サイズや部数など)を細かく制御したい場合は、OS 標準のコマンドを直接呼び出す方法が確実です。

以下に std::process::Command を使用したクロスプラットフォームな実装例を紹介します。

use std::process::Command;

#[tauri::command]
fn print_with_os_command(printer_name: String, file_path: String) -> Result<String, String> {
    
    #[cfg(target_os = "windows")]
    {
        // Windows (PowerShell)
        // Start-Process を使用して、指定されたファイルを既定のアプリで印刷します。
        // ※ プリンター指定は難しいため、通常は「既定のプリンター」に出力されます。
        let status = Command::new("powershell")
            .args(&["Start-Process", "-FilePath", &file_path, "-Verb", "Print", "-PassThru"])
            .status()
            .map_err(|e| e.to_string())?;

        if !status.success() {
            return Err("Failed to execute print command".to_string());
        }
    }

    #[cfg(not(target_os = "windows"))]
    {
        // macOS / Linux (lp コマンド)
        // -d オプションでプリンターを指定できます。
        let status = Command::new("lp")
            .arg("-d")
            .arg(&printer_name)
            .arg(&file_path)
            .status()
            .map_err(|e| e.to_string())?;

        if !status.success() {
            return Err("Failed to execute lp command".to_string());
        }
    }

    Ok("Print job queued via OS command".to_string())
}

コマンドの詳細

  • Windows: Start-Process -Verb Print は、ファイルの拡張子(.pdf など)に関連付けられたアプリケーション(Acrobat Reader や Edge など)を起動し、印刷コマンドを送信します。
  • macOS / Linux: lp コマンドは CUPS (Common Unix Printing System) の標準コマンドであり、多くのオプション(-n で部数、-o sides=two-sided-long-edge で両面印刷など)に対応しています。