Java打印的基础架构与流程

Java打印功能主要通过AWT(Abstract Window Toolkit)包中的java.awt.print模块实现,该模块提供了一套完整的打印API,支持文本、图像、图形等内容的输出,打印流程的核心在于将绘制内容转换为打印机可识别的格式,其基本步骤包括:获取打印服务、配置打印属性、创建打印任务、绘制打印内容。
Java打印体系中的关键角色包括PrinterJob(打印任务管理器)、PrintService(打印机服务)、PageFormat(页面格式)和Graphics2D(绘图上下文)。PrinterJob是整个打印过程的入口,负责协调打印任务的生命周期;PrintService代表系统中的打印机,可通过PrintServiceLookup查找可用打印机;PageFormat定义了纸张大小、打印方向(横向/纵向)、边距等页面属性;Graphics2D则用于在打印设备的“画布”上绘制具体内容。
核心API详解
-
PrinterJob:打印任务的核心
PrinterJob是打印任务的调度器,常用方法包括:getPrinterJob():静态方法,获取当前打印任务实例;setPrintable(Printable painter):设置打印内容绘制器,需实现Printable接口的print()方法;setPageable(Pageable document):设置多页文档,需实现Pageable接口,适用于分页打印;print():执行打印任务;pageDialog(PageFormat page):弹出页面设置对话框,允许用户调整页面属性。
-
Printable接口:自定义打印内容
实现打印内容需定义Printable接口,其核心方法为print(Graphics g, PageFormat pf, int pageIndex),参数说明:g:绘图上下文,实际类型为Graphics2D,用于绘制文本、图像等;pf:当前页的页面格式,包含纸张尺寸、可打印区域等信息;pageIndex:当前页索引(从0开始),若返回Printable.NO_SUCH_PAGE表示打印结束。
-
PageFormat:页面配置
通过PageFormat可设置纸张方向(PORTRAIT纵向或LANDSCAPE横向)、纸张尺寸(如A4、Letter)及边距。PageFormat pf = printerJob.defaultPage(); pf.setOrientation(PageFormat.LANDSCAPE); // 设置横向打印 pf.setImageableArea(20, 20, pf.getWidth()-40, pf.getHeight()-40); // 设置边距
不同场景的打印实现

-
纯文本打印
文本打印需处理换行、字体对齐等问题,基本思路:获取Graphics2D对象,设置字体和颜色,通过drawString()绘制文本,并计算每行文本高度实现分页,示例片段:Graphics2D g2d = (Graphics2D) g; g2d.setFont(new Font("宋体", Font.PLAIN, 12)); String text = "要打印的文本内容"; int lineHeight = 15; int y = 50; // 起始Y坐标 for (String line : text.split("\n")) { if (y > pf.getImageableHeight() - 50) { // 超出页面则换页 return Printable.PAGE_EXISTS; } g2d.drawString(line, 50, y); y += lineHeight; } -
图像打印
图像打印需处理缩放以适应纸张,使用Graphics2D的drawImage()方法,结合ImageObserver实现自适应。BufferedImage image = ImageIO.read(new File("image.png")); double scale = Math.min( pf.getImageableWidth() / image.getWidth(), pf.getImageableHeight() / image.getHeight() ); int width = (int) (image.getWidth() * scale); int height = (int) (image.getHeight() * scale); g2d.drawImage(image, 50, 50, width, height, null); -
文档打印(PDF/Word)
对于复杂文档(如PDF、Word),Java标准库支持有限,通常需借助第三方库:- PDF打印:使用iText库加载PDF文件,将其转换为
BufferedImage后通过Graphics2D绘制; - Word打印:通过Apache POI解析Word文档,提取文本和表格内容,再按上述文本打印方式绘制。
- PDF打印:使用iText库加载PDF文件,将其转换为
高级功能:分页、预览与属性配置
-
分页处理
多页文档需通过pageIndex参数判断当前页,并在print()方法中绘制对应内容,打印一个100行的文本文件,每页显示30行:int linesPerPage = 30; int startIndex = pageIndex * linesPerPage; if (startIndex >= totalLines) return Printable.NO_SUCH_PAGE; for (int i = 0; i < linesPerPage && startIndex + i < totalLines; i++) { String line = lines.get(startIndex + i); g2d.drawString(line, 50, 50 + i * lineHeight); } return Printable.PAGE_EXISTS; -
打印预览
打印预览可通过Swing实现,创建一个JFrame作为预览窗口,在JPanel的paintComponent()方法中模拟打印绘制逻辑,使用与打印相同的Graphics2D绘制代码,但输出到屏幕而非打印机。 -
打印属性配置
通过PrintRequestAttributeSet可设置打印属性,如纸张大小、份数、双面打印等,示例:
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet(); attributes.add(MediaSizeName.ISO_A4); // 纸张大小A4 attributes.add(Copies.valueOf(2)); // 打印2份 attributes.add(Sides.DUPLEX); // 双面打印 printerJob.print(attributes);
常见问题与解决方案
-
打印乱码
原因:系统未安装对应字体或编码不一致。
解决:使用Font.createFont()加载自定义字体,或确保文本编码与系统默认编码一致(如UTF-8)。 -
被裁剪
原因:绘制内容超出可打印区域。
解决:通过PageFormat.getImageableArea()获取可打印区域坐标和尺寸,调整绘制内容的起始位置和大小。 -
打印速度慢
原因:图像分辨率过高或绘制逻辑复杂。
解决:降低图像分辨率(如将DPI从300调整为150),或使用Graphics2D的setRenderingHint()优化渲染性能。
Java打印功能虽基于AWT,但通过合理运用核心API和第三方库,可满足从简单文本到复杂文档的多样化打印需求,开发者需根据实际场景选择打印方式,并注意处理分页、属性配置等细节,以实现稳定高效的打印输出。














