Java通過jacob生成動態word,還有一種方法通過word書籤實現
多個word合併
先下載jacob.jar包。
如果是32位系統 將jacob-1.18-x86.dll 檔案複製到下面目錄下,如果是64位作業系統 將jacob-1.18-x64.dll C:\Program Files\Java\jdk1.8.0_45\jre\bin
將jacob.jar增加專案。
這樣專案的環境基本上搭建完畢,接下來就是書寫相關的程式碼:
/**
* 傳入資料為HashMap物件,物件中的Key代表word模板中要替換的欄位。Value代表用來替換的值。
* word模板中全部要替換的欄位(即HashMap中的Key)以特殊字元開頭和結尾。
* 如:$code$、$date$……。以免執行錯誤的替換。
* 全部要替換為圖片的欄位,Key中需包括image或者Value為圖片的全路徑
* (眼下僅僅推斷檔案字尾名為:.bmp、.jpg、.gif)。
* 要替換表格中的資料時,HashMap中的Key格式為“[email protected]”,當中:
* R代表從表格的第R行開始替換,N代表word模板中的第N張表格;
* Value為ArrayList物件,ArrayList中包括的物件統一為String[],一條String[]代表一行資料。
* ArrayList中第一條記錄為特殊記錄。記錄的是表格中要替換的列號,
* 如:要替換第一列、第二列、第三列的資料。則第一條記錄為String[3] {"1","2","3"}。
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
/**
* 利用word模板生成word檔案
* @typename:Java2word
* @author: FishRoad
* @since: 2015年8月24日 下午2:47:41
*
*/
public class Java2word {
private boolean saveOnExit;
/**
* word文件
*/
Dispatch doc = null;
/**
* word執行程式物件s
*/
private ActiveXComponent word;
/**
* 全部word文件
*/
private Dispatch documents;
/**
* 建構函式
*/
public Java2word() {
if(word==null){
word = new ActiveXComponent("Word.Application");
word.setProperty("Visible",new Variant(false));
}
if(documents==null)
documents = word.getProperty("Documents").toDispatch();
saveOnExit = false;
}
/**
* 設定引數:退出時是否儲存
* @param saveOnExit boolean true-退出時儲存檔案,false-退出時不儲存檔案
*/
public void setSaveOnExit(boolean saveOnExit) {
this.saveOnExit = saveOnExit;
}
/**
* 得到引數:退出時是否儲存
* @return boolean true-退出時儲存檔案,false-退出時不儲存檔案
*/
public boolean getSaveOnExit() {
return saveOnExit;
}
/**
* 開啟檔案
* @param inputDoc String 要開啟的檔案,全路徑
* @return Dispatch 開啟的檔案
*/
public Dispatch open(String inputDoc) {
return Dispatch.call(documents,"Open",inputDoc).toDispatch();
}
/**
* 選定內容
* @return Dispatch 選定的範圍或插入點
*/
public Dispatch select() {
return word.getProperty("Selection").toDispatch();
}
/**
* 把選定內容或插入點向上移動
* @param selection Dispatch 要移動的內容
* @param count int 移動的距離
*/
public void moveUp(Dispatch selection,int count) {
for(int i = 0;i < count;i ++)
Dispatch.call(selection,"MoveUp");
}
/**
* 把選定內容或插入點向下移動
* @param selection Dispatch 要移動的內容
* @param count int 移動的距離
*/
public void moveDown(Dispatch selection,int count) {
for(int i = 0;i < count;i ++)
Dispatch.call(selection,"MoveDown");
}
/**
* 把選定內容或插入點向左移動
* @param selection Dispatch 要移動的內容
* @param count int 移動的距離
*/
public void moveLeft(Dispatch selection,int count) {
for(int i = 0;i < count;i ++) {
Dispatch.call(selection,"MoveLeft");
}
}
/**
* 把選定內容或插入點向右移動
* @param selection Dispatch 要移動的內容
* @param count int 移動的距離
*/
public void moveRight(Dispatch selection,int count) {
for(int i = 0;i < count;i ++)
Dispatch.call(selection,"MoveRight");
}
/**
* 把插入點移動到檔案首位置
* @param selection Dispatch 插入點
*/
public void moveStart(Dispatch selection) {
Dispatch.call(selection,"HomeKey",new Variant(6));
}
/**
* 從選定內容或插入點開始查詢文字
* @param selection Dispatch 選定內容
* @param toFindText String 要查詢的文字
* @return boolean true-查詢到並選中該文字。false-未查詢到文字
*/
public boolean find(Dispatch selection,String toFindText) {
//從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","True");
//查詢並選中
return Dispatch.call(find,"Execute").getBoolean();
}
/**
* 把選定內容替換為設定文字
* @param selection Dispatch 選定內容
* @param newText String 替換為文字
*/
public void replace(Dispatch selection,String newText) {
//設定替換文字
Dispatch.put(selection,"Text",newText);
}
/**
* 全域性替換
* @param selection Dispatch 選定內容或起始插入點
* @param oldText String 要替換的文字
* @param newText String 替換為文字
*/
public void replaceAll(Dispatch selection,String oldText,Object replaceObj) {
//移動到檔案開頭
moveStart(selection);
if(oldText.startsWith("table") || replaceObj instanceof ArrayList)
replaceTable(selection,oldText,(ArrayList) replaceObj);
else {
String newText = (String) replaceObj;
if(newText==null)
newText="";
if(oldText.indexOf("image") != -1&!newText.trim().equals("") || newText.lastIndexOf(".bmp") != -1 || newText.lastIndexOf(".jpg") != -1 || newText.lastIndexOf(".gif") != -1){
while(find(selection,oldText)) {
replaceImage(selection,newText);
Dispatch.call(selection,"MoveRight");
}
}else{
while(find(selection,oldText)) {
replace(selection,newText);
Dispatch.call(selection,"MoveRight");
}
}
}
}
/**
* 替換圖片
* @param selection Dispatch 圖片的插入點
* @param imagePath String 圖片檔案(全路徑)
*/
public void replaceImage(Dispatch selection,String imagePath) {
Dispatch.call(Dispatch.get(selection,"InLineShapes").toDispatch(),"AddPicture",imagePath);
}
/**
* 替換表格
* @param selection Dispatch 插入點
* @param tableName String 表格名稱。
* 形如 [email protected]、[email protected][email protected]。R代表從表格中的第N行開始填充,N代表word檔案裡的第N張表
* @param fields HashMap 表格中要替換的欄位與資料的相應表
*/
public void replaceTable(Dispatch selection,String tableName,ArrayList dataList) {
if(dataList.size() <= 1) {
System.out.println("Empty table!");
return;
}
//要填充的列
String[] cols = (String[]) dataList.get(0);
//表格序號
String tbIndex = tableName.substring(tableName.lastIndexOf("@") + 1);
//從第幾行開始填充
int fromRow = Integer.parseInt(tableName.substring(tableName.lastIndexOf("$") + 1,tableName.lastIndexOf("@")));
//全部表格
Dispatch tables = Dispatch.get(doc,"Tables").toDispatch();
//要填充的表格
Dispatch table = Dispatch.call(tables,"Item",new Variant(tbIndex)).toDispatch();
//表格的全部行
Dispatch rows = Dispatch.get(table,"Rows").toDispatch();
//填充表格
for(int i = 1;i < dataList.size();i ++) {
//某一行資料
String[] datas = (String[]) dataList.get(i);
//在表格中加入一行
if(Dispatch.get(rows,"Count").getInt() < fromRow + i - 1)
Dispatch.call(rows,"Add");
//填充該行的相關列
for(int j = 0;j < datas.length;j ++) {
//得到單元格
Dispatch cell = Dispatch.call(table,"Cell",Integer.toString(fromRow + i - 1),cols[j]).toDispatch();
//選中單元格
Dispatch.call(cell,"Select");
//設定格式
Dispatch font = Dispatch.get(selection,"Font").toDispatch();
Dispatch.put(font,"Bold","0");
Dispatch.put(font,"Italic","0");
//輸入資料
Dispatch.put(selection,"Text",datas[j]);
}
}
}
/**
* 儲存檔案
* @param outputPath String 輸出檔案(包括路徑)
*/
public void save(String outputPath) {
Dispatch.call(Dispatch.call(word,"WordBasic").getDispatch(),"FileSaveAs",outputPath);
}
/**
* 關閉檔案
* @param document Dispatch 要關閉的檔案
*/
public void close(Dispatch doc) {
Dispatch.call(doc,"Close",new Variant(saveOnExit));
word.invoke("Quit",new Variant[]{});
word = null;
}
/**
* 依據模板、資料生成word檔案
* @param inputPath String 模板檔案(包括路徑)
* @param outPath String 輸出檔案(包括路徑)
* @param data HashMap 資料包(包括要填充的欄位、相應的資料)
*/
public void toWord(String inputPath,String outPath,HashMap data) {
String oldText;
Object newValue;
try {
if(doc==null)
doc = open(inputPath);
Dispatch selection = select();
Iterator keys = data.keySet().iterator();
while(keys.hasNext()) {
oldText = (String) keys.next();
newValue = data.get(oldText);
replaceAll(selection,oldText,newValue);
}
save(outPath);
} catch(Exception e) {
System.out.println("操作word檔案失敗!");
e.printStackTrace();
} finally {
if(doc != null)
close(doc);
}
}
public synchronized static void word(String inputPath,String outPath,HashMap data){
Java2word j2w = new Java2word();
j2w.toWord(inputPath,outPath,data);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
//替換word中相關的欄位
HashMap data = new HashMap();
data.put("$reportDept$","2007-8-1");
data.put("$findDate$","2007-8-2");
data.put("$finder$","kdl");
data.put("$lineName$","5號線");
data.put("$voltageRate$","11月13日");
data.put("$towerNumberBound$","2004年11月10日");
data.put("$image1$","C:\\Users\\Administrator\\Pictures\\1.jpg");
data.put("$name$", "FishRoad");
data.put("$age$", "24");
//替換word中表格的資料
/**
* 要替換表格中的資料時,HashMap中的Key格式為“ [email protected]”,當中:
* R代表從表格的第R行開始替換,N代表word模板中的第N張表格;
* Value為ArrayList物件,ArrayList中包括的物件統一為String[]。
* 一條String[]代表一行資料,ArrayList中第一條記錄為特殊記錄。記錄的是表格中要替換的列號。
* 如:要替換第一列、第二列、第三列的資料,則第一條記錄為String[3] {"1","2","3"}
*/
ArrayList table1 = new ArrayList(3);
String[] fieldName1 = {"1","2","3"};
table1.add(fieldName1);
String[] field11 = {"1","751002","華夏證券"};
table1.add(field11);
String[] field21 = {"2","751004","國泰君安"};
table1.add(field21);
String[] field31 = {"3","751005","海通證券"};
table1.add(field31);
data.put("[email protected]",table1);
Java2word j2w = new Java2word();
long time1 = System.currentTimeMillis();
j2w.toWord("E:/template.doc","E:/result.doc",data);
System.out.println("time cost : " + (System.currentTimeMillis() - time1));
}
}
以上是相關的程式碼。接下來就要配置word模板,例如以下:
匯出的結果例如以下圖:
先下載jacob.jar包。
如果是32位系統 將jacob-1.18-x86.dll 檔案複製到下面目錄下,如果是64位作業系統 將jacob-1.18-x64.dll C:\Program Files\Java\jdk1.8.0_45\jre\bin
將jacob.jar增加專案。
這樣專案的環境基本上搭建完畢,接下來就是書寫相關的程式碼:
/**
* 傳入資料為HashMap物件,物件中的Key代表word模板中要替換的欄位。Value代表用來替換的值。
* word模板中全部要替換的欄位(即HashMap中的Key)以特殊字元開頭和結尾。
* 如:$code$、$date$……。以免執行錯誤的替換。
* 全部要替換為圖片的欄位,Key中需包括image或者Value為圖片的全路徑
* (眼下僅僅推斷檔案字尾名為:.bmp、.jpg、.gif)。
* 要替換表格中的資料時,HashMap中的Key格式為“[email protected]”,當中:
* R代表從表格的第R行開始替換,N代表word模板中的第N張表格;
* Value為ArrayList物件,ArrayList中包括的物件統一為String[],一條String[]代表一行資料。
* ArrayList中第一條記錄為特殊記錄。記錄的是表格中要替換的列號,
* 如:要替換第一列、第二列、第三列的資料。則第一條記錄為String[3] {"1","2","3"}。
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
/**
* 利用word模板生成word檔案
* @typename:Java2word
* @author: FishRoad
* @since: 2015年8月24日 下午2:47:41
*
*/
public class Java2word {
private boolean saveOnExit;
/**
* word文件
*/
Dispatch doc = null;
/**
* word執行程式物件s
*/
private ActiveXComponent word;
/**
* 全部word文件
*/
private Dispatch documents;
/**
* 建構函式
*/
public Java2word() {
if(word==null){
word = new ActiveXComponent("Word.Application");
word.setProperty("Visible",new Variant(false));
}
if(documents==null)
documents = word.getProperty("Documents").toDispatch();
saveOnExit = false;
}
/**
* 設定引數:退出時是否儲存
* @param saveOnExit boolean true-退出時儲存檔案,false-退出時不儲存檔案
*/
public void setSaveOnExit(boolean saveOnExit) {
this.saveOnExit = saveOnExit;
}
/**
* 得到引數:退出時是否儲存
* @return boolean true-退出時儲存檔案,false-退出時不儲存檔案
*/
public boolean getSaveOnExit() {
return saveOnExit;
}
/**
* 開啟檔案
* @param inputDoc String 要開啟的檔案,全路徑
* @return Dispatch 開啟的檔案
*/
public Dispatch open(String inputDoc) {
return Dispatch.call(documents,"Open",inputDoc).toDispatch();
}
/**
* 選定內容
* @return Dispatch 選定的範圍或插入點
*/
public Dispatch select() {
return word.getProperty("Selection").toDispatch();
}
/**
* 把選定內容或插入點向上移動
* @param selection Dispatch 要移動的內容
* @param count int 移動的距離
*/
public void moveUp(Dispatch selection,int count) {
for(int i = 0;i < count;i ++)
Dispatch.call(selection,"MoveUp");
}
/**
* 把選定內容或插入點向下移動
* @param selection Dispatch 要移動的內容
* @param count int 移動的距離
*/
public void moveDown(Dispatch selection,int count) {
for(int i = 0;i < count;i ++)
Dispatch.call(selection,"MoveDown");
}
/**
* 把選定內容或插入點向左移動
* @param selection Dispatch 要移動的內容
* @param count int 移動的距離
*/
public void moveLeft(Dispatch selection,int count) {
for(int i = 0;i < count;i ++) {
Dispatch.call(selection,"MoveLeft");
}
}
/**
* 把選定內容或插入點向右移動
* @param selection Dispatch 要移動的內容
* @param count int 移動的距離
*/
public void moveRight(Dispatch selection,int count) {
for(int i = 0;i < count;i ++)
Dispatch.call(selection,"MoveRight");
}
/**
* 把插入點移動到檔案首位置
* @param selection Dispatch 插入點
*/
public void moveStart(Dispatch selection) {
Dispatch.call(selection,"HomeKey",new Variant(6));
}
/**
* 從選定內容或插入點開始查詢文字
* @param selection Dispatch 選定內容
* @param toFindText String 要查詢的文字
* @return boolean true-查詢到並選中該文字。false-未查詢到文字
*/
public boolean find(Dispatch selection,String toFindText) {
//從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","True");
//查詢並選中
return Dispatch.call(find,"Execute").getBoolean();
}
/**
* 把選定內容替換為設定文字
* @param selection Dispatch 選定內容
* @param newText String 替換為文字
*/
public void replace(Dispatch selection,String newText) {
//設定替換文字
Dispatch.put(selection,"Text",newText);
}
/**
* 全域性替換
* @param selection Dispatch 選定內容或起始插入點
* @param oldText String 要替換的文字
* @param newText String 替換為文字
*/
public void replaceAll(Dispatch selection,String oldText,Object replaceObj) {
//移動到檔案開頭
moveStart(selection);
if(oldText.startsWith("table") || replaceObj instanceof ArrayList)
replaceTable(selection,oldText,(ArrayList) replaceObj);
else {
String newText = (String) replaceObj;
if(newText==null)
newText="";
if(oldText.indexOf("image") != -1&!newText.trim().equals("") || newText.lastIndexOf(".bmp") != -1 || newText.lastIndexOf(".jpg") != -1 || newText.lastIndexOf(".gif") != -1){
while(find(selection,oldText)) {
replaceImage(selection,newText);
Dispatch.call(selection,"MoveRight");
}
}else{
while(find(selection,oldText)) {
replace(selection,newText);
Dispatch.call(selection,"MoveRight");
}
}
}
}
/**
* 替換圖片
* @param selection Dispatch 圖片的插入點
* @param imagePath String 圖片檔案(全路徑)
*/
public void replaceImage(Dispatch selection,String imagePath) {
Dispatch.call(Dispatch.get(selection,"InLineShapes").toDispatch(),"AddPicture",imagePath);
}
/**
* 替換表格
* @param selection Dispatch 插入點
* @param tableName String 表格名稱。
* 形如[email protected]、[email protected][email protected]。R代表從表格中的第N行開始填充,N代表word檔案裡的第N張表
* @param fields HashMap 表格中要替換的欄位與資料的相應表
*/
public void replaceTable(Dispatch selection,String tableName,ArrayList dataList) {
if(dataList.size() <= 1) {
System.out.println("Empty table!");
return;
}
//要填充的列
String[] cols = (String[]) dataList.get(0);
//表格序號
String tbIndex = tableName.substring(tableName.lastIndexOf("@") + 1);
//從第幾行開始填充
int fromRow = Integer.parseInt(tableName.substring(tableName.lastIndexOf("$") + 1,tableName.lastIndexOf("@")));
//全部表格
Dispatch tables = Dispatch.get(doc,"Tables").toDispatch();
//要填充的表格
Dispatch table = Dispatch.call(tables,"Item",new Variant(tbIndex)).toDispatch();
//表格的全部行
Dispatch rows = Dispatch.get(table,"Rows").toDispatch();
//填充表格
for(int i = 1;i < dataList.size();i ++) {
//某一行資料
String[] datas = (String[]) dataList.get(i);
//在表格中加入一行
if(Dispatch.get(rows,"Count").getInt() < fromRow + i - 1)
Dispatch.call(rows,"Add");
//填充該行的相關列
for(int j = 0;j < datas.length;j ++) {
//得到單元格
Dispatch cell = Dispatch.call(table,"Cell",Integer.toString(fromRow + i - 1),cols[j]).toDispatch();
//選中單元格
Dispatch.call(cell,"Select");
//設定格式
Dispatch font = Dispatch.get(selection,"Font").toDispatch();
Dispatch.put(font,"Bold","0");
Dispatch.put(font,"Italic","0");
//輸入資料
Dispatch.put(selection,"Text",datas[j]);
}
}
}
/**
* 儲存檔案
* @param outputPath String 輸出檔案(包括路徑)
*/
public void save(String outputPath) {
Dispatch.call(Dispatch.call(word,"WordBasic").getDispatch(),"FileSaveAs",outputPath);
}
/**
* 關閉檔案
* @param document Dispatch 要關閉的檔案
*/
public void close(Dispatch doc) {
Dispatch.call(doc,"Close",new Variant(saveOnExit));
word.invoke("Quit",new Variant[]{});
word = null;
}
/**
* 依據模板、資料生成word檔案
* @param inputPath String 模板檔案(包括路徑)
* @param outPath String 輸出檔案(包括路徑)
* @param data HashMap 資料包(包括要填充的欄位、相應的資料)
*/
public void toWord(String inputPath,String outPath,HashMap data) {
String oldText;
Object newValue;
try {
if(doc==null)
doc = open(inputPath);
Dispatch selection = select();
Iterator keys = data.keySet().iterator();
while(keys.hasNext()) {
oldText = (String) keys.next();
newValue = data.get(oldText);
replaceAll(selection,oldText,newValue);
}
save(outPath);
} catch(Exception e) {
System.out.println("操作word檔案失敗!");
e.printStackTrace();
} finally {
if(doc != null)
close(doc);
}
}
public synchronized static void word(String inputPath,String outPath,HashMap data){
Java2word j2w = new Java2word();
j2w.toWord(inputPath,outPath,data);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) {
//替換word中相關的欄位
HashMap data = new HashMap();
data.put("$reportDept$","2007-8-1");
data.put("$findDate$","2007-8-2");
data.put("$finder$","kdl");
data.put("$lineName$","5號線");
data.put("$voltageRate$","11月13日");
data.put("$towerNumberBound$","2004年11月10日");
data.put("$image1$","C:\\Users\\Administrator\\Pictures\\1.jpg");
data.put("$name$", "FishRoad");
data.put("$age$", "24");
//替換word中表格的資料
/**
* 要替換表格中的資料時,HashMap中的Key格式為“[email protected]”,當中:
* R代表從表格的第R行開始替換,N代表word模板中的第N張表格;
* Value為ArrayList物件,ArrayList中包括的物件統一為String[]。
* 一條String[]代表一行資料,ArrayList中第一條記錄為特殊記錄。記錄的是表格中要替換的列號。
* 如:要替換第一列、第二列、第三列的資料,則第一條記錄為String[3] {"1","2","3"}
*/
ArrayList table1 = new ArrayList(3);
String[] fieldName1 = {"1","2","3"};
table1.add(fieldName1);
String[] field11 = {"1","751002","華夏證券"};
table1.add(field11);
String[] field21 = {"2","751004","國泰君安"};
table1.add(field21);
String[] field31 = {"3","751005","海通證券"};
table1.add(field31);
data.put("[email protected]",table1);
Java2word j2w = new Java2word();
long time1 = System.currentTimeMillis();
j2w.toWord("E:/template.doc","E:/result.doc",data);
System.out.println("time cost : " + (System.currentTimeMillis() - time1));
}
}
以上是相關的程式碼。接下來就要配置word模板,例如以下:
匯出的結果例如以下圖: