利用freemark构建word文档
本文重点利用freemarker生成word文档。基本思路是:先编辑好word模板,将模板另存为03版的xml文件,在xml文件中编辑freemarker标签,构建需要动态输出的数据,存放在一个map中,然后调用freemarker.template.Template.process(ObjectrootMap,Writerout)方法,将构建好的文件输出到指定的writer流中。
提示:在编辑word模板的时候可以在需要动态输出的地方先写好freemarker标签,类似于${..}这样的,这样方便在另存为的xml文件中找到我们要编辑的地方,因为word生成的xml会很长,比较复杂。注意检查xml文件中freemarker标签的正确性,会在${}中添加word标签,要将其删除。
在xml中找到需要循环的或者其它动态处理的地方,写上freemarker的FTL命令,以执行相应的动态输出。下面是我写的一个列子,用以动态输出数据库表结构到word文件中。import java.io.BufferedWriter; import java.io.File; 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 freemark.entity.Column; import freemark.entity.Table; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapper; import freemarker.template.Template; import freemarker.template.TemplateException; import freemarker.template.TemplateExceptionHandler; public class DocumentHandler { private Configuration configuration = null; private Map<Object, Object> dataMap = null; public DocumentHandler() { configuration = new Configuration(); configuration.setDefaultEncoding("UTF-8"); } public void createDoc(String templateDir, String templateFileName, String savePath) { // 设置模本装置方法和路径,FreeMarker支持多种模板装载方法。可以重servlet,classpath,数据库装载, Template t = null; try { // 从什么地方加载freemarker模板文件 configuration.setDirectoryForTemplateLoading(new File(templateDir)); // 设置对象包装器 configuration.setObjectWrapper(new DefaultObjectWrapper()); // 设置异常处理器 configuration .setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER); // 定义Template对象 t = configuration.getTemplate(templateFileName); } catch (IOException e) { e.printStackTrace(); } // 输出文档路径及名称 File outFile = new File(savePath); Writer out = null; try { out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(outFile), "UTF-8")); } catch (Exception e1) { e1.printStackTrace(); } try { t.process(dataMap, out); } catch (TemplateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (null != out) { try { out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } //构建数据 private Map<Object, Object> getData() { Map<Object, Object> map = new HashMap<Object, Object>(); List<Table> tables = new ArrayList<Table>(); Table table = new Table(); table.setTableName("tableName"); Column column = new Column(); column.setName("ID"); column.setType("varchar(50)"); column.setIsRequired("Yes"); column.setDesc("主键"); table.getColumns().add(column); tables.add(table); Table table1 = new Table(); table1.setTableName("tableName"); Column column1 = new Column(); column1.setName("ID"); column1.setType("varchar(50)"); column1.setIsRequired("Yes"); column1.setDesc("主键"); table1.getColumns().add(column1); tables.add(table1); map.put("tables", tables); return map; } public Map<Object, Object> getDataMap() { return dataMap; } public void setDataMap(Map<Object, Object> dataMap) { this.dataMap = dataMap; } public static void main(String[] args) { DocumentHandler dh = new DocumentHandler(); dh.setDataMap(dh.getData()); dh.createDoc("d:/test", "test.xml", "d:\\test\\outFile.doc"); } }
模板的xml文件中的关键内容如下:
<#list tables as table> ... <#list table.columns as column> ... </#list> ... </#list>