Java如何对excel,word进行打印操作

原创|其它|编辑:郝浩|2010-01-05 10:10:00.000|阅读 6277 次

概述:因为项目有个需求,要求能够在某个预定时间对特定报表进行自动打印。报表的形式主要是excel。如果是c++或者c#什么的,简直是小菜一碟。可惜,偏偏是java实现。并且,这又不同于常见的页面手工打印,可以通过javascript调用打印机来实现。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

  因为项目有个需求,要求能够在某个预定时间对特定报表进行自动打印。报表的形式主要是excel。如果是c++或者c#什么的,简直是小菜一碟。可惜,偏偏是java实现。并且,这又不同于常见的页面手工打印,可以通过javascript调用打印机来实现。于是乎,开始摸索如何实现该功能。

  首先想到的是java自带的打印类。在javax.print包下。根据jdk说明,照着搬来了个程序,小试牛刀。

 view plaincopy to clipboardprint?
  /**
  * @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) {}
  }
  }
  /**
  * @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并打印的功能。代码如下:

  view plaincopy to clipboardprint?
  /**
  * 功能:实现打印工作
  * @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();
  }
  }
  /**
  * 功能:实现打印工作
  * @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代码


    Exception in thread "main" java.lang.UnsatisfiedLinkError: no jacob in java.library.path
  at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)
  at java.lang.Runtime.loadLibrary0(Runtime.java:823)
  at java.lang.System.loadLibrary(System.java:1030)
  at com.jacob.com.ComThread.(ComThread.java:153)
  at com.bester.hw.util.PrintExcel.print(PrintExcel.java:25)
  at com.bester.hw.util.PrintExcel.main(PrintExcel.java:16)


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

  Java代码


  Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\apps\...\jacob.dll: This application has fa
  iled to start because the application configuration is incorrect. Reinstalling the application may fix this pr
  oblem


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

  Java代码


  com.jacob.com.ComFailException: Invoke of: Open
  Source: Microsoft Office Excel


  004 原因:机子上没有装office

  Java代码

  cant get Object cldid from progid

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


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:网络转载

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP