如题,我有一个类叫做:ReplaceWord,这个类是专门用于替换word中的文字的,需要被另外的控制类多次调用。
我测试过,如果这个类只运行一次的时候,调用word时产生的winword进程在程序执行完毕之后也就结束了,但是如果外部的程序多次调用这个类来替换word中的文字的时候,无论调用多少次,始终有两个winword进程挥之不去,本人十分苦恼,请大家帮我看看到底是什么地方出了问题,谢谢大家!!下面是外部类调用此类的代码:外部调用代码: //处理附件中的文件,在附件中加上邀请人的名字
ReplaceWord word = new ReplaceWord();
//循环发送邮件
for(int i = 0;i<names.length;i++){
mailbody = rebuildMailbody(mailbody_bak,names[i]);
//处理附件中的文件,在附件中加上邀请人的名字
word.setDocPath(wordToReplace);
word.setDocSaveAsPath(wordToSaveAs);
word.setStrFind(wordStrFind);
word.setStrReplace(names[i]);
if(!word.replace()){
System.out.println("["+i+"] 附件文件处理失败!");
return;
}
System.out.print("["+(i+1)+"/"+names.length+"] "+names[i]+"...");
send(mail,strSmtpHost, username, password,addressFrom,
address[i],
addressCopy, addressDarkCopy,subject,
mailbody,
isNeedAuth, isNeedNotification); }ReplaceWord类代码:import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;public class ReplaceWord {
private String docPath = ""; // 要处理的word文件的路径
private String docSaveAsPath = ""; // 处理后的文件另存为的路径(如果路径为空,则替换原有文件)
private String strFind = ""; // 要查找的关键字
private String strReplace = ""; // 要替换的关键字
public ReplaceWord(String docPath, String docSaveAsPath, String strFind, String strReplace){
this.setDocPath(docPath);
this.setDocSaveAsPath(docSaveAsPath);
this.setStrFind(strFind);
this.setStrReplace(strReplace);
}
public ReplaceWord(){
}
public boolean replace() {
boolean returnFlag = false;
ActiveXComponent app = new ActiveXComponent("Word.Application"); // 启动word
String inFile = this.getDocPath(); // 要替换的word文件
try {
app.setProperty("Visible", new Variant(false)); // 设置word不可见
Dispatch docs = app.getProperty("Documents").toDispatch();
Dispatch doc = Dispatch.invoke(
docs,
"Open",
Dispatch.Method,
new Object[] { inFile,
new Variant(false),
new Variant(true) }, // 以只读方式打开word
new int[1]).toDispatch(); Dispatch selection = app.getProperty("Selection").toDispatch();// 获得对Selection组件
Dispatch.call(selection, "HomeKey", new Variant(6));// 移到开头
Dispatch find = Dispatch.call(selection, "Find").toDispatch();// 获得Find组件
Dispatch.put(find, "Text", this.getStrFind()); // 查找字符串
Dispatch.call(find, "Execute"); // 执行查询
Dispatch.put(selection, "Text", this.getStrReplace()); // 替换字符串 if(this.getDocSaveAsPath() == null || this.getDocSaveAsPath().length() == 0){
Dispatch.call(doc, "Save"); // 保存文件
}
else{
Dispatch.call(doc, "SaveAs",this.getDocSaveAsPath()); // 文件另存为
}
//close document without saving changes
Dispatch.call(doc, "Close", new Variant(0));
returnFlag = true;
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
returnFlag = false;
} finally {
app.invoke("Quit", new Variant[]{});
app.safeRelease();
}
return returnFlag;
} // some getters and setters
}
我测试过,如果这个类只运行一次的时候,调用word时产生的winword进程在程序执行完毕之后也就结束了,但是如果外部的程序多次调用这个类来替换word中的文字的时候,无论调用多少次,始终有两个winword进程挥之不去,本人十分苦恼,请大家帮我看看到底是什么地方出了问题,谢谢大家!!下面是外部类调用此类的代码:外部调用代码: //处理附件中的文件,在附件中加上邀请人的名字
ReplaceWord word = new ReplaceWord();
//循环发送邮件
for(int i = 0;i<names.length;i++){
mailbody = rebuildMailbody(mailbody_bak,names[i]);
//处理附件中的文件,在附件中加上邀请人的名字
word.setDocPath(wordToReplace);
word.setDocSaveAsPath(wordToSaveAs);
word.setStrFind(wordStrFind);
word.setStrReplace(names[i]);
if(!word.replace()){
System.out.println("["+i+"] 附件文件处理失败!");
return;
}
System.out.print("["+(i+1)+"/"+names.length+"] "+names[i]+"...");
send(mail,strSmtpHost, username, password,addressFrom,
address[i],
addressCopy, addressDarkCopy,subject,
mailbody,
isNeedAuth, isNeedNotification); }ReplaceWord类代码:import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;public class ReplaceWord {
private String docPath = ""; // 要处理的word文件的路径
private String docSaveAsPath = ""; // 处理后的文件另存为的路径(如果路径为空,则替换原有文件)
private String strFind = ""; // 要查找的关键字
private String strReplace = ""; // 要替换的关键字
public ReplaceWord(String docPath, String docSaveAsPath, String strFind, String strReplace){
this.setDocPath(docPath);
this.setDocSaveAsPath(docSaveAsPath);
this.setStrFind(strFind);
this.setStrReplace(strReplace);
}
public ReplaceWord(){
}
public boolean replace() {
boolean returnFlag = false;
ActiveXComponent app = new ActiveXComponent("Word.Application"); // 启动word
String inFile = this.getDocPath(); // 要替换的word文件
try {
app.setProperty("Visible", new Variant(false)); // 设置word不可见
Dispatch docs = app.getProperty("Documents").toDispatch();
Dispatch doc = Dispatch.invoke(
docs,
"Open",
Dispatch.Method,
new Object[] { inFile,
new Variant(false),
new Variant(true) }, // 以只读方式打开word
new int[1]).toDispatch(); Dispatch selection = app.getProperty("Selection").toDispatch();// 获得对Selection组件
Dispatch.call(selection, "HomeKey", new Variant(6));// 移到开头
Dispatch find = Dispatch.call(selection, "Find").toDispatch();// 获得Find组件
Dispatch.put(find, "Text", this.getStrFind()); // 查找字符串
Dispatch.call(find, "Execute"); // 执行查询
Dispatch.put(selection, "Text", this.getStrReplace()); // 替换字符串 if(this.getDocSaveAsPath() == null || this.getDocSaveAsPath().length() == 0){
Dispatch.call(doc, "Save"); // 保存文件
}
else{
Dispatch.call(doc, "SaveAs",this.getDocSaveAsPath()); // 文件另存为
}
//close document without saving changes
Dispatch.call(doc, "Close", new Variant(0));
returnFlag = true;
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
returnFlag = false;
} finally {
app.invoke("Quit", new Variant[]{});
app.safeRelease();
}
return returnFlag;
} // some getters and setters
}
OS:Windows XP SP3
JDK: 1.6.0_02
jacob: 1.14.3
IDE: MyEclipse 6.0.1
{
Dispatch.call(doc, "Close", new Variant(0));
doc = null;
}
if (app != null)
{
Dispatch.call(app, "Quit");
app = null;
}
{
Dispatch.call(doc, "Close", new Variant(0));
doc = null;
}
if (app != null)
{
Dispatch.call(app, "Quit");
app = null;
} returnFlag = true;
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
returnFlag = false;
}
return returnFlag;
但是现在在程序运行完了之后,有3个winword进程仍然存在,还是没有解决啊,到底是怎么回事儿呢?
调用
public void quit()
{
Dispatch.call(word, "Quit");
logger.debug("退出Word应用程序");
}