java操作word文档(jacob,poi)

1 篇文章 0 订阅

项目需要,用户从系统里面下载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底下
测试代码
Java代码 收藏代码
ActiveXComponent word = null;
try {
word = new ActiveXComponent(“Word.Application”);
System.out.println(“jacob当前版本:”+word.getBuildVersion());
}catch(Exception e ){
e.printStackTrace();
}
下面再贴出网上常见的代码+自己整理的几个方法(模糊查询书签等)
注意插入书签+书签值的方法,要先插入书签值再选中书签值,之后插入书签。这样根据书签名才能取得书签值。否则根据网络上很多方法,都取不到书签值或者取到空。因为书签值可以是一个点也可以是一大段内容。
Java代码 收藏代码
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;
/**
* *
*

Description: {jacob操作word类}


*
*

Copyright: Copyright (c) 2011


*
*

CreateDate: 2012-6-28


*
* @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功能比较强大。
Java代码 收藏代码
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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值