前一个月搞的一个招生项目需要动态生成word文档并插入数据。好找一遍发现了Java2Word这个包。java2word是com桥jacob包的封装,它专门针对word文档的操作做了封装,方便使用。
说实话,java2word本身做的不咋地,兼容性不好,也不大稳定。在设计解决方案的时候因为这一点费了不少劲。现总结如下:
1. 安装java2word。该过程将其中的jacob.dll动态链接库复制到system32目录下,可能还有注册操作;
2. 将java2word.jar包复制到tomcat的lib下,引用至工程的build path中,或者直接复制到工程lib下。这两步保证了其中的jacob类正常连接com组件;
3. 编写访问类(见附录);
Java2word中每个word文档对应一个document对象。Document对象拥有open、close、insert以及find和 replace等多种方法。另外,document还含有style属性及其getter和setter来设置word文档指定元素的格式,但这一属性我没用到。原因是只需在目标word文档中待插入数据的位置预先设置好格式,即可保证插入后的文档符合要求(除非需要动态改变)。
4. Eclipse的兼容性问题。
Java2word,或者说jacob本身对eclipse支持不是很好,在netbean上倒是可以正常调用。对于使用myeclipse的工程,仅按照上面设置可能会出错。这时可作如下处理:
将jacob.dll复制一份到eclipse使用的jdk/bin下(无需注册),这样就可以保证Jacob or java2word的正常工作。(这问题当时快把我给折腾死了)
5. Word本身对象模型的兼容性问题。
由于涉及到com组件,就必须考虑到与其通信的com组件本身的特性。我在开发时,系统环境是word 2007(当然是D版^^),结果错误百出,经常报java.lang.exception或者application.word没有注册的错误。在朋友提醒后我才恍然大悟:word2003跟2007的对象模型压根儿就是不一样的(至少有差别)。在换成2003后,问题搞定。
后话:其实对于传统word文档的操作一般都会使用asp.net等语言去完成,java与com组件的通信还是其一大软肋。当前的com桥有poi、jcom、jacob等。其中poi简洁易用但功能较弱,jacob功能强大但上手较慢,需视需求而定。
但这个问题在以openxml为基础的2007文档中是不存在的。2007文档实际上是对一组xml的压缩包,其内部结构可以通过将.docx的文档改名为.rar后打开查看便一目了然。这时我们只需要找到存储数据的xml,按照其格式来读取即可。
至于2007格式的word文档,见我转载的文章
Java操作office 2007文档。
/** * This is the basic class to operate office files by Java, it's not suggested * to use itself.Please use the classes derived from it. * * @filename: Convertor.java * @author Me */ package ***.***.system.document;
import com.heavenlake.wordapi.Document;
import java.io.File; import java.util.List;
public class Convertor{ Document doc = null; //DocumentLock dl = new DocumentLock( ); //加锁操作会与word程序本身的文件锁冲突
public Document open( String strFileName){ if ( "".equals( strFileName) || null == strFileName){ System.err.println( "File name error !"); return null; }
//lock the word document. The release operation will appear in the funtion close()
//dl.setFile( strFileName);
//dl.lock( );
// judge the state of the file
File file = new File( strFileName); if ( !file.canRead( )){ System.err.println( "File can not Read ! file:" + strFileName); return null; }
// Generate the Instance of Document
try{ doc = new Document( ); } catch ( Exception e1){ System.err.println( "Create Instance Failed (file name:" + strFileName); e1.printStackTrace( );
return null; }
// open the target document
try{ if ( null == doc){ return null; } doc.open( strFileName); return doc; } catch ( Exception e){ System.err.println( "The operation Open Failed (file name:" + strFileName); e.printStackTrace( );
// close without save
if ( !this.close( false)){ System.err.println( "Error occured when close the file:" + strFileName); }
return null; }// end catch
}
public boolean close( boolean bSave){ if ( null != doc){ // try to close
try{ doc.close( bSave); return true; } // if close failed
catch ( Exception e1){ // if bSave = true( means tried to close with save failed)
if ( bSave){ // try to close without save
try{ if ( null != doc){ doc.close( !bSave); } } // try to close without save failed
catch ( Exception e){ e.printStackTrace( ); }// end inner try
}// end inner if
System.err.println( "The operation Close Failed (document id:" + doc.toString( )); }// end outer try
finally { //dl.release( );
} } return false; }
/** * Copy a word's document from a template(not *.dot, but *.doc) * * @param from: * the template file * @param to: * the target file * @return: result of the copy operation */ public boolean copy( String from, String to) { if ( null == from || "".equals( from) || null == to || "".equals( to)) { return false; }
// 简单的复制操作。对副本进行插入动作,保证原word文档不因插入操作失败而被损坏
return CopyFile.copyFile( from, to); }
/** * insert data into the place identified by bookmarks * * @param file: * target file * @param bookmark: * List of bookmarks * @param data: * List of data * @return result of the Insert operation */ public boolean conv( String file, List< String> bookmark, List< String> data) { if ( bookmark.size( ) != data.size( )) { System.err.println( "The count differs (" + file + ":bookmark and data)"); return false; }
boolean result = false;
//Document doc = this.open( file);
if ( null == doc) { return result; } // open file and insert
try { result = true; for ( int i = 0; i < bookmark.size( ); i++) { // when exception occurs, continue with the section FOR
try { doc.insertAtBookmark( bookmark.get( i), data.get( i)); } catch ( Exception e) { System.err.println( "data insert failed (index:" + String.valueOf( i) + ")"); result = false; continue; } } } catch ( Exception e1) { System.err.println( "Open file failed when trying to insert data:" + file); // close the file
if ( !this.close( true)) { result = false; } } return result; }
public boolean insertPic( String strFileName, String bookmark, File fImage) { if ( null == fImage) { System.err.println( "Image to insert into is INVALID !"); return false; }
//Document doc = this.open( strFileName);
if ( null == doc) { return false; }
try { doc.insertAtBookmark( bookmark, fImage); return true; } catch ( Exception e) { System.err .println( "Open file failed when trying to insert image, file name is " + strFileName); e.printStackTrace( ); if ( !this.close( true)) { return false; } return false; } }
public boolean replaceText( String strFilePath, String toFindText, String toInsText, int index) { if ( null == strFilePath || "".equals( strFilePath)) { System.err.println( "Document Path is INVALID !"); return false; } else if ( null == toFindText || "".equals( toFindText)) { System.err.println( "Text to find is INVALID !"); return false; } else if ( null == toInsText || "".equals( toInsText)) { System.err.println( "Text to Insert is INVALID !"); return false; }
//Document doc = this.open( strFilePath);
if ( null == doc) { return false; }
// insert
int i = 0; try { // find to the former toFindText
for ( ; i < index; i++) { doc.find( toFindText); } // replace the next toFindText
if ( !doc.replace( toFindText, toInsText)) { System.err.println( "No Matching ! index:" + i); return false; } return true; } catch ( Exception e) { System.err.println( "Insert error ! File:" + strFilePath); e.printStackTrace( ); // close
if ( !this.close( true)) { return false; } return false; } }
//test//////////////////////////////
public static void main( String[] args) { Convertor conv = new Convertor( ); Convertor conv1 = new Convertor( ); conv.open( "e:/1.doc"); conv1.open( "e:/1.doc"); } }
|
阅读(3021) | 评论(0) | 转发(0) |