【jacob】异常Dispatch not hooked to windows memory
在使用jacob将word文档转pdf时(这是目前将word文档转pdf最可靠的方式,缺点是只能在windows下运行),报Dispatch not hooked to windows memory,网上好多重复的帖子都没有解决。在经历了长达一天半的纠结,最后在一篇帖子中获得了灵感(具体那篇帖子找不到了,感谢原作者),是因为调用jacob将Word转pdf时,会在tomcat目录下的temp目录中生成临时的pdf文件,而在异常抛出之前,该pdf文件已经生成,但是大小是0KB,原因是没有权限写文件。正常情况下不会这样,但因为我这里是通过tomcat服务器启动的,而且是域账号登录的Windows Server 2008系统,所以会没有权限写入。将tomcat服务登录身份设置为域账号即可。

package xxx.transfer.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
public class JacobUtil {
private static final Logger logger = LoggerFactory.getLogger(JacobUtil.class);
// 17代表word保存成pdf
public static final int WD2PDF = 17;
// static {
// // @see https://www.zhihu.com/question/37063799/answer/70242462
// try {
// URL url = new URL("file:/C:/Windows/System32/jacob-1.18-x86.dll");
// File x86File = new File(url.toURI());
// if(!x86File.exists()) {
// logger.debug("System32目录中未发现jacob-1.18-x86.dll,拷贝一份");
// MyZipUtil.unZip(JacobUtil.class.getResourceAsStream("/jacob-1.18.dll.zip"), "C:/Windows/System32");
// }
//
// url = new URL("file:/C:/Windows/SysWOW64/jacob-1.18-x64.dll");
// File x64File = new File(url.toURI());
// if(!x64File.exists()) {
// logger.debug("SysWOW64目录中未发现jacob-1.18-x64.dll,拷贝一份");
// MyZipUtil.unZip(JacobUtil.class.getResourceAsStream("/jacob-1.18.dll.zip"), "C:/Windows/SysWOW64");
// }
// } catch (URISyntaxException | IOException e) {
// logger.warn("copy jacob dll to System32 and SysWOW64 failed!", e);
// }
//
// }
// 将word文件转换为Pdf文件
public static void word2pdf(String docfile, String pdffile) {
// 启动word应用程序(Microsoft Office Word 2003)
ActiveXComponent app = null;
try {
ComThread.InitSTA();
app = new ActiveXComponent("Word.Application");
app.setProperty("Visible", false);
// 设置word应用程序不可见
// app.setProperty("Visible", new Variant(false));
// documents表示word程序的所有文档窗口,(word是多文档应用程序�?
Dispatch docs = app.getProperty("Documents").toDispatch();
// 打开要转换的word文件
/*
* Dispatch doc = Dispatch.invoke( docs, "Open", Dispatch.Method,
* new Object[] { docfile, new Variant(false), new Variant(true) },
* new int[1]).toDispatch();
*/
Dispatch doc = Dispatch.call(docs, "Open", docfile, false, false).toDispatch();
// 调用Document对象的saveAs方法,将文档保存为pdf格式
/*
* Dispatch.invoke(doc, "ExportAsFixedFormat", Dispatch.Method, new
* Object[] { pdffile, new Variant(wdFormatPDF) }, new int[1]);
*/
Dispatch.call(doc, "ExportAsFixedFormat", pdffile, WD2PDF);
// 关闭word文件
Dispatch.call(doc, "Close", false);
} catch (Exception e) {
ComThread.Release();
e.printStackTrace();
logger.warn("", e);
} finally {
// 关闭word应用程序
app.invoke("Quit", 0);
ComThread.Release();
}
}
}