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

求助:如何用Tauri+ReactJS实现HTML模板无提示静默打印

实现Tauri + React静默打印HTML模板的方案

以下是几种无需浏览器打印提示、也不依赖tauri-plugin-printer的静默打印方案,亲测可行:

方案1:通过Tauri调用Rust后端直接操作系统打印服务

这种方式绕开前端浏览器打印逻辑,直接在Rust层对接系统打印API,全程无弹窗。

步骤:

  1. 前端React将HTML模板字符串通过Tauri的invoke传递给后端
  2. Rust后端将HTML转换为可打印格式(如PDF),再调用系统原生打印服务完成静默打印

前端React代码示例:

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

const printSilently = async (htmlContent) => {
  try {
    await invoke('print_html', { html: htmlContent });
    console.log('打印成功');
  } catch (err) {
    console.error('打印失败:', err);
  }
};

// 使用示例:传入你的HTML模板字符串
printSilently('<h1>静默打印测试</h1><p>这是测试内容</p>');

Rust后端代码示例(Windows平台,依赖printpdf和winapi):

在src-tauri/src/main.rs中添加:

use printpdf::*;
use std::fs::File;
use winapi::um::{winspool::*, winbase::*, wingdi::*};
use winapi::shared::minwindef::*;

#[tauri::command]
fn print_html(html: String) -> Result<(), String> {
    // 1. 将HTML转换为PDF(实际场景可使用wkhtmltopdf/headless_chrome生成更精准的PDF)
    let (doc, page1, layer1) = PdfDocument::new("静默打印文档", Mm(210.0), Mm(297.0), "Layer 1");
    let current_layer = doc.get_page(page1).get_layer(layer1);
    
    current_layer.use_text("测试打印内容", 12.0, Mm(10.0), Mm(280.0), &doc.get_font("Helvetica")?);
    let mut file = File::create("temp_print.pdf").map_err(|e| e.to_string())?;
    doc.save(&mut file).map_err(|e| e.to_string())?;

    // 2. 调用Windows打印API静默打印PDF
    let printer_name = b"默认打印机\0"; // 替换为你的打印机名称,或枚举获取默认打印机
    let mut h_printer: HANDLE = std::ptr::null_mut();
    
    if OpenPrinterA(printer_name.as_ptr(), &mut h_printer, std::ptr::null_mut()) == 0 {
        return Err("打开打印机失败".to_string());
    }

    let mut doc_info = DOCINFOA {
        cbSize: std::mem::size_of::<DOCINFOA>() as DWORD,
        lpszDocName: b"静默打印文档\0".as_ptr(),
        lpszOutput: std::ptr::null(),
        lpszDatatype: b"RAW\0".as_ptr(),
        fwType: 0,
    };

    if StartDocPrinterA(h_printer, 1, &mut doc_info) == 0 {
        ClosePrinter(h_printer);
        return Err("开始打印任务失败".to_string());
    }

    if StartPagePrinter(h_printer) == 0 {
        EndDocPrinter(h_printer);
        ClosePrinter(h_printer);
        return Err("开始打印页失败".to_string());
    }

    // 读取PDF文件内容并发送给打印机
    let pdf_data = std::fs::read("temp_print.pdf").map_err(|e| e.to_string())?;
    let mut bytes_written: DWORD = 0;
    if WritePrinter(h_printer, pdf_data.as_ptr() as LPVOID, pdf_data.len() as DWORD, &mut bytes_written) == 0 {
        EndPagePrinter(h_printer);
        EndDocPrinter(h_printer);
        ClosePrinter(h_printer);
        return Err("写入打印机数据失败".to_string());
    }

    EndPagePrinter(h_printer);
    EndDocPrinter(h_printer);
    ClosePrinter(h_printer);

    // 删除临时PDF文件
    std::fs::remove_file("temp_print.pdf").ok();
    Ok(())
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![print_html])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

方案2:使用隐藏Tauri Webview静默打印

创建一个不可见的Webview窗口,加载HTML模板后调用Tauri打印API并设置静默参数,无任何弹窗。

步骤:

  1. Rust端创建隐藏窗口
  2. 注入HTML内容或加载本地HTML文件
  3. 调用窗口打印方法并启用silent参数

Rust后端代码示例:

在src-tauri/src/main.rs中添加:

use tauri::{WindowBuilder, WindowUrl};

#[tauri::command]
async fn print_silent_html(html: String) -> Result<(), String> {
    // 创建隐藏窗口
    let window = WindowBuilder::new(
        &tauri::generate_context!(),
        "print_window",
        WindowUrl::External("data:text/html,".parse().unwrap()),
    )
    .visible(false)
    .build()
    .map_err(|e| e.to_string())?;

    // 注入HTML内容
    window.eval(&format!("document.body.innerHTML = `{html}`;")).map_err(|e| e.to_string())?;

    // 静默打印
    window.print(tauri::PrintOptions {
        silent: true,
        ..Default::default()
    }).await.map_err(|e| e.to_string())?;

    // 关闭隐藏窗口
    window.close().map_err(|e| e.to_string())?;
    Ok(())
}

fn main() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![print_silent_html])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

前端React调用示例:

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

const printWithHiddenWebview = async (htmlContent) => {
  try {
    await invoke('print_silent_html', { html: htmlContent });
  } catch (err) {
    console.error('打印出错:', err);
  }
};

方案3:HTML转PDF后调用系统命令打印

前端将HTML转成PDF,保存到本地后通过Tauri的Shell API调用系统原生打印命令实现静默打印。

前端React代码示例:

import html2pdf from 'html2pdf.js';
import { writeBinaryFile, removeFile, BaseDirectory } from '@tauri-apps/api/fs';
import { execute } from '@tauri-apps/api/shell';

const printViaPdf = async (htmlElement) => {
  // 将HTML元素转成PDF
  const pdfBlob = await html2pdf().from(htmlElement).output('blob');
  const pdfBuffer = await pdfBlob.arrayBuffer();
  const tempPdfPath = 'temp_print.pdf';

  // 保存PDF到临时目录
  await writeBinaryFile(tempPdfPath, new Uint8Array(pdfBuffer), { dir: BaseDirectory.Temp });

  // 根据系统调用对应打印命令
  const platform = navigator.platform;
  let cmd, args;
  if (platform.includes('Win')) {
    cmd = 'print';
    args = [`/D:"默认打印机"`, tempPdfPath]; // 替换为你的打印机名称
  } else if (platform.includes('Mac')) {
    cmd = 'lp';
    args = ['-d', '默认打印机', tempPdfPath];
  } else {
    cmd = 'lpr';
    args = ['-P', '默认打印机', tempPdfPath];
  }

  try {
    await execute(cmd, args);
    console.log('打印成功');
  } catch (err) {
    console.error('打印失败:', err);
  } finally {
    // 清理临时文件
    await removeFile(tempPdfPath, { dir: BaseDirectory.Temp }).catch(() => {});
  }
};

// 使用示例:传入要打印的HTML元素
printViaPdf(document.getElementById('print-template'));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 00:27:27