项目需要,用户从系统里面下载word文档,该文档进行了填写限制和加密,用户只能在固定位置填写内容。现要求系统验证上传的附件是否从系统上下载下来的。
思路:系统上面的文档都加入一个固定书签,用户上传文档的时候,检验文档里是否包含这个书签。
采用jacob操作word文档
JACOB(java -com bridge)是一个 JAVA到微软的COM接口的桥梁。使用JACOB允许任何JVM访问COM对象,从而使JAVA应用程序能够调用COM对象。
下载地址:http://sourceforge.net/projects/jacob-project/
其中jacob-1.16.1-x64.dll 是用于64位机器上的,jacob-1.16.1-x86.dll用于32位的。
该dll放于 C:\Windows\system32 目录下。jacob.jar放于应用lib底下
测试代码
ActiveXComponent word = null; try { word = new ActiveXComponent("Word.Application"); System.out.println("jacob当前版本:"+word.getBuildVersion()); }catch(Exception e ){ e.printStackTrace(); }
下面再贴出网上常见的代码+自己整理的几个方法(模糊查询书签等)
注意插入书签+书签值的方法,要先插入书签值再选中书签值,之后插入书签。这样根据书签名才能取得书签值。否则根据网络上很多方法,都取不到书签值或者取到空。因为书签值可以是一个点也可以是一大段内容。
import java.io.File; import java.util.HashMap; import java.util.Map; import com.gdcn.bpaf.common.helper.StringHelper; import com.jacob.activeX.ActiveXComponent; import com.jacob.com.ComThread; import com.jacob.com.Dispatch; import com.jacob.com.Variant; /** * * * <p>Description: {jacob操作word类} </p> * * <p>Copyright: Copyright (c) 2011</p> * * <p>CreateDate: 2012-6-28</p> * * @author Beny * @version 1.0 */ public class JacobHelper { // word文档 private Dispatch doc; // word运行程序对象 private ActiveXComponent word; // 所有word文档集合 private Dispatch documents; // 选定的范围或插入点 private Dispatch selection; private boolean saveOnExit = true; public JacobHelper(boolean visible) throws Exception { ComThread.InitSTA();//线程启动 if (word == null) { word = new ActiveXComponent("Word.Application"); word.setProperty("Visible", new Variant(visible)); // 不可见打开word word.setProperty("AutomationSecurity", new Variant(3)); // 禁用宏 } if (documents == null) documents = word.getProperty("Documents").toDispatch(); } /** * 设置退出时参数 * * @param saveOnExit * boolean true-退出时保存文件,false-退出时不保存文件 */ public void setSaveOnExit(boolean saveOnExit) { this.saveOnExit = saveOnExit; } /** * 创建一个新的word文档 * */ public void createNewDocument() { doc = Dispatch.call(documents, "Add").toDispatch(); selection = Dispatch.get(word, "Selection").toDispatch(); } /** * 打开一个已存在的文档 * * @param docPath */ public void openDocument(String docPath) { // closeDocument(); doc = Dispatch.call(documents, "Open", docPath).toDispatch(); selection = Dispatch.get(word, "Selection").toDispatch(); } /** * 只读方式打开一个加密的文档 * * @param docPath-文件全名 * @param pwd-密码 */ public void openDocumentOnlyRead(String docPath, String pwd) throws Exception { // closeDocument(); doc = Dispatch.callN( documents, "Open", new Object[] { docPath, new Variant(false), new Variant(true), new Variant(true), pwd, "", new Variant(false) }) .toDispatch(); selection = Dispatch.get(word, "Selection").toDispatch(); } /** * 打开一个加密的文档 * @param docPath * @param pwd * @throws Exception */ public void openDocument(String docPath, String pwd) throws Exception { // closeDocument(); doc = Dispatch.callN( documents, "Open", new Object[] { docPath, new Variant(false), new Variant(false), new Variant(true), pwd }).toDispatch(); selection = Dispatch.get(word, "Selection").toDispatch(); } /** * 从选定内容或插入点开始查找文本 * * @param toFindText * 要查找的文本 * @return boolean true-查找到并选中该文本,false-未查找到文本 */ @SuppressWarnings("static-access") public boolean find(String toFindText) { if (toFindText == null || toFindText.equals("")) return false; // 从selection所在位置开始查询 Dispatch find = word.call(selection, "Find").toDispatch(); // 设置要查找的内容 Dispatch.put(find, "Text", toFindText); // 向前查找 Dispatch.put(find, "Forward", "True"); // 设置格式 Dispatch.put(find, "Format", "True"); // 大小写匹配 Dispatch.put(find, "MatchCase", "True"); // 全字匹配 Dispatch.put(find, "MatchWholeWord", "false"); // 查找并选中 return Dispatch.call(find, "Execute").getBoolean(); } /** * 把选定选定内容设定为替换文本 * * @param toFindText * 查找字符串 * @param newText * 要替换的内容 * @return */ public boolean replaceText(String toFindText, String newText) { if (!find(toFindText)) return false; Dispatch.put(selection, "Text", newText); return true; } /** * 全局替换文本 * * @param toFindText * 查找字符串 * @param newText * 要替换的内容 */ public void replaceAllText(String toFindText, String newText) { while (find(toFindText)) { Dispatch.put(selection, "Text", newText); Dispatch.call(selection, "MoveRight"); } } /** * 在当前插入点插入字符串 * * @param newText * 要插入的新字符串 */ public void insertText(String newText) { Dispatch.put(selection, "Text", newText); } /** * 设置当前选定内容的字体 * * @param boldSize * @param italicSize * @param underLineSize * 下划线 * @param colorSize * 字体颜色 * @param size * 字体大小 * @param name * 字体名称 * @param hidden * 是否隐藏 */ public void setFont(boolean bold, boolean italic, boolean underLine, String colorSize, String size, String name,boolean hidden) { Dispatch font = Dispatch.get(selection, "Font").toDispatch(); Dispatch.put(font, "Name", new Variant(name)); Dispatch.put(font, "Bold", new Variant(bold)); Dispatch.put(font, "Italic", new Variant(italic)); Dispatch.put(font, "Underline", new Variant(underLine)); Dispatch.put(font, "Color", colorSize); Dispatch.put(font, "Size", size); Dispatch.put(font, "Hidden", hidden); } /** * 文件保存或另存为 * * @param savePath * 保存或另存为路径 */ public void save(String savePath) { Dispatch.call(Dispatch.call(word, "WordBasic").getDispatch(), "FileSaveAs", savePath); } /** * 文件保存为html格式 * * @param savePath * @param htmlPath */ public void saveAsHtml(String htmlPath) { Dispatch.invoke(doc, "SaveAs", Dispatch.Method, new Object[] { htmlPath, new Variant(8) }, new int[1]); } /** * 关闭文档 * * @param val * 0不保存修改 -1 保存修改 -2 提示是否保存修改 */ public void closeDocument(int val) { Dispatch.call(doc, "Close", new Variant(val));//注 是documents而不是doc documents = null; doc = null; } /** * 关闭当前word文档 * */ public void closeDocument() { if (documents != null) { Dispatch.call(documents, "Save"); Dispatch.call(documents, "Close", new Variant(saveOnExit)); documents = null; doc = null; } } public void closeDocumentWithoutSave() { if (documents != null) { Dispatch.call(documents, "Close", new Variant(false)); documents = null; doc = null; } } /** * 保存并关闭全部应用 * */ public void close() { closeDocument(-1); if (word != null) { // Dispatch.call(word, "Quit"); word.invoke("Quit", new Variant[] {}); word = null; } selection = null; documents = null; ComThread.Release();//释放com线程。根据jacob的帮助文档,com的线程回收不由java的垃圾回收器处理 } /** * 打印当前word文档 * */ public void printFile() { if (doc != null) { Dispatch.call(doc, "PrintOut"); } } /** * 保护当前档,如果不存在, 使用expression.Protect(Type, NoReset, Password) * * @param pwd * @param type * WdProtectionType 常量之一(int 类型,只读): * 1-wdAllowOnlyComments 仅批注 * 2-wdAllowOnlyFormFields 仅填写窗体 * 0-wdAllowOnlyRevisions 仅修订 * -1-wdNoProtection 无保护, * 3-wdAllowOnlyReading 只读 * */ public void protectedWord(String pwd,String type) { String protectionType = Dispatch.get(doc, "ProtectionType").toString(); if (protectionType.equals("-1")) { Dispatch.call(doc, "Protect", Integer.parseInt(type), new Variant(true),pwd); } } /** * 解除文档保护,如果存在 * * @param pwd * WdProtectionType 常量之一(int 类型,只读): * 1-wdAllowOnlyComments 仅批注 * 2-wdAllowOnlyFormFields 仅填写窗体 * 0-wdAllowOnlyRevisions 仅修订 * -1-wdNoProtection 无保护, * 3-wdAllowOnlyReading 只读 * */ public void unProtectedWord(String pwd) { String protectionType = Dispatch.get(doc, "ProtectionType").toString(); if (!protectionType.equals("0")&&!protectionType.equals("-1")) { Dispatch.call(doc, "Unprotect", pwd); } } /** * 返回文档的保护类型 * @return */ public String getProtectedType(){ return Dispatch.get(doc, "ProtectionType").toString(); } /** * 设置word文档安全级别 * * @param value * 1-msoAutomationSecurityByUI 使用“安全”对话框指定的安全设置。 * 2-msoAutomationSecurityForceDisable * 在程序打开的所有文件中禁用所有宏,而不显示任何安全提醒。 3-msoAutomationSecurityLow * 启用所有宏,这是启动应用程序时的默认值。 */ public void setAutomationSecurity(int value) { word.setProperty("AutomationSecurity", new Variant(value)); } /** * 在word中插入标签 labelName是标签名,labelValue是标签值 * @param labelName * @param labelValue */ public void insertLabelValue(String labelName,String labelValue) { Dispatch bookMarks = Dispatch.call(doc, "Bookmarks").toDispatch(); boolean isExist = Dispatch.call(bookMarks, "Exists", labelName).getBoolean(); if (isExist == true) { Dispatch rangeItem1 = Dispatch.call(bookMarks, "Item", labelName).toDispatch(); Dispatch range1 = Dispatch.call(rangeItem1, "Range").toDispatch(); String bookMark1Value = Dispatch.get(range1, "Text").toString(); System.out.println("书签内容:"+bookMark1Value); } else { System.out.println("当前书签不存在,重新建立!"); //TODO 先插入文字,再查找选中文字,再插入标签 this.insertText(labelValue); // this.find(labelValue);//查找文字,并选中 this.setFont(true, true,true,"102,92,38", "20", "",true); Dispatch.call(bookMarks, "Add", labelName, selection); Dispatch.call(bookMarks, "Hidden", labelName); } } /** * 在word中插入标签 labelName是标签名 * @param labelName */ public void insertLabel(String labelName) { Dispatch bookMarks = Dispatch.call(doc, "Bookmarks").toDispatch(); boolean isExist = Dispatch.call(bookMarks, "Exists", labelName).getBoolean(); if (isExist == true) { System.out.println("书签已存在"); } else { System.out.println("建立书签:"+labelName); Dispatch.call(bookMarks, "Add", labelName, selection); } } /** * 查找书签 * @param labelName * @return */ public boolean findLabel(String labelName) { Dispatch bookMarks = Dispatch.call(doc, "Bookmarks").toDispatch(); boolean isExist = Dispatch.call(bookMarks, "Exists", labelName).getBoolean(); if (isExist == true) { return true; } else { System.out.println("当前书签不存在!"); return false; } } /** * 模糊查找书签,并返回准确的书签名称 * @param labelName * @return */ public String findLabelLike(String labelName) { Dispatch bookMarks = Dispatch.call(doc, "Bookmarks").toDispatch(); int count = Dispatch.get(bookMarks, "Count").getInt(); // 书签数 Dispatch rangeItem = null; String lname = ""; for(int i=1;i<=count;i++){ rangeItem = Dispatch.call(bookMarks, "Item", new Variant(i)).toDispatch(); lname = Dispatch.call(rangeItem, "Name").toString();//书签名称 if(lname.startsWith(labelName)){//前面匹配 // return lname.replaceFirst(labelName, "");//返回后面值 return lname; } } return ""; } /** * 模糊删除书签 * @param labelName */ public void deleteLableLike(String labelName){ Dispatch bookMarks = Dispatch.call(doc, "Bookmarks").toDispatch(); int count = Dispatch.get(bookMarks, "Count").getInt(); // 书签数 Dispatch rangeItem = null; String lname = ""; for(int i=1;i<=count;i++){ rangeItem = Dispatch.call(bookMarks, "Item", new Variant(i)).toDispatch(); lname = Dispatch.call(rangeItem, "Name").toString();//书签名称 if(lname.startsWith(labelName)){//前面匹配 Dispatch.call(rangeItem, "Delete"); count--;//书签已被删除,书签数目和当前书签都要相应减1,否则会报错:集合找不到 i--; } } } /** * 获取书签内容 * @param labelName * @return */ public String getLableValue(String labelName){ if(this.findLabel(labelName)){ Dispatch bookMarks = Dispatch.call(doc, "Bookmarks").toDispatch(); Dispatch rangeItem1 = Dispatch.call(bookMarks, "Item", labelName).toDispatch(); Dispatch range1 = Dispatch.call(rangeItem1, "Range").toDispatch(); Dispatch font = Dispatch.get(range1, "Font").toDispatch(); Dispatch.put(font, "Hidden", new Variant(false)); //显示书签内容 String bookMark1Value = Dispatch.get(range1, "Text").toString(); System.out.println("书签内容:"+bookMark1Value); // font = Dispatch.get(range1, "Font").toDispatch(); // Dispatch.put(font, "Hidden", new Variant(true)); //隐藏书签内容 return bookMark1Value; } return ""; } public static void main(String[] args) throws Exception { } }
采用jacob方式操作文档,经常会出现卡机的现象,所以最后采用poi方式来操作书签。若单纯的操作书签用poi方式还是比较简单的,但要操作表格、文档格式之类的还是用jacob功能比较强大。
InputStream input = null; File docFile = new File( fileName ); HWPFDocument document = null; try{ input = new FileInputStream(docFile);//加载 doc 文档 document = new HWPFDocument(input);//文件流方式创建hwpf Bookmarks bookmarks = document.getBookmarks();//文档书签 for(int i=0,length=bookmarks.getBookmarksCount();i<length;i++){ bookmarkName = bookmarks.getBookmark(i).getName(); //..... } }catch( Exception e){ }finally{ if( null != input ) input.close(); }
相关推荐
word合并全家桶,包括横页和竖页兼容合并,里面包含使用文件格式转换,rtf转换为标准的word格式或者其他类型转换,jacob合并word案例及jar包,docx4j合并word案例及jar包,还有poi合并,以及Plutext-Enterprise-3.3.0.6...
Java 实现word文件增加图片水印 jacob实现 用到的jar itextpdf-5.5.2和 jacob
最近因项目开发的需要,整理了一份用JAVA导出WORD文档,其部署步骤如下: 1、将jacob-1.14.3-x86.dll放在服务器的系统盘(或运行本机的系统):\WINDOWS\system32目录下。 2、将jacob-1.14.3-x86.dll放在JDK 的 bin ...
Apache_POI_API.rar;jacob.jar;poi-3.0.2.rar
java准确读取word页码,正确率100%,请结合本文查看http://blog.csdn.net/tiandixuanwuliang/article/details/71298406
基于Java语言来导出Word文档的方式也有很多种,如Jacob,Apache POI,Freemarker,PageOffice,java2word 等等。。。。 在这里将通过Freemarker这个模板引擎来实现导出 Word,项目不限于Swing,SSH,SSM,Spring ...
实现word、excel转pdf;自动加盖电子印章;自动加盖二维码。包含itextpdf-5.5.8.jar、core-3.3.0.jar、aspose-words-18.6-jdk16.jar、aspose-cells-8.5.2.jar、jacob.jar、javase-3.3.0.jar
java实现word表格指定位置盖章,并且设置印章悬浮于文字之上,达到跟用实体印章在A4纸上盖章一样的效果
java2word,poi,jacob外加api文档
word文档处理要么用itext写word文档,要么用Poi读word文档,还有用jacob 或者那个java2word ,但是java2word和jacob 不太好的一点就是容易在服务器上生成多个关闭不了的winword.exe线程
批量的实现了指定路径下的doc\docx文档转换为txt文档。
实现将多个word文件合并成一个word文档,整理两种方法,所需资料比较齐全,已经过测试,可直接下载使用。
java通过POI和jacob实现word文档在windows环境下的下载和生成html页面实现在线的预览的工具类。
简单:模板引擎,对POI进行封装,支持Word文档合并、表格处理等 Apache POI 纯Java组件,跨平台 编码 简单,没有模板引擎功能 Freemarker XML操作,跨平台 无 复杂,需要理解XML结构,基于XML构造模板 OpenOffice ...
POI包括一系列的API,它们可以操作基于MicroSoft OLE 2 Compound Document Format的各种格式文件,可以通过这些API在Java中读写Excel、Word等文件。他的excel处理很强大,对于word还局限于读取,目前只能实现一些...
适用于将doc转换成docx maven项目 doc批量转换成docx
针对传统数据导出方法存在处理文档不统一、执行时间长、实现复杂、同步性差等问题,提出运用外观模式,把处理Word文档的JACOB包和处理Excel文档的POI包封装起来,组成一个新的JP类包,并阐述该JP类包封装的具体过程...
网络上有很多种Word转PDF的方式(openoffice,jacob,POI),但都不是很完美,要不依赖三防包还要下载dll文件,要不转换不完美,还不支持中文,我的转换方式使用eclipse自带的swt包即可,程序引用swt的jar后直接运行
POI读取Word文档比较适合、对于生成文档样式比较难控制,iText操作Excel还可以,对Word的操作功能有限,JACOB操作Word实现复杂,并且无法将服务部署到Linux平台,要求安装office,对于实现固定格式的报表实现困难,...
将word文档转化为PDF是项目中常见的需求之一,目前主流的方法可以分为两大类,一类是利用各种Office应用进行转换,譬如Microsoft Office、WPS以及LiberOffice,另一种是利用各种语言提供的对于Office文档读取的接口...