最近做项目,需要导出word文档的报表,网上查询了一些资料,感觉用xml做这个相对比较简单,Word从2003开始支持XML格式,大致的思路是先用office2003或者2007编辑好word的样式,然后另存为xml,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板并输出Doc。经测试这样方式生成的word文档完全符合office标准,样式、内容控制非常便利,打印也不会变形,生成的文档和office中编辑文档完全一样。

 以下是实现步骤:

 1 先导入FreeMarker的jar包(网上搜),如果是maven工程的话,导入坐标:

<dependency>
		    <groupId>org.freemarker</groupId>
		    <artifactId>freemarker</artifactId>
		    <version>2.3.21</version>
		</dependency>

 2 用word文档先做一个你想要的模板的文件:

java xml转word java xml转word文档_xml


然后将word另存为.xml文件,打开文件,找到title将其修改为${title},后面要替换的内容依次替换掉

(凡是表格中是英文标识的地方都替换掉)。然后将.xml文件后缀改为.ftl,导入.ftl模板文件到指定目录

(这个指定目录是指跟你的导出word的java类经过编译后的class文件要在同一目录下,

比如我的java类的路径是 :D:\Java\myWorkspace\zdw-crm\target\classes\com\chinacreator\c2\expword,

那么我就在我的模板文件在如下图所示的位置:

java xml转word java xml转word文档_xml导出word_02


3 开始写代码:

 

package com.chinacreator.c2.expword;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class WordTest {
	 private Configuration configuration = null;  
	       
	      public WordTest(){  
	          configuration = new Configuration();  
	          configuration.setDefaultEncoding("UTF-8");  
	      }  
	       
	     public static void main(String[] args) {  
	         WordTest test = new WordTest();  
	         test.createWord();  
	     }  
	      
	     public String createWord(){  
	         Map<String,Object> dataMap=new HashMap<String,Object>();  
	         getData(dataMap);  
	         
	         
	         
	         configuration.setClassForTemplateLoading(this.getClass(),"");//模板文件所在路径
	         Template t=null;  
	         try {  
	             t = configuration.getTemplate("score.ftl"); //获取模板文件
	         } catch (IOException e) {  
	             e.printStackTrace();  
	         }  
	        
	         //File outFile = new File("D:/outFile"+Math.random()*1000000000+".doc"); //导出文件
	         
	        String url = this.getClass().getResource("/").getPath();
	 		url = url + "我的word文档" + ".doc";

	 		File outFile = new File(url); // 导出文件
	         
	         Writer out = null;  
	         try {  
	             out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile)));  
	         } catch (FileNotFoundException e1) {  
	             e1.printStackTrace();  
	         }  
	           
	        try {  
	             t.process(dataMap, out); //将填充数据填入模板文件并输出到目标文件 
	         } catch (TemplateException e) {  
	             e.printStackTrace();  
	        } catch (IOException e) {  
	             e.printStackTrace();  
	         }  
	       
	        return "我的word文档";
	     }  
	  
	     private void getData(Map<String, Object> dataMap) {  
	         dataMap.put("title", "标题");  
	         dataMap.put("year", "2018");  
	         dataMap.put("month", "1");  
	         dataMap.put("day", "6");   
	         dataMap.put("shenheren", "张无忌");  
	          
	         List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();  
	         for (int i = 0; i < 10; i++) {  
	             Map<String,Object> map = new HashMap<String,Object>();  
	             map.put("sid", i);  
	             map.put("name", "张三"+i);  
	             map.put("age", 23+i);
	             map.put("sex", "男");
	             list.add(map);  
	         }  
	          
	          
	         dataMap.put("list", list);  
	     }  
	     
}



4 继续修改你刚才放到那个目录下的模板文件,你会发现你的模板文件打开之后的格式是错乱的,所以建议你参照这个博主写的去

修改(地址:)

修改模板文件的内容是:

 修改.ftl文件,找到列表所在位置,将其要加入的列表加入到文件中。在列表前加入<#list list as l>(在它的头上加一个<#list 你的集合名称 as xxxx>),并在结尾加上</#list>。修改list内容,在要输出的名字前面加上l.。如name,修改为l.name。这样有点像EL表达式的使用。

下面是我的模板文件的部分截图:

 

java xml转word java xml转word文档_java xml转word_03

基本上就完成了,动手试试吧!!!!