在Java中连接打印机并执行打印任务,主要依靠标准的javax.print
API实现,以下是详细步骤和最佳实践,涵盖从基础连接到高级应用的全流程:
核心API:javax.print包
Java原生支持打印服务,通过以下关键类实现:
PrintService
:代表物理打印机DocFlavor
:定义打印数据类型(如PDF、文本、图片)DocPrintJob
:管理打印任务SimpleDoc
:封装打印内容和格式
import javax.print.*; import javax.print.attribute.*; import javax.print.attribute.standard.*; import java.io.FileInputStream; public class JavaPrinterDemo { public static void main(String[] args) { try { // 1. 获取默认打印机 PrintService defaultPrinter = PrintServiceLookup.lookupDefaultPrintService(); // 2. 指定打印内容格式 (此处打印PDF) DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE; // 3. 创建打印任务 DocPrintJob job = defaultPrinter.createPrintJob(); // 4. 封装打印文件 FileInputStream pdfFile = new FileInputStream("document.pdf"); Doc doc = new SimpleDoc(pdfFile, flavor, null); // 5. 设置打印属性(份数、方向等) PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); attributes.add(new Copies(1)); // 打印份数 attributes.add(MediaSizeName.ISO_A4); // A4纸张 attributes.add(OrientationRequested.PORTRAIT); // 纵向 // 6. 执行打印 job.print(doc, attributes); System.out.println("打印任务已提交!"); } catch (Exception e) { e.printStackTrace(); } } }
连接特定打印机的三种方式
按名称匹配打印机
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null); String targetPrinter = "HP LaserJet 1020"; for (PrintService service : services) { if (service.getName().equalsIgnoreCase(targetPrinter)) { DocPrintJob job = service.createPrintJob(); // ... 执行打印 break; } }
按属性筛选(如支持彩色打印)
PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet(); attrs.add(ColorSupported.SUPPORTED); // 筛选彩色打印机 PrintService[] colorPrinters = PrintServiceLookup.lookupPrintServices(null, attrs);
直接使用打印对话框(用户选择)
PrinterJob job = PrinterJob.getPrinterJob(); if (job.printDialog()) { // 弹出系统打印对话框 job.print(); }
支持不同文件类型打印
文件类型 | DocFlavor 示例 | 注意事项 |
---|---|---|
PDF文件 | DocFlavor.INPUT_STREAM.PDF |
需依赖PDF库(如Apache PDFBox) |
图片 | DocFlavor.INPUT_STREAM.JPEG |
支持JPEG/PNG/GIF |
纯文本 | DocFlavor.STRING.TEXT_PLAIN |
自动处理编码 |
HTML | DocFlavor.URL.TEXT_HTML |
需浏览器渲染引擎 |
打印图片示例:
DocFlavor flavor = DocFlavor.INPUT_STREAM.JPEG; FileInputStream image = new FileInputStream("photo.jpg"); Doc doc = new SimpleDoc(image, flavor, null); job.print(doc, null); // 使用默认属性
常见问题与解决方案
-
打印机未找到
- 检查系统是否安装驱动
- 使用
PrintServiceLookup.lookupPrintServices()
列出所有可用设备
-
打印乱码
- 明确文本编码:
attributes.add(new MediaPrintableArea(0,0,210,297,MediaPrintableArea.MM));
- 使用
DocFlavor.STRING.TEXT_HTML
保留格式
- 明确文本编码:
-
跨平台兼容性
- Linux:确保CUPS服务运行
- Windows:配置默认打印机权限
- MacOS:检查系统隐私设置
-
异步打印监控
job.addPrintJobListener(new PrintJobAdapter() { @Override public void printJobCompleted(PrintJobEvent event) { System.out.println("打印完成!"); } });
高级应用场景
-
批量打印
attributes.add(new Copies(50)); // 一次性打印50份
-
条码/标签打印
- 使用Zebra、TSC等工业打印机SDK
- 示例库:Zebra SDK for Java
-
云打印集成
- Google Cloud Print(已弃用) → 迁移至IPP协议 (Internet Printing Protocol)
- 开源库推荐:jspi
安全性与权限配置
- 代码签名:若需访问系统级资源,对JAR进行数字签名
- 策略文件 (java.policy):
grant { permission javax.print.PrintPermission "print"; };
- 避免在Web环境中直接操作打印机,建议通过队列服务(如RabbitMQ)中转任务
Java通过标准javax.print
API提供稳定的打印支持,关键步骤包括:
- 定位打印机服务 (
PrintServiceLookup
) - 匹配文件格式 (
DocFlavor
) - 配置打印参数(份数、纸张等)
- 提交任务 (
DocPrintJob.print()
)
最佳实践建议:生产环境中建议使用异步打印队列,避免阻塞主线程;工业级打印需求优先选择厂商SDK,测试阶段务必模拟不同操作系统环境。
引用说明:
- Oracle官方文档:Java Printing API
- Apache PDFBox库:处理PDF打印
- IPP协议标准:RFC 8010
- 安全性参考:Java安全策略指南
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/7454.html