介绍一下jacob:
jacob是在java与微软的com组件之间的桥梁,通过使用jacob自带的dll动态链接库通过jni的方式实现了在sun java平台上的程序对com调用!
下载地址:
http://sourceforge.net/project/showfi ... 543&package_id=118368
配置说明::
解压文件:jacob_1.11.1.zip ,copy jacob.jar文件加入到classpath
copy jacob.dll 放在java jdk bin目录下
jacob版本:jacob_1.11.1
JDK版本:jdk1.4
实现的功能:根据word模版生成新的word文档
代码如下:
/*************************************
*
*作用:利用jacob插件根据模板word生成word 文件!
*
*传入数据为HashMap对象,对象中的Key代表word模板中要替换的字段,Value代表用来替换的值。
* 1:替换内容来自文本
* word模板中所有要替换的字段(即HashMap中的Key)以特殊字符开头和结尾,如:$code$、$date$……,以免执行错误的替换。
* 2:替换内容来自图片
* 所有要替换为图片的字段,Key中需包含image或者Value为图片的全路径(目前只判断文件后缀名为:.bmp、.jpg、.gif)。
* 3:替换内容来自文件
* 所有要替换的内容如果来自word文件,HashMap中的Key格式为"$file1$",其中必须有"file",Value为ArrayList对象,ArrayList中
* 包含的对象为用来替换该内容word文件的全路径。如:e:/doc/ill1.doc
* 4:替换表格中的内容
* 要替换表格中的数据时,HashMap中的Key格式为"table$R@N",其中:R代表从表格的第R行开始替换,N代表word模板中的第N张表格;
* Value为ArrayList对象,ArrayList中包含的对象统一为String[],一条String[]代表一行数据,ArrayList中第一条记录为特殊记录,
* 记录的是表格中要替换的列号,如:要替换第一列、第三列、第五列的数据,则第一条记录为String[3] {"1","3","5"}。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
//import java.util.ArrayList;
//import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.log4j.Logger;
//import javax.print.DocFlavor;
//import javax.print.PrintService;
//import javax.print.PrintServiceLookup;
//
//import javax.print.attribute.HashPrintRequestAttributeSet;
//import javax.print.attribute.PrintRequestAttributeSet;
//
//import com.cyber.javax.util.General;
import com.cyber.javax.util.General;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
public class JavaToWord {
public static void main(String[] args){
// System.out.println("开始。。。。。。。。。。。。");
// long lbegin = System.currentTimeMillis();
// Map data = new HashMap();
// data.put("$NAME$","张三");
// data.put("$SEX$", "男");
// data.put("$BIRTH$", "1978-11-12");
// data.put("$IDCARD$","430522198712047810");
// data.put("$IMG$", "e:/doc/aa.gif");
// List listFile = new ArrayList();
// for(int i = 1; i < 9;i++){
// listFile.add("e:/doc/ill"+i+".doc");
// }
// listFile.add("//192.168.2.4/tools/test.doc");
//
// data.put("$file1$", listFile);
//
////
//// data.put("$ILLNESS$", General.readDoc("e:/doc/ill1.doc")+
//// General.readDoc("e:/doc/ill2.doc")+
//// General.readDoc("e:/doc/ill3.doc")+
//// General.readDoc("e:/doc/ill4.doc")+
//// General.readDoc("e:/doc/ill5.doc")+
//// General.readDoc("e:/doc/ill6.doc")+
//// General.readDoc("e:/doc/ill7.doc"));
//
// List listTable = new ArrayList();
// String[] arrRecord = {"1","2","3"};
// listTable.add(arrRecord);
// arrRecord = new String[]{"1","桥本甲状腺炎1","++/-"};
// listTable.add(arrRecord);
// arrRecord = new String[]{"2","桥本甲状腺炎2","++/-"};
// listTable.add(arrRecord);
// arrRecord = new String[]{"3","桥本甲状腺炎3","++/-"};
// listTable.add(arrRecord);
// arrRecord = new String[]{"4","桥本甲状腺炎4","++/-"};
// listTable.add(arrRecord);
// arrRecord = new String[]{"5","桥本甲状腺炎5","++/-"};
// listTable.add(arrRecord);
// arrRecord = new String[]{"6","桥本甲状腺炎6","++/-"};
// listTable.add(arrRecord);
// arrRecord = new String[]{"7","桥本甲状腺炎7","++/-"};
// listTable.add(arrRecord);
// data.put("table$2@1",listTable);
// data.put("table$2@2",listTable);
//
// JavaToWord javaToWord = new JavaToWord();
// try {
// javaToWord.toWord("e:/doc/template.doc", "e:/doc/new.doc", data);
// } catch (Exception e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println("结束。。。。。。。。。。。。");
// String totalTime = General.calMius(System.currentTimeMillis()-lbegin);
// System.out.println("花的时长为:"+totalTime);
//
//
System.out.println("打印开始........");
JavaToWord javaToWord = new JavaToWord();
try {
javaToWord.printWord("e:/doc/test.doc","Canon iP1600");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("打印结束........");
}
protected Logger log4j = Logger.getLogger(getClass());
private boolean saveOnExit;
/**
* word文档
*/
private Dispatch doc = null;
/**
* word运行程序对象
*/
private ActiveXComponent word;
/**
* 所有word文档
*/
private Dispatch documents;
/**
* 构造函数
*/
public JavaToWord() {
saveOnExit = false;
word = new ActiveXComponent("Word.Application");
word.setProperty("Visible", new Variant(false));
documents = word.getProperty("Documents").toDispatch();
}
/**
* 设置参数:退出时是否保存
* @param saveOnExit :true-退出时保存文件,false-退出时不保存文件
*/
public void setSaveOnExit(boolean saveOnExit) {
this.saveOnExit = saveOnExit;
}
/**
* 得到参数:退出时是否保存
* @return boolean: true-退出时保存文件,false-退出时不保存文件
*/
public boolean getSaveOnExit() {
return saveOnExit;
}
/**
* 打开文件
* @param inputDoc :要打开的文件,全路径
* @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: 要移动的内容
* @param count: 移动的距离
*/
public void moveUp(Dispatch selection, int count) {
for (int i = 0; i < count; i++){
Dispatch.call(selection, "MoveUp");
}
}
/**
* 把选定内容或插入点向下移动
* @param selection: 要移动的内容
* @param count: 移动的距离
*/
public void moveDown(Dispatch selection, int count) {
for (int i = 0; i < count; i++){
Dispatch.call(selection, "MoveDown");
}
}
/**
* 把选定内容或插入点向左移动
* @param selection:要移动的内容
* @param count:移动的距离
*/
public void moveLeft(Dispatch selection, int count) {
for (int i = 0; i < count; i++){
Dispatch.call(selection, "MoveLeft");
}
}
/**
* 把选定内容或插入点向右移动
* @param selection:要移动的内容
* @param count:移动的距离
*/
public void moveRight(Dispatch selection, int count) {
for (int i = 0; i < count; i++){
Dispatch.call(selection, "MoveRight");
}
}
/**
* 把插入点移动到文件首位置
* @param selection: 插入点
*/
public void moveStart(Dispatch selection) {
Dispatch.call(selection, "HomeKey", new Variant(6));
}
/**
* 从选定内容或插入点开始查找文本
* @param selection: 选定内容
* @param toFindText:要查找的文本
* @return boolean: true-查找到并选中该文本,false-未查找到文本
*/
public boolean find(Dispatch selection, String toFindText) {
// 从selection所在位置开始查询
Dispatch find = Dispatch.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:选定内容
* @param newText:替换为文本
*/
public void replace(Dispatch selection, String newText) {
// 设置替换文本
Dispatch.put(selection, "Text", newText);
}
/**
* 全局替换
* @param selection: 选定内容或起始插入点
* @param oldText: 要替换的文本
* @param newText: 替换为文本
*/
public void replaceAll(Dispatch selection, String oldText, Object replaceObj) {
// 移动到文件开头
moveStart(selection);
if(oldText.indexOf("file") != -1 && replaceObj instanceof List){
while (find(selection, oldText)) {
replaceFile(selection, (List) replaceObj);
Dispatch.call(selection, "MoveRight");
}
}else if (oldText.startsWith("table") && replaceObj instanceof List) {
replaceTable(selection, oldText, (List) replaceObj);
} else {
String newText = (replaceObj == null)?"":(String)replaceObj;
if (oldText.indexOf("image") != -1
|| 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
* @param fileList
*/
public void replaceFile(Dispatch selection, List fileList) {
//追加文件
for (int i = 0; i < fileList.size(); i++) {
if(fileList.get(i) != null && ((String)fileList.get(i)).toLowerCase().lastIndexOf(".doc")!= -1){
String filePath = (String)fileList.get(i);
File file = new File(filePath);
//只有存在的文件并且有内容时才执行追加操作
if(file.exists() && file.length() > 0 ){
// String docContent = General.readDoc(file);
// docContent = General.trimLeft(docContent);
// docContent = General.trimRight(docContent);
// if("".equals(docContent)) continue;
Dispatch.invoke(selection,
"insertFile", Dispatch.Method, new Object[] {
(String) fileList.get(i), "",
new Variant(false), new Variant(false),
new Variant(false) }, new int[3]);
}
}
}
}
/**
* 替换图片
* @param selection: 图片的插入点
* @param imagePath: 图片文件(全路径)
*/
public void replaceImage(Dispatch selection, String imagePath) {
File file = new File(imagePath);
if(file.exists()){
Dispatch.call(Dispatch.get(selection, "InLineShapes").toDispatch(),
"AddPicture", imagePath);
//居中显示
Dispatch oAlign = Dispatch.get(selection, "ParagraphFormat").toDispatch();
Dispatch.put(oAlign, "Alignment", "1");
}
}
/**
* 替换表格
* @param selection: 插入点
* @param tableName
* 表格名称,形如table$1@1、[email protected]$R@N,R代表从表格中的第N行开始填充,
* N代表word文件中的第N张表
* @param fields
* 表格中要替换的字段与数据的对应表
*/
public void replaceTable(Dispatch selection, String tableName, List dataList) {
if (dataList == null || dataList.size() <= 1) {
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(datas == null || datas.length == 0) continue;
// 在表格中添加一行
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]);
}
}
}
/**
* 将word转换成html
* @param htmlFilePath
*/
public void wordToHtml(String htmlFilePath) {
Dispatch.invoke(Dispatch.call(word, "WordBasic").getDispatch(),"FileSaveAs", Dispatch.Method, new Object[]{htmlFilePath,new Variant(8)}, new int[1]);
}
/**
* 保存文件
* @param outputPath: 输出文件(包含路径)
*/
public void save(String outputPath) {
Dispatch.call(Dispatch.call(word, "WordBasic").getDispatch(),
"FileSaveAs", outputPath);
}
/**
* 关闭文件
* @param document:要关闭的文件
*/
public void close(Dispatch doc) {
Dispatch.call(doc, "Close", new Variant(saveOnExit));
}
/**
* 退出程序
*/
public void quit() {
word.invoke("Quit", new Variant[0]);
ComThread.Release();
}
/**
* 根据模板、数据生成word文件
* @param inputPath: 模板文件(包含路径)
* @param outPath: 输出文件(包含路径)
* @param data: 数据包(包含要填充的字段、对应的数据)
* @param isUpdateField:是否需要更新域
* @param seekView:页眉内容
*/
public void toWord(String inputPath, String outPath, Map data,boolean isUpdateField,String seekView) throws Exception{
String oldText;
Object newValue;
String tempFilePath = "";
try {
File file = new File(inputPath);
if(!file.exists()) return;
///////////////////////////////////////////////////////////////////////
//long lbegin = System.currentTimeMillis();
//拷贝模板文件,防止模版文件被锁定
tempFilePath = General.getTempFile(inputPath);
General.copyFile(inputPath, tempFilePath);
//log4j.info("tempFilePath = "+tempFilePath+"\t\t 拷贝时长:"+General.calMius(System.currentTimeMillis()-lbegin));
///////////////////////////////////////////////////////////////
doc = open(tempFilePath);
Dispatch selection = select();
if(data != null){
//替换模版文件中的内容
for (Iterator keys = data.keySet().iterator();keys.hasNext();) {
oldText = (String) keys.next();
//如果键值为空,继续
if(oldText == null || "".equals(oldText)) continue;
newValue = data.get(oldText);
if(newValue == null ) newValue = "";
replaceAll(selection, oldText, newValue);
}
//设置页眉
if(seekView != null && !"".equals(seekView)){
//取得活动窗体对象
Dispatch ActiveWindow = word.getProperty("ActiveWindow").toDispatch();
//取得活动窗格对象
Dispatch ActivePane = Dispatch.get(ActiveWindow,"ActivePane").toDispatch();
//取得视窗对象
Dispatch View = Dispatch.get(ActivePane, "View").toDispatch();
Dispatch.put(View,"SeekView", "9");
Dispatch.put(selection,"Text",seekView);
}
//更新域的操作
if(isUpdateField){
Dispatch fields = Dispatch.get(doc,"Fields").toDispatch();
Dispatch.call(fields, "Update");
}
}
save(outPath);
} catch (Exception e) {
throw e;
} finally {
try{
if (doc != null) close(doc);
if(word != null) quit();
}catch(Exception e){
log4j.error("toWord:"+ExceptionUtils.getStackTrace(e));
}
//删除临时文件
File file = new File(tempFilePath);
if(file != null && file.exists()) file.delete();
}
}
/**
*
* 根据模板、数据生成word文件
* @param inputPath: 模板文件(包含路径)
* @param outPath: 输出文件(包含路径)
* @param data: 数据包(包含要填充的字段、对应的数据)
* @throws Exception
*/
public void toWord(String inputPath, String outPath, Map data) throws Exception{
toWord(inputPath,outPath,data,false,"");
}
// /**
// * 查找本机上所有的打印机
// * @return
// */
// public static String[] getAllPrint(){
//
// String[] strAll = {};
//
// //构建打印请求属性集
// PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
// //设置打印格式,因为未确定文件类型,这里选择AUTOSENSE
// DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
// //查找所有的可用打印服务
// PrintService[] printService = PrintServiceLookup.lookupPrintServices(flavor,pras);
// //如果没有打印服务就返回
// if(printService == null || printService.length == 0) return strAll;
//
// strAll = new String[printService.length];
//
// for(int i = 0;i < printService.length; i ++){
// String strPrint = printService[i].toString();
// strPrint = strPrint.substring(strPrint.lastIndexOf(":")+1).trim();
// strPrint = General.replaceString(strPrint,"\\","\\\\");
//
// strAll[i] = strPrint;
// }
//
// return strAll;
//
//
// }
/**
* 打印
* @param filePath : 文件全路径
* @param printName :打印机名称
*/
public void printWord(String filePath,String printName) throws Exception{
// ActiveXComponent objWord = null;
// Dispatch document = null;
try{
//创建word
//objWord = new ActiveXComponent("Word.Application");
//设置当前使用的打印机
word.setProperty("ActivePrinter",new Variant(printName));
// Dispatch wordObject = (Dispatch) objWord.getObject();
// //设置word不可见
// Dispatch.put((Dispatch) wordObject, "Visible", new Variant(false));
// Dispatch documents = objWord.getProperty("Documents").toDispatch();
// //打开word文件
// document = Dispatch.call(documents, "Open", filePath).toDispatch();
doc = open(filePath);
//使用当前的打印机进行打印
Dispatch.call(doc, "PrintOut");
}catch(Exception e){
throw e;
}finally{
// Dispatch.call(document, "Close", new Variant(false));
// objWord.invoke("Quit",new Variant[0]);
if (doc != null) close(doc);
if(word != null) quit();
}
}
}