Java调用打印机打印图片和文本的多种方法
作者:齐鲁大虾
这篇文章主要介绍了在Java中调用打印机打印文本和图片的多种方法,包括Java内置的打印API、JavaPrintServiceAPI、ApachePDFBox库、iText库等,并提供了详细的使用步骤和注意事项,需要的朋友可以参考下
在Java中调用打印机打印文本和图片有多种方法,以下是几种常用的实现方式:
一、使用Java内置的打印API
1.基本打印框架
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.awt.*;
import java.awt.print.*;
import java.io.*;
import javax.imageio.ImageIO;
public class JavaPrinter {
// 打印文本
public static void printText(String text) {
PrinterJob job = PrinterJob.getPrinterJob();
// 设置打印内容
job.setPrintable(new Printable() {
@Override
public int print(Graphics g, PageFormat pf, int pageIndex) {
if (pageIndex > 0) {
return Printable.NO_SUCH_PAGE;
}
Graphics2D g2d = (Graphics2D) g;
g2d.translate(pf.getImageableX(), pf.getImageableY());
// 设置字体
Font font = new Font("宋体", Font.PLAIN, 12);
g2d.setFont(font);
// 绘制文本
g2d.drawString(text, 100, 100);
return Printable.PAGE_EXISTS;
}
});
try {
// 显示打印对话框
if (job.printDialog()) {
job.print();
}
} catch (PrinterException e) {
e.printStackTrace();
}
}
}
2.完整打印类(支持文本和图片)
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.awt.*;
import java.awt.print.*;
import java.awt.image.*;
import javax.imageio.*;
import java.io.*;
public class DocumentPrinter implements Printable {
private String text;
private BufferedImage image;
private boolean hasImage;
public DocumentPrinter(String text) {
this.text = text;
this.hasImage = false;
}
public DocumentPrinter(String text, BufferedImage image) {
this.text = text;
this.image = image;
this.hasImage = true;
}
public void printDocument() {
PrinterJob printerJob = PrinterJob.getPrinterJob();
printerJob.setPrintable(this);
// 设置打印属性
PageFormat pageFormat = printerJob.defaultPage();
// 自定义页面设置
Paper paper = new Paper();
paper.setSize(595, 842); // A4 size in points (1/72 inch)
paper.setImageableArea(72, 72, 451, 698); // 1 inch margins
pageFormat.setPaper(paper);
// 显示打印对话框
if (printerJob.printDialog()) {
try {
printerJob.print();
} catch (PrinterException e) {
System.err.println("打印失败: " + e.getMessage());
}
}
}
@Override
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
throws PrinterException {
if (pageIndex > 0) {
return NO_SUCH_PAGE;
}
Graphics2D g2d = (Graphics2D) graphics;
// 设置高质量渲染
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// 转换坐标到可打印区域
double pageWidth = pageFormat.getImageableWidth();
double pageHeight = pageFormat.getImageableHeight();
int x = (int) pageFormat.getImageableX();
int y = (int) pageFormat.getImageableY();
// 打印文本
if (text != null && !text.isEmpty()) {
printText(g2d, x, y, pageWidth);
}
// 打印图片
if (hasImage && image != null) {
printImage(g2d, x, y, pageWidth, pageHeight);
}
return PAGE_EXISTS;
}
private void printText(Graphics2D g2d, int x, int y, double pageWidth) {
// 设置字体
Font font = new Font("宋体", Font.PLAIN, 12);
g2d.setFont(font);
g2d.setColor(Color.BLACK);
// 计算文本布局
FontMetrics metrics = g2d.getFontMetrics();
int lineHeight = metrics.getHeight();
int currentY = y + lineHeight;
// 处理换行
String[] lines = text.split("\n");
for (String line : lines) {
// 如果一行太长,进行换行处理
if (metrics.stringWidth(line) > pageWidth - 100) {
printWrappedLine(g2d, line, x + 50, currentY,
(int)pageWidth - 100, metrics);
} else {
g2d.drawString(line, x + 50, currentY);
}
currentY += lineHeight;
}
}
private void printWrappedLine(Graphics2D g2d, String line,
int x, int y, int maxWidth, FontMetrics metrics) {
String[] words = line.split(" ");
StringBuilder currentLine = new StringBuilder();
for (String word : words) {
String testLine = currentLine + word + " ";
if (metrics.stringWidth(testLine) <= maxWidth) {
currentLine.append(word).append(" ");
} else {
if (currentLine.length() > 0) {
g2d.drawString(currentLine.toString(), x, y);
y += metrics.getHeight();
}
currentLine = new StringBuilder(word + " ");
}
}
if (currentLine.length() > 0) {
g2d.drawString(currentLine.toString(), x, y);
}
}
private void printImage(Graphics2D g2d, int x, int y,
double pageWidth, double pageHeight) {
if (image == null) return;
// 计算图片尺寸和位置
int imgWidth = image.getWidth();
int imgHeight = image.getHeight();
// 调整图片大小以适应页面
double scale = Math.min(
(pageWidth - 100) / imgWidth,
(pageHeight - 200) / imgHeight
);
int scaledWidth = (int) (imgWidth * scale);
int scaledHeight = (int) (imgHeight * scale);
// 居中显示图片
int imgX = x + (int)((pageWidth - scaledWidth) / 2);
int imgY = y + (int)((pageHeight - scaledHeight) / 2) + 100;
// 绘制图片
g2d.drawImage(image, imgX, imgY, scaledWidth, scaledHeight, null);
// 添加图片边框
g2d.setColor(Color.LIGHT_GRAY);
g2d.drawRect(imgX - 1, imgY - 1, scaledWidth + 2, scaledHeight + 2);
}
public static void main(String[] args) {
try {
// 示例1:打印文本
String text = "这是一个打印测试文档。\n" +
"第二行文本内容。\n" +
"第三行文本内容,这一行比较长,用于测试自动换行功能。";
DocumentPrinter textPrinter = new DocumentPrinter(text);
textPrinter.printDocument();
// 示例2:打印文本和图片
BufferedImage image = ImageIO.read(new File("image.jpg"));
DocumentPrinter imagePrinter = new DocumentPrinter(text, image);
imagePrinter.printDocument();
} catch (IOException e) {
e.printStackTrace();
}
}
}
二、使用Java Print Service API(更现代的方式)
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.awt.print.*;
import java.io.*;
import java.util.Locale;
public class PrintServiceExample {
// 获取所有打印机
public static void listPrinters() {
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
System.out.println("可用的打印机:");
for (PrintService service : services) {
System.out.println(" - " + service.getName());
}
}
// 使用指定打印机打印文本
public static void printToSpecificPrinter(String text, String printerName) {
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
PrintService selectedService = null;
// 查找指定打印机
for (PrintService service : services) {
if (service.getName().equals(printerName)) {
selectedService = service;
break;
}
}
if (selectedService == null) {
System.err.println("未找到打印机: " + printerName);
return;
}
// 创建打印作业
DocPrintJob job = selectedService.createPrintJob();
// 创建打印属性集
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
attributes.add(MediaSizeName.ISO_A4);
attributes.add(OrientationRequested.PORTRAIT);
attributes.add(new Copies(1));
// 创建打印文档
byte[] bytes = text.getBytes();
Doc doc = new SimpleDoc(bytes, DocFlavor.BYTE_ARRAY.AUTOSENSE, null);
try {
job.print(doc, attributes);
System.out.println("打印任务已发送到: " + printerName);
} catch (PrintException e) {
System.err.println("打印失败: " + e.getMessage());
}
}
// 打印HTML内容
public static void printHTML(String htmlContent) {
try {
// 创建临时HTML文件
File tempFile = File.createTempFile("print", ".html");
try (FileWriter writer = new FileWriter(tempFile)) {
writer.write(htmlContent);
}
// 使用默认程序打开并打印(Windows)
if (System.getProperty("os.name").toLowerCase().contains("win")) {
Runtime.getRuntime().exec(
"rundll32 url.dll,FileProtocolHandler " +
tempFile.getAbsolutePath()
);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、使用Apache PDFBox库打印PDF
首先添加Maven依赖:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.27</version>
</dependency>
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.printing.PDFPrintable;
import org.apache.pdfbox.printing.Scaling;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.awt.print.*;
import java.io.*;
public class PDFPrinter {
// 创建PDF并打印
public static void createAndPrintPDF(String text, String imagePath) {
try (PDDocument document = new PDDocument()) {
PDPage page = new PDPage();
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(
document, page);
// 添加文本
contentStream.beginText();
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);
contentStream.newLineAtOffset(50, 750);
contentStream.showText(text);
contentStream.endText();
// 添加图片
if (imagePath != null) {
PDImageXObject image = PDImageXObject.createFromFile(
imagePath, document);
contentStream.drawImage(image, 100, 400, 300, 300);
}
contentStream.close();
// 保存PDF
document.save("document.pdf");
// 打印PDF
printPDF("document.pdf");
} catch (IOException e) {
e.printStackTrace();
}
}
// 打印PDF文件
public static void printPDF(String pdfPath) throws IOException {
try (PDDocument document = PDDocument.load(new File(pdfPath))) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new PDFPrintable(document, Scaling.SCALE_TO_FIT));
if (job.printDialog()) {
job.print();
}
} catch (PrinterException e) {
e.printStackTrace();
}
}
// 直接打印PDF(无对话框)
public static void silentPrintPDF(String pdfPath) throws IOException {
try (PDDocument document = PDDocument.load(new File(pdfPath))) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new PDFPrintable(document, Scaling.SCALE_TO_FIT));
job.print();
} catch (PrinterException e) {
e.printStackTrace();
}
}
}
四、使用iText库打印
首先添加Maven依赖:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.io.*;
import java.awt.print.*;
public class ITextPrinter {
public static void createPdfAndPrint(String text, String imagePath) {
Document document = new Document();
try {
// 创建PDF文件
PdfWriter writer = PdfWriter.getInstance(
document, new FileOutputStream("output.pdf"));
document.open();
// 添加文本
Font font = FontFactory.getFont(FontFactory.HELVETICA, 12);
Paragraph paragraph = new Paragraph(text, font);
document.add(paragraph);
// 添加图片
if (imagePath != null) {
Image image = Image.getInstance(imagePath);
image.scaleToFit(300, 300);
document.add(image);
}
document.close();
// 打印PDF
printDocument("output.pdf");
} catch (Exception e) {
e.printStackTrace();
}
}
private static void printDocument(String filePath) {
try {
// 使用系统命令打印(Windows)
if (System.getProperty("os.name").toLowerCase().contains("win")) {
Runtime.getRuntime().exec(
"rundll32 SHELL32.DLL,ShellExec_RunDLL " +
"msprint2.dll,MyPrint " + filePath
);
} else {
// Linux/Mac
Runtime.getRuntime().exec("lpr " + filePath);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
五、Web应用中的打印(Java Servlet)
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.awt.print.*;
public class WebPrinterServlet extends HttpServlet {
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String content = request.getParameter("content");
String printerName = request.getParameter("printer");
// 在服务器端打印
if (printOnServer(content, printerName)) {
response.getWriter().write("打印任务已提交");
} else {
response.getWriter().write("打印失败");
}
}
private boolean printOnServer(String content, String printerName) {
try {
PrinterJob job = PrinterJob.getPrinterJob();
// 设置打印机(如果指定)
if (printerName != null && !printerName.isEmpty()) {
PrintService[] services = PrinterJob.lookupPrintServices();
for (PrintService service : services) {
if (service.getName().equals(printerName)) {
job.setPrintService(service);
break;
}
}
}
job.setPrintable(new Printable() {
@Override
public int print(Graphics g, PageFormat pf, int page) {
if (page > 0) return NO_SUCH_PAGE;
Graphics2D g2d = (Graphics2D) g;
g2d.setFont(new Font("宋体", Font.PLAIN, 12));
g2d.drawString(content, 100, 100);
return PAGE_EXISTS;
}
});
job.print();
return true;
} catch (PrinterException e) {
e.printStackTrace();
return false;
}
}
// 生成HTML页面,包含打印按钮
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><title>打印测试</title>");
out.println("<script>");
out.println("function printContent() {");
out.println(" var content = document.getElementById('content').value;");
out.println(" var printWindow = window.open('', '', 'width=800,height=600');");
out.println(" printWindow.document.write('<html><head><title>打印</title></head><body>');");
out.println(" printWindow.document.write('<pre>' + content + '</pre>');");
out.println(" printWindow.document.write('</body></html>');");
out.println(" printWindow.document.close();");
out.println(" printWindow.print();");
out.println("}");
out.println("</script>");
out.println("</head>");
out.println("<body>");
out.println("<h2>打印测试</h2>");
out.println("<textarea id='content' rows='10' cols='50'></textarea><br>");
out.println("<button onclick='printContent()'>打印</button>");
out.println("</body>");
out.println("</html>");
}
}
六、高级打印功能
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import java.util.*;
public class AdvancedPrinter {
// 批量打印
public static void batchPrint(List<String> documents, String printerName) {
PrintService printer = findPrinter(printerName);
if (printer == null) {
System.err.println("打印机未找到: " + printerName);
return;
}
DocPrintJob job = printer.createPrintJob();
PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
for (String doc : documents) {
byte[] bytes = doc.getBytes();
Doc document = new SimpleDoc(bytes,
DocFlavor.BYTE_ARRAY.AUTOSENSE, null);
try {
job.print(document, attributes);
System.out.println("已打印文档: " + doc.substring(0, Math.min(50, doc.length())));
// 延迟一下,避免打印机过载
Thread.sleep(1000);
} catch (Exception e) {
System.err.println("打印失败: " + e.getMessage());
}
}
}
// 查找打印机
private static PrintService findPrinter(String printerName) {
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService service : services) {
if (service.getName().contains(printerName)) {
return service;
}
}
return null;
}
// 获取打印机状态
public static void checkPrinterStatus(String printerName) {
PrintService printer = findPrinter(printerName);
if (printer == null) {
System.out.println("打印机未找到");
return;
}
Attribute[] attributes = printer.getAttributes().toArray();
System.out.println("打印机状态: " + printer.getName());
for (Attribute attr : attributes) {
System.out.println(" " + attr.getName() + ": " + attr);
}
}
// 打印设置类
public static class PrintSettings {
private String printerName;
private int copies = 1;
private boolean duplex = false;
private MediaSizeName paperSize = MediaSizeName.ISO_A4;
private OrientationRequested orientation = OrientationRequested.PORTRAIT;
// getters and setters
public String getPrinterName() { return printerName; }
public void setPrinterName(String printerName) { this.printerName = printerName; }
public int getCopies() { return copies; }
public void setCopies(int copies) { this.copies = copies; }
public boolean isDuplex() { return duplex; }
public void setDuplex(boolean duplex) { this.duplex = duplex; }
public MediaSizeName getPaperSize() { return paperSize; }
public void setPaperSize(MediaSizeName paperSize) { this.paperSize = paperSize; }
public OrientationRequested getOrientation() { return orientation; }
public void setOrientation(OrientationRequested orientation) { this.orientation = orientation; }
}
}
七、实用工具类
import java.awt.*;
import java.awt.print.*;
import javax.print.*;
import javax.print.attribute.*;
import java.io.*;
import java.util.*;
public class PrintUtility {
// 打印图片文件
public static boolean printImageFile(File imageFile) {
try {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new Printable() {
@Override
public int print(Graphics g, PageFormat pf, int pageIndex) {
if (pageIndex > 0) return NO_SUCH_PAGE;
Graphics2D g2d = (Graphics2D) g;
Image image = Toolkit.getDefaultToolkit().getImage(
imageFile.getAbsolutePath());
// 等待图片加载
MediaTracker tracker = new MediaTracker(new Component() {});
tracker.addImage(image, 0);
try {
tracker.waitForID(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 计算缩放比例
double pageWidth = pf.getImageableWidth();
double pageHeight = pf.getImageableHeight();
double imageWidth = image.getWidth(null);
double imageHeight = image.getHeight(null);
double scale = Math.min(
pageWidth / imageWidth,
pageHeight / imageHeight
);
int scaledWidth = (int) (imageWidth * scale);
int scaledHeight = (int) (imageHeight * scale);
// 居中绘制
int x = (int) pf.getImageableX() +
(int) ((pageWidth - scaledWidth) / 2);
int y = (int) pf.getImageableY() +
(int) ((pageHeight - scaledHeight) / 2);
g2d.drawImage(image, x, y, scaledWidth, scaledHeight, null);
return PAGE_EXISTS;
}
});
if (job.printDialog()) {
job.print();
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
// 打印HTML到PDF再打印
public static void printHTMLAsPDF(String htmlContent) {
try {
// 创建临时HTML文件
File htmlFile = File.createTempFile("print", ".html");
try (FileWriter writer = new FileWriter(htmlFile)) {
writer.write(htmlContent);
}
// 使用wkhtmltopdf转换为PDF(需要安装wkhtmltopdf)
File pdfFile = File.createTempFile("print", ".pdf");
String command = String.format("wkhtmltopdf %s %s",
htmlFile.getAbsolutePath(), pdfFile.getAbsolutePath());
Process process = Runtime.getRuntime().exec(command);
process.waitFor();
// 打印PDF
printPDF(pdfFile);
// 清理临时文件
htmlFile.delete();
pdfFile.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void printPDF(File pdfFile) {
// 使用系统打印命令
try {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
// Windows
Runtime.getRuntime().exec(
"rundll32 SHELL32.DLL,ShellExec_RunDLL " +
"msprint2.dll,MyPrint " + pdfFile.getAbsolutePath()
);
} else if (os.contains("mac")) {
// Mac
Runtime.getRuntime().exec(
"lp " + pdfFile.getAbsolutePath()
);
} else {
// Linux
Runtime.getRuntime().exec(
"lp " + pdfFile.getAbsolutePath()
);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 测试方法
public static void main(String[] args) {
// 测试打印文本
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new Printable() {
@Override
public int print(Graphics g, PageFormat pf, int page) {
if (page > 0) return NO_SUCH_PAGE;
Graphics2D g2d = (Graphics2D) g;
g2d.setFont(new Font("Arial", Font.BOLD, 16));
g2d.drawString("测试打印", 100, 100);
g2d.setFont(new Font("Arial", Font.PLAIN, 12));
g2d.drawString("当前时间: " + new Date(), 100, 150);
// 绘制表格
int startY = 200;
g2d.drawLine(100, startY, 300, startY);
g2d.drawString("项目", 110, startY - 5);
g2d.drawString("数量", 210, startY - 5);
startY += 30;
g2d.drawString("商品A", 110, startY);
g2d.drawString("10", 210, startY);
return PAGE_EXISTS;
}
});
try {
if (job.printDialog()) {
job.print();
}
} catch (PrinterException e) {
e.printStackTrace();
}
}
}
八、使用注意事项
1.依赖管理(Maven)
<!-- PDFBox -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.27</version>
</dependency>
<!-- iText -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.3</version>
</dependency>
<!-- 图形处理 -->
<dependency>
<groupId>com.twelvemonkeys.imageio</groupId>
<artifactId>imageio-core</artifactId>
<version>3.8.2</version>
</dependency>
2.错误处理
public class SafePrinter {
public static boolean safePrint(Runnable printTask) {
try {
printTask.run();
return true;
} catch (PrinterException e) {
System.err.println("打印机错误: " + e.getMessage());
return false;
} catch (SecurityException e) {
System.err.println("安全权限错误: " + e.getMessage());
return false;
} catch (Exception e) {
System.err.println("未知错误: " + e.getMessage());
return false;
}
}
}
3.异步打印
public class AsyncPrinter {
public static void printAsync(String content) {
new Thread(() -> {
try {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable((g, pf, page) -> {
// 打印逻辑
return PAGE_EXISTS;
});
job.print();
} catch (PrinterException e) {
e.printStackTrace();
}
}).start();
}
}
总结
选择打印方法:
- 简单文本打印:使用
PrinterJob和Printable接口 - 复杂文档打印:使用PDFBox或iText生成PDF后打印
- Web应用打印:使用Servlet或生成HTML/PDF
- 跨平台需求:使用Java内置API,或调用系统命令
注意事项:
- Java的打印API在不同操作系统上可能有差异
- 处理大图片时注意内存使用
- 生产环境中应添加完善的错误处理
- 考虑使用异步打印避免阻塞主线程
- 注意字体和编码问题(特别是中文)
以上就是Java调用打印机打印图片和文本的多种方法的详细内容,更多关于Java打印机打印图片和文本的资料请关注脚本之家其它相关文章!
