读书人

java平台上通过jacob对excel,word进行

发布时间: 2012-10-12 10:17:04 作者: rapoo

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

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

/** * @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. Verion1.8 is now available at Sourceforge. If you are a sourceforge developerand are interested in contributing to the project, please contact theproject administrators.也就是jacob已经在大名鼎鼎的Sourceforge.net上安营扎寨了。不过不解的是,最新版本1./** * 功能:实现打印工作 * @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下,只需要在系统中加入cant?get?Object?cldid?from?progid??

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

1 楼 minfirefox 2010-07-28 请问你知道这是什么原因吗?
在win2003下出现cant get Object cldid from progid 2 楼 linchixiong 2011-05-09 学习了,谢谢~ 3 楼 antony102201 2011-12-21 有没有支持通过java调用Adobe_PDF_Printer来打印一些可以打印的文件啊

读书人网 >软件架构设计

热点推荐