使用Jacob与Word文件交互

Jacob项目的官方地址: Http://sourceforge.net/projects/jacob-project/
官方介绍:
    JACOB is a JAVA-COM Bridge that allows you to call COM Automation components from Java. It uses JNI to make native calls to the COM libraries. JACOB runs on x86 and x64 environments supporting 32 bit and 64 bit JVMs
它是一个使用jni来调用com组件及其库文件的工具。这里仅介绍处理word文档。

首先要部署其dll文件。jacob-1.14.3-x86.dll 或 jacob-1.14.3-x64.dll,下载的文件解压后即可看到。我是直接将dll文件放在windows/system32目录下的,方便,当然也有其他做法。
其次,就是把其jar文件路径加入Windows路径中。
接着就可以在你的Java程序中调用了。我总结下大概有下面几个阶段:

1. 初始化相关参数,代码如下:

//  打开Word应用程序
ActiveXComponent app  =   new  ActiveXComponent( " Word.Application " );
//  设置word不可见
app.setProperty( " Visible " new  Variant( false ));
//  打开word文件
Dispatch word  =  app.getProperty( " Documents " ).toDispatch();
Dispatch doc 
=  Dispatch.invoke(word,  " Open " , Dispatch.Method,  new  Object[] { " File Name " new  Variant( false ),  new  Variant( false ) },  new   int [ 1 ]).toDispatch();
// 获取指针
Dispatch cursor  =  app.getProperty( " Selection " ).toDispatch();


如上,我们打开了一个名为File Name的word文件,你可能会觉得最后那句看起来很繁琐,是的,有更好的代替方式,如下:

Dispatch doc = Dispatch.call(word,  " Open " new  Variant( false ),  new  Variant( false )).toDisptach();


这正是Jacob给我们提供的两种调用方式。

2. 处理word文档,如果你先前有VBA相关开发经验,那就简单了。没有的也没事,打开office程序目录下的2052/VBAWD10.chm,这里有Word的对象模型的所有记录。
接着讲述下Jacob中两种最常用的类型:
Variant:这是一种可变的类型,用于Jacob中几乎所有函数的返回值,并可转换为其他任何类型,包括Java基本类型。当然,应该按需要与规则来。
Dispatch:Object represents MS level dispatch object. Each instance of this points at some data structure on the MS windows side.就是说可以代表所有对象模型。
有所了解后我们来看对模型的处理方式。
当我们获得一个模型后,如前面打开的doc文档,均已转换成一个Dispatch对象。只有转换后才能读取、设置其属性,或者调用其方法,如下:

// 获取其属性,表格的集合
Dispatch tables  =  Dispatch.get(doc,  " Tables " ).toDispatch();
// 调用方法取得其中的第一张表格
Dispatch table  =  Dispatch.call( this .tables,  " Item " new  Variant( 0 )).toDispatch();
// 修改此表格第一行第一列的单元格
Dispatch cell  =  Dispatch.call(table, " Cell " , Integer.toString( 1 ), Integer.toString( 1 )).toDispatch();
Dispatch.call(cell, 
" Select " );
Dispatch.put(cursor, 
" Text " , "New String");

这就是简单的处理,更多的还是多了解了解对象模型吧

3. 关闭文档及进程
// 关闭文档且不保存
Dispatch.call(doc,  " Close " new  Variant( false ));
// 退出进程对象
app.invoke( " Quit " new  Variant[] {});

更多请参看下载文件中的API帮助文档..

下面是我写的类,用于封装其功能。(注意,这个类并没有涉及多个word文档线程的处理)
import  com.jacob.com. * ;
import  com.jacob.activeX. * ;

/**
 *
 * 
@author  Lonsy
 
*/
public   class  WordHandle {
    
    
// 运行时的Word程序
     private  ActiveXComponent app;

    
// word对象
     private  Dispatch words;

    
// 当前的word文档
     private  Dispatch doc;

    
// 当前光标位置
     private  Dispatch cursor;

    
// 当前文档是否只读
     private   boolean  readOnly;

    
// 当前文档中所有表格
     private  Dispatch tables;

    
// 当前所在表格
     private  Dispatch table;

    
private   int  count;

    
public  WordHandle()
    {
        
this .app  =   new  ActiveXComponent( " Word.Application " );
        
this .app.setProperty( " Visible " new  Variant( false ));     //  设置word不可见
        words  =   this .app.getProperty( " Documents " ).toDispatch();
        
this .doc  =   null ;
        
this .cursor  =   null ;
        
this .readOnly  =   true ;
        
this .count  =   0 ;
    }

    
/**
     * 打开word文件
     * 
@param  fileName 文件名,使用绝对路径
     * 
@param  readOnly 是否只读
     * 
@return
     * 
@throws  java.lang.Exception
     
*/
    
public   boolean  open(String fileName,  boolean  readOnly)  throws  Exception
    {
        
if  (doc  !=   null )
        {
            System.out.println(
" 当前文件未关闭 " );
            
return   false ;
        }
        
this .doc  =  Dispatch.invoke( this .words,  " Open " , Dispatch.Method,  new  Object[] {fileName,  new  Variant( false ),  new  Variant(readOnly)},  new   int [ 1 ]).toDispatch();
        
this .cursor  =  app.getProperty( " Selection " ).toDispatch();
        
this .tables  =  Dispatch.get( this .doc, " Tables " ).toDispatch();
        
this .readOnly  =  readOnly;
        
this .count  =  Dispatch.get(Dispatch.get( this .doc,  " Words " ).toDispatch(),  " Count " ).getInt()  -   1 ;
        System.out.println(
" 打开文件 "   +  fileName  +  (readOnly  ?   "  ReadOnly "  :  "  Writable " ));
        
return   true ;
    }

    
/**
     * 建立新的Word文件
     * 
@return
     * 
@throws  java.lang.Exception
     
*/
    
public   boolean  newFile()  throws  Exception
    {
        
if  (doc  !=   null )
        {
            System.out.println(
" 当前文件未关闭 " );
            
return   false ;
        }
        
this .doc  =  Dispatch.call( this .words,  " Add " ).toDispatch();
        
this .readOnly  =   false ;
        
this .cursor  =  app.getProperty( " Selection " ).toDispatch();
        
this .tables  =  Dispatch.get( this .doc, " Tables " ).toDispatch();
        System.out.println(
" 新建word文档 " );
        
return   true ;
    }

    
/**
     * 关闭当前文件,并不保存
     * 
@return
     
*/
    
public   boolean  close()
    {
        String fileName 
=   null ;
        
if  ( this .doc  !=   null )
        {
            
try
            {
                fileName 
=  Dispatch.get( this .doc,  " Name " ).getString();
                Dispatch.call(
this .doc,  " Close " new  Variant( false ));
            }
            
catch  (Exception e)
            {
                e.printStackTrace();
            }
            
finally
            {
                
this .doc  =   null ;
            }
        }
        System.out.println(
" 关闭文件  "   +  fileName);
        
return   true ;
    }

    
/**
     * 退出
     * 
@return
     
*/
    
public   boolean  quit()
    {
        
try
        {
            
this .app.invoke( " Quit " new  Variant[] {});
        }
        
catch  (Exception e)
        {
            e.printStackTrace();
        }
        System.out.println(
" 退出word " );
        
return   true ;
    }

    
/**
     * 另存为
     * 
@param  fileName 目标文件名,为绝对路径
     * 
@return
     
*/
    
public   boolean  saveAs(String fileName)  throws  Exception
    {
        
if  ( this .doc  ==   null )
        {
            System.out.println(
" 当前无文件 " );
            
return   false ;
        }
        
else
        {
            Dispatch.call(
this .doc,  " SaveAs " , fileName);
            System.out.println(
" 另存为 "   +  fileName);
            
return   true ;
        }
    }

    
/**
     * 保存
     * 
@return
     
*/
    
public   boolean  save()  throws  Exception
    {
        
if  ( this .doc  ==   null )
        {
            System.out.println(
" 当前无文档,无法保存 " );
            
return   false ;
        }
        
else
        {
            
if  ( this .readOnly)
            {
                System.out.println(
" 只读文档,保存失败 " );
                
return   false ;
            }
            Dispatch.call(
this .doc,  " Save " );
            System.out.println(
" 保存完成 " );
            
return   true ;
        }
    }

    
/**
     * 将光标或选定内容向右移动
     * 
@param  step
     * 
@return
     
*/
    
public   boolean  moveRight( int  steps)  throws  Exception
    {
        
// int start = Dispatch.get(this.cursor, "Start").getInt();
        
// Dispatch.put(this.cursor, "Start", start + steps);
         for  ( int  i = 0 ; i < steps; i ++ )
        {
            Dispatch.call(cursor, 
" MoveRight " );
        }
        
return   true ;
    }

    
/**
     * 将光标或选定内容向左移动
     * 
@param  step
     * 
@return
     
*/
    
public   boolean  moveLeft( int  steps)  throws  Exception
    {
        
for  ( int  i = 0 ; i < steps; i ++ )
        {
            Dispatch.call(cursor, 
" MoveLeft " );
        }
        
return   true ;
    }

    
/**
     * 从当前位置起查找指定内容,并将光标移到相应位置上
     * 
@param  str
     * 
@return  光标位置,未找到则为0
     * 
@throws  java.lang.Exception
     
*/
    
public   int  search(String str)  throws  Exception
    {
        
//  从cursor所在位置开始查询
        Dispatch find  =  Dispatch.call( this .cursor,  " Find " ).toDispatch();
        
//  设置要查找的内容
        Dispatch.put(find,  " Text " , str);
        
//  向前查找
        Dispatch.put(find,  " Forward " " True " );
        
//  设置格式
        Dispatch.put(find,  " Format " " True " );
        
//  大小写匹配
        Dispatch.put(find,  " MatchCase " " True " );
        
//  全字匹配
        Dispatch.put(find,  " MatchWholeWord " " True " );
        
//  查找
         if  ( ! Dispatch.call(find, " Execute " ).getBoolean())
            
return   0 ;
        
else
        {
            
return  Dispatch.get( this .cursor,  " Start " ).getInt();
        }
    }

    
/**
     * 从当前位置起查找指定内容,并只将光标开始处移到相应位置上
     * 
@param  str
     * 
@return  光标位置,未找到则为0
     * 
@throws  java.lang.Exception
     
*/
    
public   int  searchOnly(String str)  throws  Exception
    {
        
//  从cursor所在位置开始查询
        Dispatch find  =  Dispatch.call( this .cursor,  " Find " ).toDispatch();
        
//  设置要查找的内容
        Dispatch.put(find,  " Text " , str);
        
//  向前查找
        Dispatch.put(find,  " Forward " " True " );
        
//  大小写匹配
        Dispatch.put(find,  " MatchCase " " True " );
        
//  全字匹配
        Dispatch.put(find,  " MatchWholeWord " " True " );
        
if  ( ! Dispatch.call(find, " Execute " ).getBoolean())
            
return   0 ;
        
else
        {
            
int  start  =  Dispatch.get( this .cursor,  " Start " ).getInt();
            Dispatch.put(
this .cursor,  " End " this .count);
            
// System.out.println(start);
             return  start;
        }
    }

    
public  String getBetween( int  start,  int  end)  throws  Exception
    {
        Dispatch range 
=  Dispatch.get( this .cursor,  " Range " ).toDispatch();
        Dispatch.call(range,
" SetRange " , start, end);
        
return  Dispatch.get(range,  " Text " ).getString();
    }

    
public  String getLineAfter( int  start)  throws  Exception
    {
        Dispatch.put(
this .cursor,  " Start " , start);
        
int  length  =  Dispatch.call( this .cursor,  " EndKey " ).getInt()  +  start;
        
return  getBetween(start, length);
    }

    
public  String getLine( int  position)  throws  Exception
    {
        Dispatch.put(
this .cursor,  " Start " , position);
        Dispatch.call(
this .cursor,  " SelectRow " );
        
int  start  =  Dispatch.get( this .cursor,  " Start " ).getInt();
        
int  end  =  Dispatch.get( this .cursor,  " End " ).getInt();
        
return  getBetween(start, start  +  end);
    }

    
public   boolean  gotoPage( int  index)  throws  Exception
    {
        Dispatch.invoke(
this .cursor,  " Goto " , Dispatch.Method,  new  Object[] { 1 2 , String.valueOf(index)},  new   int [ 1 ]);
        
// Dispatch.call(this.cursor, "GoTo", "wdGoToLine", "wdGoToNext", String.valueOf(index), null);
         return   true ;
    }

    
public   int  getCurrentCursor()  throws  Exception
    {
        
return  Dispatch.get( this .cursor,  " Start " ).getInt();
    }

    
public   boolean  setCursorMode()  throws  Exception
    {
        Dispatch.put(
this .cursor,  " End " , Dispatch.get( this .cursor,  " Start " ).getInt());
        
return   true ;
    }

    
public   boolean  gotoHome()  throws  Exception
    {
        Dispatch.put(
this .cursor,  " Start " 0 );
        
return   true ;
    }

    
/**
     * 在光标后指定便宜插入字符串,并将光标移到新位置
     * 
@param  str
     * 
@return
     * 
@throws  java.lang.Exception
     
*/
    
public   boolean  insert( int  steps, String str)  throws  Exception
    {
        
int  start  =  Dispatch.get( this .cursor,  " Start " ).getInt()  +  steps;
        Dispatch.put(
this .cursor,  " Start " , start);
        Dispatch.call(
this .cursor,  " InsertBefore " , str);
        
this .getCount();
        Dispatch.put(
this .cursor,  " Start " , start  +  str.length());
        
// System.out.println(Dispatch.get(this.cursor, "Start").getInt() + "   " + (Dispatch.get(this.cursor, "Start").getInt()+Dispatch.get(this.cursor, "End").getInt()));
         return   true ;
    }

    
/**
     * 用指定的字符串替代当前选定的内容
     * 
@param  str
     * 
@return
     * 
@throws  java.lang.Exception
     
*/
    
public   boolean  replace(String str)  throws  Exception
    {
        Dispatch.put(
this .cursor,  " Text " , str);
        
return   true ;
    }

    
/**
     * 获取当前文档中的表格数
     * 
@return
     * 
@throws  java.lang.Exception
     
*/
    
public   int  getTableNum()  throws  Exception
    {
        
return  Dispatch.get( this .tables,  " Count " ).getInt();
    }
    
    
/**
     * 设定当前工作表格
     * 
@param  index
     * 
@return
     * 
@throws  java.lang.Exception
     
*/
    
public   boolean  setCurrentTable( int  index)  throws  Exception
    {
        
this .table  =  Dispatch.call( this .tables,  " Item " new  Variant(index)).toDispatch();
        Dispatch.call(
this .table,  " Select " );
        
return   true ;
    }
    
    
/**
     * 获取指定单元格的内容
     * 
@param  row
     * 
@param  col
     * 
@return
     * 
@throws  java.lang.Exception
     
*/
    
public  String getCell( int  row,  int  col)  throws  Exception
    {
        Dispatch cell 
=  Dispatch.call(table,  " Cell " , Integer.toString(row), Integer.toString(col)).toDispatch();
        Dispatch.call(cell,
" Select " );
        String tmp 
=  Dispatch.get( this .cursor,  " Text " ).getString();
        
// System.out.println(".." + tmp);
         if  (tmp.length()  >   2 )
        {
            
return  tmp.substring( 0 , tmp.length()  -   2 );
        }
        
else
            
return   "" ;
    }

    
/**
     * 用指定的字符串代替当前表格中指定的单元格
     * 
@param  row
     * 
@param  col
     * 
@param  str
     * 
@return
     * 
@throws  java.lang.Exception
     
*/
    
public   boolean  replaceCell( int  row,  int  col, String str)  throws  Exception
    {
        Dispatch cell 
=  Dispatch.call(table, " Cell " , Integer.toString(row), Integer.toString(col)).toDispatch();
        Dispatch.call(cell, 
" Select " );
        Dispatch.put(
this .cursor,  " Text " , str);
        
return   true ;
    }
}

 

From: http://www.blogjava.net/lonsy/archive/2009/01/09/250713.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值