因为项目有个需求要求能够在某个预定时间对特定报表进行自动打印报表的形式主要是excel如果是c++或者c#什么的简直是小菜一碟可惜偏偏是java实现并且这又不同于常见的页面手工打印可以通过javascript调用打印机来实现于是乎开始摸索如何实现该功能
首先想到的是java自带的打印类在javaxprint包下根据jdk说明照着搬来了个程序小试牛刀
view plaincopy to clipboardprint?
/**
* @author xjj
* 说明:打印类
* email:
* @date Oct
*/
public class AutoPrint {
public static void main(String[] args) {
FileInputStream psStream;
try {
psStream = new FileInputStream(fileps);
} catch (FileNotFoundException ffne) {
}
if (psStream == null) {
return;
}
DocFlavor psInFormat = DocFlavorINPUT_STREAMPOSTSCRIPT;
Doc myDoc = new SimpleDoc(psStream psInFormat null);
PrintRequestAttributeSet aset =
new HashPrintRequestAttributeSet();
asetadd(new Copies());
asetadd(MediaSizeA);
asetadd(SidesDUPLEX);
PrintService[] services =
PrintServiceLookuplookupPrintServices(psInFormat aset);
if(serviceslength<){
throw new RuntimeException(找不到打印机);
}
if (serviceslength > ) {
DocPrintJob job = services[]createPrintJob();
try {
jobprint(myDoc aset);
} catch (PrintException pe) {}
}
}
/**
* @author xjj
* 说明:打印类
* email:
* @date Oct
*/
public class AutoPrint {
public static void main(String[] args) {
FileInputStream psStream;
try {
psStream = new FileInputStream(fileps);
} catch (FileNotFoundException ffne) {
}
if (psStream == null) {
return;
}
DocFlavor psInFormat = DocFlavorINPUT_STREAMPOSTSCRIPT;
Doc myDoc = new SimpleDoc(psStream psInFormat null);
PrintRequestAttributeSet aset =
new HashPrintRequestAttributeSet();
asetadd(new Copies());
asetadd(MediaSizeA);
asetadd(SidesDUPLEX);
PrintService[] services =
PrintServiceLookuplookupPrintServices(psInFormat aset);
if(serviceslength<){
throw new RuntimeException(找不到打印机);
}
if (serviceslength > ) {
DocPrintJob job = services[]createPrintJob();
try {
jobprint(myDoc aset);
} catch (PrintException pe) {}
}
}
通过测试始终无法找到打印机运行时报定义的:找不到打印机听说局域网内的打印机无法链接打印机只能连在本机上而测试的打印机刚好在局域网内而不在本机上然后查看了下文档忽然发现java自带的打印只对plain文本gifjpegpdf等支持而对excleword等是不支持的看来要学会放弃goodbye java print
有道是车道山前必有路这不关键时刻jacob出现了根据官方网站的介绍 jacob即Java COM Bridge
充当java和windows平台的桥梁作用通过com组件的方式如果大家不了解com组件可以google一下(顺便鄙视下百度)通过它是我们在java中可以很方便的操作office包括wordexcel等
闲话少说马上开始jacob之旅首先当然是从官网上下载我们必要的资源
进入官网大家会看到这样一段话The JACOB project is moving to Verion 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已经在大名鼎鼎的上安营扎寨了不过不解的是最新版本已经出来了这里介绍的最新版本为什么还是鄙视一下下载的时候除了jacobzip我建议最好把jacob_srczip也下载下来src下有源码demo等等非常有用
解压:jacobzip将jacobjar加入classpath如果是intel平台将jacobxdll加入系统盘的system下比如我的路径是C:\WINDOWS\system 如果是AMD平台则加入jacobxdll
ok 准备就绪开始写代码了本人参照自带的demo实现了简单的打开excel并打印的功能代码如下
view plaincopy to clipboardprint?
/**
* 功能:实现打印工作
* @param path
* @date Oct
* @time :: AM
*/
public static void print(String path){
ComThreadInitSTA();
ActiveXComponent xl = new ActiveXComponent(ExcelApplication);
try {
// Systemoutprintln(version= + xlgetProperty(Version));
//不打开文档
Dispatchput(xl Visible new Variant(true));
Dispatch workbooks = xlgetProperty(Workbooks)toDispatch();
//打开文档
Dispatch excel=Dispatchcall(workbooksOpenpath)toDispatch();
//开始打印
Dispatchget(excelPrintOut);
} catch (Exception e) {
eprintStackTrace();
} finally {
//始终释放资源
ComThreadRelease();
}
}
/**
* 功能:实现打印工作
* @param path
* @date Oct
* @time :: AM
*/
public static void print(String path){
ComThreadInitSTA();
ActiveXComponent xl = new ActiveXComponent(ExcelApplication);
try {
// Systemoutprintln(version= + xlgetProperty(Version));
//不打开文档
Dispatchput(xl Visible new Variant(true));
Dispatch workbooks = xlgetProperty(Workbooks)toDispatch();
//打开文档
Dispatch excel=Dispatchcall(workbooksOpenpath)toDispatch();
//开始打印
Dispatchget(excelPrintOut);
} catch (Exception e) {
eprintStackTrace();
} finally {
//始终释放资源
ComThreadRelease();
}
}
然后运行就会打开路径下的文件然后链接打印机打印而这正是我想要的然后就开始其他操作的摸索了在此基础上通过定时任务生成excel利用jacob进行打印就功成名就了
说个题外话参照demo打开的命令调用是Open关闭的命令调用是Close我想当然认为打印当然是Print莫属了然而jacob真是不按常理出牌啊既然搞个PrintOut真nnd最后还是暴力破解出来的相关文档也没有(不知道是不是本人没有找到)
根据我所掌握的情况有两点需要说明(通过验证)
jacob只适合windows平台如果是linux平台你最终会南辕北辙
在xp下只需要在系统中加入jacobxdll即可但是如果在(估计已经绝技了)或者 server下需要额外的msvcrdll支持可以从通过下载vcredist_xexe进行安装获得下载地址
x?familyid=BFDAEAADCF&displaylang=en
最后说一下我说碰到的几个异常情况
原因没有dll文件
Java代码
Exception in thread main javalangUnsatisfiedLinkError: no jacob in javalibrarypath
at javalangClassLoaderloadLibrary(ClassLoaderjava:)
at javalangRuntimeloadLibrary(Runtimejava:)
at javalangSystemloadLibrary(Systemjava:)
at ComThread(ComThreadjava:)
at combesterhwutilPrintExcelprint(PrintExceljava:)
at combesterhwutilPrintExcelmain(PrintExceljava:)
原因C++库不正确
Java代码
Exception in thread main javalangUnsatisfiedLinkError: C:\apps\\jacobdll: This application has fa
iled to start because the application configuration is incorrect Reinstalling the application may fix this pr
oblem
原因文件路径不正确(因为调用的第一个命令是Open所以这里Invoke of:Open 以此类推)
Java代码
ComFailException: Invoke of: Open
Source: Microsoft Office Excel
原因机子上没有装office
Java代码
cant get Object cldid from progid
好了搞了一个上午也算高点名堂出来了至少找到了一条解决问题的明路一点体会共勉!