(转)Jacob 导出word文档 资源无法正常释放 解决方法

  1.  操作word文档失败!com.jacob.com.ComFailException: Can't map name to dispid: Open   
  2. 2009-03-17 15:11:41,812 WARN [org.apache.struts.action.RequestProcessor] - <Unhandled Exception thrown: class com.jacob.com.ComFailException>   
  3. 2009-3-17 15:11:41 org.apache.catalina.core.StandardWrapperValve invoke   
  4.   严重: Servlet.service() for servlet action threw exception   
  5. com.jacob.com.ComFailException: Can't map name to dispid: Quit  

 

    1. 经过多次调试,发现内存消耗严重。查看任务管理器,有多个word进程积压未关闭。
         发现原因:第一次调用完后,虽然word已经被关闭。但装载word的ActiveXComponent并没有被关闭。
         所以,加入管理com组件的线程,在关闭word之后,关闭线程。

      修改后的代码如下:
    2. public class JacobWord {   
    3.   
    4.     /**  
    5.      * 打开文件  
    6.      * @param documents   
    7.      * @param inputDocPath  
    8.      * @return  
    9.      */  
    10.     private Dispatch open(Dispatch documents,String inputDocPath){   
    11.         return Dispatch.call(documents,"Open",inputDocPath).toDispatch();   
    12.     }   
    13.        
    14.     /**  
    15.      * 选定内容  
    16.      * @param word  
    17.      * @return  
    18.      */  
    19.     private Dispatch select(ActiveXComponent word){   
    20.         return word.getProperty("Selection").toDispatch();   
    21.     }   
    22.        
    23.     /**  
    24.      * 把插入点移动到文件首位置  
    25.      * @param selection  
    26.      */  
    27.     private void moveStart(Dispatch selection){   
    28.         Dispatch.call(selection, "HomeKey",new Variant(6));   
    29.     }   
    30.        
    31.     /**  
    32.      * 从选定内容或插入点开始查找文本  
    33.      * @param selection 选定内容  
    34.      * @param toFindText    要查找的文本  
    35.      * @return  true:查找到并选中该文本;false:未查找到文本。  
    36.      */  
    37.     private boolean find(Dispatch selection,String toFindText){   
    38.         //从selection所在位置开始查询   
    39.         Dispatch find = Dispatch.call(selection, "Find").toDispatch();   
    40.         //设置要查找的内容   
    41.         Dispatch.put(find, "Text", toFindText);   
    42.         //向前查找   
    43.         Dispatch.put(find, "Forward""True");   
    44.         //设置格式   
    45.         Dispatch.put(find,"format","True");   
    46.         //大小写匹配   
    47.         Dispatch.put(find, "MatchCase""True");   
    48.         //全字匹配   
    49.         Dispatch.put(find, "MatchWholeWord""True");   
    50.         //查找并选中   
    51.         return Dispatch.call(find, "Execute").getBoolean();   
    52.     }   
    53.        
    54.     /**  
    55.      * 把选定内容替换为设定文本  
    56.      * @param selection  
    57.      * @param newText  
    58.      */  
    59.     private void replace(Dispatch selection,String newText){   
    60.         Dispatch.put(selection, "Text", newText);   
    61.     }   
    62.        
    63.     /**  
    64.      * 全局替换  
    65.      * @param selection   
    66.      * @param oldText  
    67.      * @param replaceObj  
    68.      */  
    69.     private void replaceAll(Dispatch selection,String oldText,Object replaceObj){   
    70.         moveStart(selection);   
    71.         String newText = (String)replaceObj;   
    72.         while(find(selection,oldText)){   
    73.             replace(selection,newText);   
    74.             Dispatch.call(selection, "MoveRight");   
    75.         }   
    76.     }   
    77.        
    78.     /**  
    79.      * 打印  
    80.      * @param document  
    81.      */  
    82.     private void print(Dispatch document){   
    83.         Dispatch.call(document, "PrintOut");   
    84.     }   
    85.        
    86.     /**  
    87.      * 保存文件  
    88.      * @param word  
    89.      * @param outputPath  
    90.      */  
    91.     private void save(ActiveXComponent word,String outputPath){   
    92.         Dispatch.call(Dispatch.call(word, "WordBasic").getDispatch(), "FileSaveAs",outputPath);   
    93.     }   
    94.        
    95.     /**  
    96.      * 关闭文件  
    97.      * @param doc  
    98.      */  
    99.     private void close(Dispatch doc){   
    100.         Dispatch.call(doc, "Close",new Variant(true));   
    101.     }   
    102.        
    103.     /**  
    104.      * 保存打印doc文档  
    105.      * @param inputDocPath  
    106.      * @param outPutDocPath  
    107.      * @param data  
    108.      * @param isPrint  
    109.      */  
    110.     public void saveDoc(String inputDocPath,String outPutDocPath,HashMap data,boolean isPrint){   
    111.         //初始化com的线程   
    112.         ComThread.InitSTA();   
    113.         //word运行程序对象   
    114.         ActiveXComponent word = new ActiveXComponent("Word.Application");   
    115.         //文档对象   
    116.         Dispatch wordObject = (Dispatch) word.getObject();   
    117.         //设置属性  Variant(true)表示word应用程序可见   
    118.         Dispatch.put((Dispatch)wordObject,"Visible"new Variant(false));   
    119.         //word所有文档   
    120.         Dispatch documents = word.getProperty("Documents").toDispatch();   
    121.         //打开文档   
    122.         Dispatch document = this.open(documents,inputDocPath);   
    123.         Dispatch selection = this.select(word);   
    124.         Iterator keys = data.keySet().iterator();   
    125.         String oldText;   
    126.         Object newValue;   
    127.         while(keys.hasNext()){   
    128.             oldText = (String)keys.next();   
    129.             newValue = data.get(oldText);   
    130.             this.replaceAll(selection, oldText, newValue);   
    131.         }   
    132.         //是否打印   
    133.         if(isPrint){   
    134.             this.print(document);   
    135.         }   
    136.         this.save(word,outPutDocPath);   
    137.         this.close(document);   
    138.         word.invoke("Quit"new Variant[0]);   
    139.         //关闭com的线程   
    140.         ComThread.Release();   
    141.     }   
    142. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值