目录

我的学习分享

记录精彩的程序人生

【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服务登录身份设置为域账号即可。

15736084121.png

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();
		}
	}
}