首页 > 代码库 > Java打印pdf方法的记录

Java打印pdf方法的记录

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public class PrintDemo {  
  2.   
  3.     public static void main(String[] args) {  
  4.         JFileChooser fileChooser = new JFileChooser(); // 创建打印作业  
  5.         int state = fileChooser.showOpenDialog(null);  
  6.         if (state == JFileChooser.APPROVE_OPTION) {  
  7.             File file = fileChooser.getSelectedFile(); // 获取选择的文件  
  8.             // 构建打印请求属性集  
  9.             HashPrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();  
  10.             // 设置打印格式,因为未确定类型,所以选择autosense  
  11.             DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;  
  12.             // 查找所有的可用的打印服务  
  13.             PrintService printService[] = PrintServiceLookup  
  14.                     .lookupPrintServices(flavor, pras);  
  15.             // 定位默认的打印服务  
  16.             PrintService defaultService = PrintServiceLookup  
  17.                     .lookupDefaultPrintService();  
  18.             // 显示打印对话框  
  19.             PrintService service = ServiceUI.printDialog(null, 200, 200,  
  20.                     printService, defaultService, flavor, pras);  
  21.             if (service != null) {  
  22.                 try {  
  23.                     DocPrintJob job = service.createPrintJob(); // 创建打印作业  
  24.                     FileInputStream fis = new FileInputStream(file); // 构造待打印的文件流  
  25.                     DocAttributeSet das = new HashDocAttributeSet();  
  26.                     Doc doc = new SimpleDoc(fis, flavor, das);  
  27.                     job.print(doc, pras);  
  28.                 } catch (Exception e) {  
  29.                     e.printStackTrace();  
  30.                 }  
  31.             }  
  32.         }  
  33.     }  
  34. }  

但是经过尝试之后,发现pdf文件并没有以pdf的格式打印出来,而是打印出乱码(也就是文件的二进制码)

初步猜想是打印机无法识别吧。于是将上面的DocFlavor改成DocFlavor.INPUT_STREAM.PDF;

那么printService[]将会为null,为什么呢?因为lookupDefaultPrintService()方法只会返回支持docFlavor的打印机~

若未通过docFlavor来过滤打印机,而直接进行打印时,会报错:invalid flavor,也就是不支持该类型~

其实我们看docFlavor,它其实也就是发送到打印机的数据流的content-type,类似到web中,也就是不支持该content-type,那么就比较容易理解了。


那怎么办呢?难道我们就没办法通过Java程序来打印pdf文件了吗?不管有没有,至少要去试试吧~

发现网上并没有特别好的解决方案。大概收集了几种:

1、比较偷懒的方法,调外挂程序来实现打印,最典型的就是Adobe Reader

2、使用PdfRenderer等第三方库先将pdf文件转换成图片,那么就可以调用PrintService来打印了


先说第一种方法吧~

首先你的电脑上得装上Adobe Reader,调用Adobe Reader来打印需要依赖acrord32这个命令

我们知道在Java中要调用命令行需要Runtime对象,具体代码如下:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public static boolean printPdf(String pdfPath){  
  2.         try{  
  3.             Runtime.getRuntime().exec("cmd.exe /C start acrord32 /P /h " + pdfPath);  
  4.             return true;  
  5.         }catch(Exception e){  
  6.             e.printStackTrace();  
  7.             return false;  
  8.         }  
  9.     }  

这里调用了Adobe Reader的acrord32.exe方法,下面来介绍下这个命令的参数。 

acrord32.exe filename - 执行Adobe Reader,并且浏览PDF 

其他还支持的参数有: 

AcroRd32.exe /p filename - 执行Adobe Reader,并且打印一个PDF文件 

AcroRd32.exe /t path printername drivername portname 

初始化Adobe Reader, 不弹出打印对话框,然后结束打印 

/t 命令所需的四个参数有 

path - 打印文件路径 

printername - 打印机名字 

drivername - 打印机驱动名字 

portname - 打印机端口 

其他的参数: 

/n 开一个新的Adobe Reader, 尽管有Adobe Reader已经打开 (静默打印不用) 

/s 打开一个Adobe Reader不开splash screen 

/o 打开一个Adobe Reader不开打开文件对话框 

/h 以最小化方式打开一个Adobe Reader (静默打印使用)

Java打印pdf方法的记录