如何向word文档写入数据

第二篇文章,代码更精简,增加生成图片的思路

 

大致流程:

如何向word文档写入数据

1.创建模板docx并取出document.xml

 

新建一个docx文档,放在D盘命名test_template.docx

如何向word文档写入数据

 

2.用winrar打开test_template.docx,取出word/document.xml

把xml文件格式化一下看起来更清晰,并且把要替换的内容用freemarker的指令代替,最后将文件重命名为test.xml放在D盘下面

如何向word文档写入数据

3.准备工作完毕,上代码了,这个类是把内容填充到xml

[java] view plain copy

  1. import java.io.File;  
  2. import java.io.IOException;  
  3. import java.io.Writer;  
  4. import java.util.Map;  
  5.   
  6. import freemarker.template.Configuration;  
  7. import freemarker.template.Template;  
  8. import freemarker.template.TemplateException;  
  9.   
  10. public class XmlToExcel {  
  11.   
  12.     private static XmlToExcel tplm = null;  
  13.     private Configuration cfg = null;  
  14.   
  15.     private XmlToExcel() {  
  16.         cfg = new Configuration();  
  17.         try {  
  18.             // 注册tmlplate的load路径  
  19.             // cfg.setClassForTemplateLoading(this.getClass(), "/template/");  
  20.             cfg.setDirectoryForTemplateLoading(new File("D:/"));  
  21.         } catch (Exception e) {  
  22.   
  23.         }  
  24.     }  
  25.   
  26.     private static Template getTemplate(String name) throws IOException {  
  27.         if (tplm == null) {  
  28.             tplm = new XmlToExcel();  
  29.         }  
  30.         return tplm.cfg.getTemplate(name);  
  31.     }  
  32.   
  33.     /** 
  34.      *  
  35.      * @param templatefile 模板文件 
  36.      * @param param 需要填充的内容 
  37.      * @param out 填充完成输出的文件 
  38.      * @throws IOException 
  39.      * @throws TemplateException 
  40.      */  
  41.     public static void process(String templatefile, Map param, Writer out) throws IOException, TemplateException {  
  42.         // 获取模板  
  43.         Template template = XmlToExcel.getTemplate(templatefile);  
  44.         template.setOutputEncoding("UTF-8");  
  45.         // 合并数据  
  46.         template.process(param, out);  
  47.         if (out != null) {  
  48.             out.close();  
  49.         }  
  50.     }  
  51. }  

4.这个类是把填充完毕的xml转成docx

[java] view plain copy

  1. import java.io.File;  
  2. import java.io.FileInputStream;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.util.Enumeration;  
  7. import java.util.zip.ZipEntry;  
  8. import java.util.zip.ZipException;  
  9. import java.util.zip.ZipFile;  
  10. import java.util.zip.ZipOutputStream;  
  11.   
  12. /** 
  13.  * 其实docx属于zip的一种,这里只需要操作word/document.xml中的数据,其他的数据不用动 
  14.  *  
  15.  * @author yigehui 
  16.  *  
  17.  */  
  18. public class XmlToDocx {  
  19.   
  20.     /** 
  21.      *  
  22.      * @param documentFile 动态生成数据的docunment.xml文件 
  23.      * @param docxTemplate docx的模板 
  24.      * @param toFileName 需要导出的文件路径 
  25.      * @throws ZipException 
  26.      * @throws IOException 
  27.      */  
  28.   
  29.     public void outDocx(File documentFile, String docxTemplate, String toFilePath) throws ZipException, IOException {  
  30.   
  31.         try {  
  32.             File docxFile = new File(docxTemplate);  
  33.             ZipFile zipFile = new ZipFile(docxFile);  
  34.             Enumeration<? extends ZipEntry> zipEntrys = zipFile.entries();  
  35.             ZipOutputStream zipout = new ZipOutputStream(new FileOutputStream(toFilePath));  
  36.             int len = -1;  
  37.             byte[] buffer = new byte[1024];  
  38.             while (zipEntrys.hasMoreElements()) {  
  39.                 ZipEntry next = zipEntrys.nextElement();  
  40.                 InputStream is = zipFile.getInputStream(next);  
  41.                 // 把输入流的文件传到输出流中 如果是word/document.xml由我们输入  
  42.                 zipout.putNextEntry(new ZipEntry(next.toString()));  
  43.                 if ("word/document.xml".equals(next.toString())) {  
  44.                     InputStream in = new FileInputStream(documentFile);  
  45.                     while ((len = in.read(buffer)) != -1) {  
  46.                         zipout.write(buffer, 0, len);  
  47.                     }  
  48.                     in.close();  
  49.                 } else {  
  50.                     while ((len = is.read(buffer)) != -1) {  
  51.                         zipout.write(buffer, 0, len);  
  52.                     }  
  53.                     is.close();  
  54.                 }  
  55.             }  
  56.             zipout.close();  
  57.         } catch (Exception e) {  
  58.             e.printStackTrace();  
  59.         }  
  60.     }  
  61. }  

5.main方法调用

[java] view plain copy

  1. public static void main(String[] args) throws IOException, TemplateException {  
  2.   
  3.         try {  
  4.             // xml的文件名  
  5.             String xmlTemplate = "test.xml";  
  6.             // docx的路径和文件名  
  7.             String docxTemplate = "d:\\test_template.docx";  
  8.             // 填充完数据的临时xml  
  9.             String xmlTemp = "d:\\temp.xml";  
  10.             // 目标文件名  
  11.             String toFilePath = "d:\\test.docx";  
  12.   
  13.             Writer w = new FileWriter(new File(xmlTemp));  
  14.             // 1.需要动态传入的数据  
  15.             Map<String, Object> p = new HashMap<String, Object>();  
  16.             List<String> students = new ArrayList<String>();  
  17.             students.add("张三");  
  18.             students.add("李四");  
  19.             students.add("王二");  
  20.             p.put("ddeptdept""研发部门");  
  21.             p.put("ddatedate""2016-12-15");  
  22.             p.put("dnamename", students);  
  23.   
  24.             // 2.把map中的数据动态由freemarker传给xml  
  25.             XmlToExcel.process(xmlTemplate, p, w);  
  26.   
  27.             // 3.把填充完成的xml写入到docx中  
  28.             XmlToDocx xtd = new XmlToDocx();  
  29.             xtd.outDocx(new File(xmlTemp), docxTemplate, toFilePath);  
  30.         } catch (Exception e) {  
  31.             e.printStackTrace();  
  32.         }  
  33.     }  
  34.