java平台下通过jacob对excel,word进行打印等操作

本文探讨了使用Java实现自动打印Excel报表的方法。面对项目需求,在尝试Java内置打印功能受阻后,引入了Jacob库,成功实现了Excel文件的自动打印。文章详细记录了实现过程及常见错误处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

因为项目有个需求,要求能够在某个预定时间对特定报表进行自动打印。报表的形式主要是excel。如果是c++或者c#什么的,简直是小菜一碟。可 惜,偏偏是java实现。并且,这又不同于常见的页面手工打印,可以通过javascript调用打印机来实现。于是乎,开始摸索如何实现该功能。
      首先想到的是java自带的打印类。在javax.print包下。根据jdk说明,照着搬来了个程序,小试牛刀。

  1. /**   
  2.  * @author xjj   
  3.  * 说明:打印类   
  4.  * email: exceljava@163.com   
  5.  * @date Oct 29, 2008   
  6.  */     
  7. public   class  AutoPrint {    
  8.     public   static   void  main(String[] args) {    
  9.         FileInputStream psStream;    
  10.         try  {    
  11.            psStream = new  FileInputStream( "file.ps" );    
  12.         } catch  (FileNotFoundException ffne) {    
  13.         }    
  14.         if  (psStream ==  null ) {    
  15.             return ;    
  16.         }    
  17.         DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT;    
  18.         Doc myDoc = new  SimpleDoc(psStream, psInFormat,  null );      
  19.         PrintRequestAttributeSet aset =     
  20.                 new  HashPrintRequestAttributeSet();    
  21.         aset.add(new  Copies( 5 ));    
  22.         aset.add(MediaSize.A4);    
  23.         aset.add(Sides.DUPLEX);    
  24.         PrintService[] services =     
  25.           PrintServiceLookup.lookupPrintServices(psInFormat, aset);    
  26.         if (services.length< 1 ){    
  27.             throw   new  RuntimeException( "找不到打印机" );    
  28.         }    
  29.         if  (services.length >  0 ) {    
  30.            DocPrintJob job = services[0 ].createPrintJob();    
  31.            try  {    
  32.                 job.print(myDoc, aset);    
  33.            } catch  (PrintException pe) {}    
  34.         }    
  35.     
  36.     }    

/** * @author xjj * 说明:打印类 * email: exceljava@163.com * @date Oct 29, 2008 */ public class AutoPrint { public static void main(String[] args) { FileInputStream psStream; try { psStream = new FileInputStream("file.ps"); } catch (FileNotFoundException ffne) { } if (psStream == null) { return; } DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT; Doc myDoc = new SimpleDoc(psStream, psInFormat, null); PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); aset.add(new Copies(5)); aset.add(MediaSize.A4); aset.add(Sides.DUPLEX); PrintService[] services = PrintServiceLookup.lookupPrintServices(psInFormat, aset); if(services.length<1){ throw new RuntimeException("找不到打印机"); } if (services.length > 0) { DocPrintJob job = services[0].createPrintJob(); try { job.print(myDoc, aset); } catch (PrintException pe) {} } }

 

通过测试,始终无法找到打印机,运行时报定义的:找不到打印机。听说,局域网内的打印机无法链接,打印机只能连在本机上。而测试的打印机刚好在局域 网内而不在本机上。然后,查看了下文档,忽然发现,java自带的打印只对plain文本,gif,jpeg,pdf等支持,而对excle,word等 是不支持的。看来要学会放弃,goodbye java print。

       有道是:车道山前必有路。这不,关键时刻,jacob出现了。根据官方网站的介绍 jacob即Java COM Bridge
充当java和windows平台的桥梁作用,通过com组件的方式。如果大家不了解com组件。可以google一下。(顺便鄙视下百度)。通过它,是我们在java中可以很方便的操作office,包括word,excel等。

       闲话少说,马上开始jacob之旅。首先,当然是从官网上下载我们必要的资源。http://danadler.com/jacob/
进 入官网,大家会看到这样一段话:The JACOB project is moving to Sourceforge.net. Verion 1.8 is now available at Sourceforge. If you are a sourceforge developer and are interested in contributing to the project, please contact the project administrators. 也就是jacob已经在大名鼎鼎的Sourceforge.net上安营扎寨了。不过不解的是,最新版本1.14 已经出来了,这里介绍的最新版本为什么还是1.8.鄙视一下。下载的时候,除了jacob-1 .14 .3.zip,我建议最好把jacob-1 .14 .3_src.zip也下载下来。src下有源码,demo等等,非常有用。
      解压:jacob-1 .14 .3.zip,将jacob.jar加入classpath,如果是intel平台,将jacob-1 .14 .3-x86 .dll加入系统盘的system32下。比如我的路径是:C:\WINDOWS\system32 如果是AMD平台,则加入:jacob-1 .14 .3-x64.dll,       

      ok, 准备就绪。开始写代码了,本人参照自带的demo实现了简单的打开excel并打印的功能。代码如下:

  1. /**   
  2. * 功能:实现打印工作   
  3. * @param path   
  4. * @date Oct 29, 2008   
  5. * @time 11:40:03 AM   
  6. */    
  7. public   static   void  print(String path){   
  8. ComThread.InitSTA();   
  9. ActiveXComponent xl = new  ActiveXComponent( "Excel.Application" );   
  10. try  {   
  11. // System.out.println("version=" + xl.getProperty("Version"));    
  12. //不打开文档    
  13. Dispatch.put(xl, "Visible"new  Variant( true ));   
  14. Dispatch workbooks = xl.getProperty("Workbooks" ).toDispatch();   
  15. //打开文档    
  16. Dispatch excel=Dispatch.call(workbooks,"Open" ,path).toDispatch();   
  17. //开始打印    
  18. Dispatch.get(excel,"PrintOut" );   
  19. catch  (Exception e) {   
  20. e.printStackTrace();   
  21. finally  {   
  22. //始终释放资源    
  23. ComThread.Release();   
  24. }   
  25. }  

/** * 功能:实现打印工作 * @param path * @date Oct 29, 2008 * @time 11:40:03 AM */ public static void print(String path){ ComThread.InitSTA(); ActiveXComponent xl = new ActiveXComponent("Excel.Application"); try { // System.out.println("version=" + xl.getProperty("Version")); //不打开文档 Dispatch.put(xl, "Visible", new Variant(true)); Dispatch workbooks = xl.getProperty("Workbooks").toDispatch(); //打开文档 Dispatch excel=Dispatch.call(workbooks,"Open",path).toDispatch(); //开始打印 Dispatch.get(excel,"PrintOut"); } catch (Exception e) { e.printStackTrace(); } finally { //始终释放资源 ComThread.Release(); } }

 

然后,运行,就会打开路径下的文件,然后链接打印机,打印。而这,正是我想要的。然后就开始其他操作的摸索了。在此基础上,通过定时任务,生成excel,利用jacob进行打印。就功成名就了。
      说个题外话,参照demo,打开的命令调用是Open,关闭的命令调用是Close,我想当然认为,打印当然是Print莫属了。然而,jacob真是不按常理出牌啊,既然搞个PrintOut ,真nnd。最后还是暴力破解出来的。相关文档也没有(不知道是不是本人没有找到).

      根据我所掌握的情况,有两点需要说明(通过验证):
     1.jacob只适合windows平台,如果是linux平台,你最终会南辕北辙。
     2.在xp下,只需要在系统中加入jacob-1 .14 .3-x86 .dll即可。但是如果在2000(估计已经绝技了)或者2003 server下,需要额外的msvcr80.dll支持,可以从通过下载vcredist_x86.exe进行安装获得。下载地址:http://www.microsoft.com/downloads/details.aspx?familyid=200B2FD9-AE1A-4A14-984D-389C36F85647&displaylang=en

最后说一下,我说碰到的几个异常情况:
001 原因:没有dll文件:

Java代码 < type="application/x-shockwave-flash" width="14" height="15" src="http://exceljava.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=Exception%20in%20thread%20%22main%22%20java.lang.UnsatisfiedLinkError%3A%20no%20jacob%20in%20java.library.path%0A%20at%20java.lang.ClassLoader.loadLibrary(ClassLoader.java%3A1682)%0A%20at%20java.lang.Runtime.loadLibrary0(Runtime.java%3A823)%0A%20at%20java.lang.System.loadLibrary(System.java%3A1030)%0A%20at%20com.jacob.com.ComThread.%3Cclinit%3E(ComThread.java%3A153)%0A%20at%20com.bester.hw.util.PrintExcel.print(PrintExcel.java%3A25)%0A%20at%20com.bester.hw.util.PrintExcel.main(PrintExcel.java%3A16)">
  1. Exception in thread  "main"  java.lang.UnsatisfiedLinkError: no jacob in java.library.path  
  2.  at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682 )  
  3.  at java.lang.Runtime.loadLibrary0(Runtime.java:823 )  
  4.  at java.lang.System.loadLibrary(System.java:1030 )  
  5.  at com.jacob.com.ComThread.<clinit>(ComThread.java:153 )  
  6.  at com.bester.hw.util.PrintExcel.print(PrintExcel.java:25 )  
  7.  at com.bester.hw.util.PrintExcel.main(PrintExcel.java:16 )  

 
002 原因:C++库不正确:

Java代码 < type="application/x-shockwave-flash" width="14" height="15" src="http://exceljava.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=Exception%20in%20thread%20%22main%22%20java.lang.UnsatisfiedLinkError%3A%20C%3A%5Capps%5C...%5Cjacob.dll%3A%20This%20application%20has%20fa%20%0Ailed%20to%20start%20because%20the%20application%20configuration%20is%20incorrect.%20Reinstalling%20the%20application%20may%20fix%20this%20pr%20%0Aoblem%20">
  1. Exception in thread  "main"  java.lang.UnsatisfiedLinkError: C:\apps\...\jacob.dll: This application has fa   
  2. iled to start because the application configuration is incorrect. Reinstalling the application may fix this  pr   
  3. oblem   

003 原因:文件路径不正确(因为调用的第一个命令是Open,所以这里Invoke of:Open ,以此类推):

Java代码 < type="application/x-shockwave-flash" width="14" height="15" src="http://exceljava.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=%20com.jacob.com.ComFailException%3A%20Invoke%20of%3A%20Open%0A%20Source%3A%20Microsoft%20Office%20Excel">
  1. com.jacob.com.ComFailException: Invoke of: Open  
  2. Source: Microsoft Office Excel  

 004 原因:机子上没有装office

Java代码 < type="application/x-shockwave-flash" width="14" height="15" src="http://exceljava.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=cant%20get%20Object%20cldid%20from%20progid">
  1. cant get Object cldid from progid  

好了,搞了一个上午,也算高点名堂出来了。至少找到了一条解决问题的明路。一点体会,共勉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值