java操作word文件(jacob,poi)
專案需要,使用者從系統裡面下載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