java编程要实现对word的操作没有vb那种编程语言来得容易,得借助一些开源组件,其中就包括jacob、poi等,而poi应用得最为广泛,对word2003和2007的读和写word操作都十分方便。它是Apache组织的一个项目,早在2001年就已经发布了第一个版本,可以说是apache组织的一个老牌项目,到现在已经走过了10年光辉历程,目前最新版本是3.8的beta版本。下面就以该版本来演示如何实现对word进行读取和改写值操作。
本文的所有源代码可以通过下载poi实现对word读写操作源代码获得。
1.下载
下载3.8beta4版本,请记得一定要下载该版本,其他版本读取word模板并改写内容生成新的文件后,打开新文件时会提示“word无法读取文档,文档可能损坏。”,见下图
低版本poi生成word文档打开时的错误
2.集成到项目
这一步很简单,只要把下载后解压得到的poi-3.8-beta4-20110826.jar和poi-scratchpad-3.8-beta4-20110826.jar两个文件复制到java web项目的lib目录下就行了
3.制作word模板
把需要变动的值全部用代码来代替,例如你需要改变名称的值,则可以在模板中用name来表示。详细见附件中的doc文件。
4.调用接口方法实现对word的读写操作
整个过程就是先读取模板,然后修改内容,再重新生成新的文档保存到本地或者输出文件流提供下载,下面分别是生成新文档和输出文件流两种方式的代码片断,详细的代码请见附件中的ReadAndWriteDoc.java文件和ReadWriteAndDownloadDocServlet.java两个文件。
生成新文档的方式:
2 | String fileDir = new File(base.getFile(), "../../../../../doc/" ).getCanonicalPath(); |
3 | FileInputStream in = new FileInputStream( new File(fileDir+ "/laokboke.doc" )); |
4 | HWPFDocument hdt = new HWPFDocument(in); |
5 | Fields fields = hdt.getFields(); |
6 | Iterator<Field> it = fields.getFields(FieldsDocumentPart.MAIN).iterator(); |
8 |
System.out.println(it.next().getType()); |
12 | Range range = hdt.getRange(); |
13 | System.out.println(range.text()); |
15 | for (Map.Entry<String,String> entry:map.entrySet()) { |
16 |
range.replaceText(entry.getKey(),entry.getValue()); |
18 | ByteArrayOutputStream ostream = new ByteArrayOutputStream(); |
19 | String fileName = "" +System.currentTimeMillis(); |
21 | FileOutputStream out = new FileOutputStream(fileDir+ "/" +fileName, true ); |
24 | out.write(ostream.toByteArray()); |
输出文件流下载方式:
2 | String fileDir = new File(base.getFile(), "../../../../../doc/" ).getCanonicalPath(); |
3 | FileInputStream in = new FileInputStream( new File(fileDir+ "/laokboke.doc" )); |
4 | HWPFDocument hdt = new HWPFDocument(in); |
5 | Fields fields = hdt.getFields(); |
6 | Iterator<Field> it = fields.getFields(FieldsDocumentPart.MAIN).iterator(); |
8 |
System.out.println(it.next().getType()); |
12 | Range range = hdt.getRange(); |
13 | Map<String, String> map= new HashMap<String, String>(); |
14 | map.put( "title" , "老k博客" ); |
15 | map.put( "blog_name" , "老k博客" ); |
16 | map.put( "domain_name" , "laokboke.net" ); |
17 | map.put( "description" , "是一个专注于wordpress、java、gis、建站、网站推广、seo的IT博客。" ); |
18 | for (Map.Entry<String,String> entry:map.entrySet()) { |
19 |
range.replaceText(entry.getKey(),entry.getValue()); |
24 | response.setContentType( "application/x-msdownload" ); |
25 | response.addHeader( "Content-Disposition" , "attachment; filename=\"laokboke.doc\"" ); |
26 | ByteArrayOutputStream ostream = new ByteArrayOutputStream(); |
27 | ServletOutputStream servletOS = response.getOutputStream(); |
29 | servletOS.write(ostream.toByteArray()); |