项目需要,用户从系统里面下载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(); }
相关推荐
总的来说,Java操作Word-Jacob是一种有效的技术,特别适合那些需要在Java环境中处理大量Word文档或者需要对Word文档进行深度定制的应用场景。不过,需要根据项目需求和目标平台来权衡选择哪种方法最合适。
总结来说,Java读取Word文档页数可以通过两种主要途径:一是直接使用Jacob库操作Word文档;二是先将Word转换为PDF,再使用iTextPDF库读取PDF的页数。这两种方法各有优劣,应根据具体项目需求和环境选择合适的方法。
word合并全家桶,包括横页和竖页兼容合并,里面包含使用文件格式转换,rtf转换为标准的word格式或者其他类型转换,jacob合并word案例及jar包,docx4j合并word案例及jar包,还有poi合并,以及Plutext-Enterprise-3.3.0.6...
为了在Java中操作Word文档,我们可以利用第三方库,其中最常用的是Jacob库。这个库提供了Java与COM(Component Object Model)接口的桥梁,使得Java能够调用Windows API,从而实现对Office应用如Word的操作。 Jacob...
这意味着你可以直接通过Jacob来操作Word文档,进行文本替换、段落格式调整、图片插入等操作。 - 加载Word应用:`ActiveXObject activeObject = new ActiveXObject("Word.Application");` - 打开Word文档:`...
Jacob库为Java开发者提供了一个与Microsoft Office交互的解决方案,允许在Java应用程序中操纵Word文档。Jacob库实际上是Java和COM(Component Object Model)之间的桥梁,使得Java能够调用Windows平台上的Office API...
总的来说,"java操作word文档的jacob.jar"提供了在Java中便捷操作Word文档的能力,但需要在适当的系统环境下使用,并注意性能和兼容性的问题。在开发过程中,应充分测试并优化代码,以确保程序的稳定性和效率。
在处理文档操作时,Java提供了一些库来实现高级功能,比如在Word文档中添加图片水印。本篇将深入探讨如何使用Java和两个特定的库——iTextPDF与Jacob——来实现这一目标。 首先,iTextPDF是一个开源的Java库,专门...
本主题将深入探讨如何使用Apache POI API和Jacob库来读取和操作Word文档。 Apache POI是一个流行的开源Java API,专为处理Microsoft Office格式的文件而设计。它允许开发者在Java应用程序中创建、修改和显示MS ...
在本文中,我们将深入探讨使用Jacob 16在Java中操作Office文档的关键知识点。 首先,Jacob库的核心是通过Java Native Interface (JNI) 实现的,它使得Java代码能够与本地Windows系统中的COM组件交互。因此,Jacob...
- 由于Apache POI和JACOB处理的是Office文档的内部结构,因此可能需要对Word文档的格式有深入理解,以避免操作过程中出现格式丢失或错误。 - 在实际应用中,确保正确处理并发和资源释放,以防止文件锁或其他资源...
总的来说,Jacob为Java开发者提供了一种强大的工具,可以直接在代码中操作Word文档,进行诸如目录分析、段落处理等任务。虽然你已经实现了文本的处理,但进一步探索Range对象的功能,将使你能够处理更丰富的文档元素...
总结来说,Java结合JACOB工具提供了一种有效的方法来操作Word文档,无论是读取还是写入,都为开发者提供了便利。然而,这种方式有一定的局限性,特别是在跨平台应用上。通过理解这些基本操作,你可以根据需求灵活地...
在这个“Jacob操作word文档的方法集”中,我们将探讨如何使用Jacob 1.5版本来创建和操作Word文档,特别是创建目录。 首先,为了使用Jacob,你需要在你的项目中添加Jacob的jar文件。这通常涉及到将库添加到项目的类...
除了Jacob,还有其他一些Java库可以处理Word文档,如Apache POI、Aspose.Words等,它们不需要依赖COM组件,但可能功能相对有限。 通过以上知识,开发者可以利用Jacob在Java中高效地处理Word文档,实现自动化办公...
JACOB通过JNI(Java Native Interface)技术,使得Java可以利用COM对象,从而在没有使用ActiveX控件或服务器的情况下操作Word文档。 在Java中使用JACOB打印Word文档,首先需要安装JACOB库,并将其添加到项目的类...
总的来说,Java通过JACOB库可以有效地处理Word文档的复杂操作,如插入水印和设置保护密码,从而满足OA系统的需求。在实际开发中,应确保正确处理异常,并考虑性能优化,比如关闭Word应用程序时确保所有资源已释放。
在给定的文件内容中可以看到“APIjava2Wordjacobpoijava2Wordjacobitext”这样的字符串,虽然因为错误的OCR识别和重复字符而不太清晰,但可以推测这是在尝试说明使用API或者POI库来处理Word文档。 2. Jacob库:...
最近因项目开发的需要,整理了一份用JAVA导出WORD文档,其部署步骤如下: 1、将jacob-1.14.3-x86.dll放在服务器的系统盘(或运行本机的系统):\WINDOWS\system32目录下。 2、将jacob-1.14.3-x86.dll放在JDK 的 bin ...