使用Jacob实现Word转换Html

2023-11-05 20:10

本文主要是介绍使用Jacob实现Word转换Html,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

       源于一个项目的需求,用户上传Word文件后要能及时在网页上查看文件内容,类似于QQ邮箱的附件查看,QQ邮箱使用的是永中的产品工具。自己做当然是首选不要钱自己写代码就能搞定的。网上搜索后找到了Jacob,下面记录一下使用过程和自己使用中的一些心得。

环境

       在项目中引入jacob.jar。复制jacob-1.16.1-x86.dll到jdk\bin目录,放置dll的位置网上有两种说法,一种是jdk\bin另一种是system32。其实只要放在path目录下即可,java中查看path目录的方式:System.getProperty("java.library.path")。另外切勿修改dll的文件名称,因为jacob.jar中已经写好了dll的名称,改了dll的名称后调用时就找不到了。下载的Jacob里面一般会包含x86和x64两个dll,使用哪一个是与jdk的版本相关的,与操作系统版本无关。

代码

常规方式

//word文件路径及名称
String docPath = "D:\\download\\word\\1.docx";
//html文件路径及名称
String fileName = "D:\\download\\html\\1.html";
//创建Word对象,启动WINWORD.exe进程
ActiveXComponent app = new ActiveXComponent("Word.Application");
//设置用后台隐藏方式打开
app.setProperty("Visible", new Variant(false));
//获取操作word的document调用
Dispatch documents = app.getProperty("Documents").toDispatch();
//调用打开命令,同时传入word路径
Dispatch doc = Dispatch.call(documents, "Open", docPath).toDispatch();
//调用另外为命令,同时传入html的路径
Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { fileName, new Variant(8) }, new int[1]);
//关闭document对象
Dispatch.call(doc, "Close", new Variant(0));
//关闭WINWORD.exe进程
Dispatch.call(app, "Quit");
//清空对象
doc = null;
app = null;

       如果word文件包含图片,那么会生成与html同名的1.files文件夹。这与在IE浏览器中使用右键另存为网页一样。

       以上方式在每次调用时系统会创建WINWORD.exe进程,然后再关闭。要知道系统创建进程是非常耗资源的,时间和CPU。我做了一个简单的测试,将1.docx文件复制了30份,循环调用30次,用时76秒。

long start = System.currentTimeMillis();
JacobUtil jacobUtil = new JacobUtil();
for (int i = 1; i <= 30; i++) {
<span style="white-space:pre">	</span>jacobUtil.wordConvert("D:\\download\\word\\"+i+".docx", "D:\\download\\html\\"+i+".html");
}
long end = System.currentTimeMillis();
System.out.println("用时:"+(end-start)/1000L+"秒");

单例方式

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;public class JacobUtil {private static ActiveXComponent app;/*** 单例模式*/public static ActiveXComponent getWordInstance(){if (app == null) {app = new ActiveXComponent("Word.Application");app.setProperty("Visible", new Variant(false));}return app;}/*** 转换word*/public static void wordConvertSingleton(String docPath, String fileName) {try {app = getWordInstance();Dispatch documents = app.getProperty("Documents").toDispatch();Dispatch doc = Dispatch.call(documents, "Open", docPath).toDispatch();Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { fileName, new Variant(8) }, new int[1]);Dispatch.call(doc, "Close", new Variant(0));//没有调用Quit命令doc = null;} catch (Exception e) {e.printStackTrace();}}
}
       单例方式将只有一个ActiveXComponet,那么WINWORD.exe进程也只会有一个,不会重复创建关闭进程,而是一直使用这个进程。转换30次,只需14秒。

long start = System.currentTimeMillis();
for (int i = 1; i <= 30; i++) {
<span style="white-space:pre">	</span>JacobUtil.wordConvertSingleton("D:\\download\\word\\"+i+".docx", "D:\\download\\html\\"+i+".html");
}
long end = System.currentTimeMillis();
System.out.println("单例用时:"+(end-start)/1000L+"秒");

多线程方式

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;public class ThreadConvert implements Runnable{private  ActiveXComponent app;private String docPath;private String fileName;public ThreadConvert(ActiveXComponent app,String docPath, String fileName) {this.app = app;this.docPath = docPath;this.fileName = fileName;}public void run() {System.out.println("开始:"+System.currentTimeMillis());try {app.setProperty("Visible", new Variant(false));Dispatch documents = app.getProperty("Documents").toDispatch();Dispatch doc = Dispatch.call(documents, "Open", docPath).toDispatch();Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { fileName, new Variant(8) }, new int[1]);Dispatch.call(doc, "Close", new Variant(0));doc = null;} catch (Exception e) {e.printStackTrace();}System.out.println("结束:"+System.currentTimeMillis());}
}
ActiveXComponent app1 = new ActiveXComponent("Word.Application");
for (int i = 1; i <= 30; i++) {Thread thread = new Thread(new ThreadConvert(app1,"D:\\download\\word\\"+i+".docx", "D:\\download\\html\\"+i+".html"));thread.start();
}
       因为线程执行不好计时,使用的是找出最早的开始时间与最晚的结束时间相减是15秒,与单例方式相近。

多进程方式

ActiveXComponent app1 = new ActiveXComponent("Word.Application");
ActiveXComponent app2 = new ActiveXComponent("Word.Application");
ActiveXComponent app3 = new ActiveXComponent("Word.Application");
for (int i = 1; i <= 30; i++) {
<span style="white-space:pre">	</span>if (i<=10) {Thread thread = new Thread(new ThreadConvert(app1,"D:\\download\\word\\"+i+".docx", "D:\\download\\html\\"+i+".html"));thread.start();}else if(i <= 20){Thread thread = new Thread(new ThreadConvert(app2,"D:\\download\\word\\"+i+".docx", "D:\\download\\html\\"+i+".html"));thread.start();}else {Thread thread = new Thread(new ThreadConvert(app3,"D:\\download\\word\\"+i+".docx", "D:\\download\\html\\"+i+".html"));thread.start();}
}
       使用三个ActiveXComponent,也就是三个WINWORD.exe进程,每个进程分配10个转换任务,同样用最早的开始时间与最晚的结束时间相减是9秒。

这篇关于使用Jacob实现Word转换Html的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/352210

相关文章

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

Redis客户端连接机制的实现方案

《Redis客户端连接机制的实现方案》本文主要介绍了Redis客户端连接机制的实现方案,包括事件驱动模型、非阻塞I/O处理、连接池应用及配置优化,具有一定的参考价值,感兴趣的可以了解一下... 目录1. Redis连接模型概述2. 连接建立过程详解2.1 连php接初始化流程2.2 关键配置参数3. 最大连

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

使用IDEA部署Docker应用指南分享

《使用IDEA部署Docker应用指南分享》本文介绍了使用IDEA部署Docker应用的四步流程:创建Dockerfile、配置IDEADocker连接、设置运行调试环境、构建运行镜像,并强调需准备本... 目录一、创建 dockerfile 配置文件二、配置 IDEA 的 Docker 连接三、配置 Do

Android Paging 分页加载库使用实践

《AndroidPaging分页加载库使用实践》AndroidPaging库是Jetpack组件的一部分,它提供了一套完整的解决方案来处理大型数据集的分页加载,本文将深入探讨Paging库... 目录前言一、Paging 库概述二、Paging 3 核心组件1. PagingSource2. Pager3.

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所