热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java导出2007版word(docx格式)freemarker+xml实现

http:www.itdaan.comimgs115121237e9ea84b730e1a98a1e0621e31f47f.jpeFreemarker+xml生成do

 

http://www.#.com/imgs/1/1/5/1/21/237e9ea84b730e1a98a1e0621e31f47f.jpe

 

Freemarker+xml生成docx

原理概述:word从2003版就支持xml格式,而freemarker是java封装的模板工具,两者结合也就是在xml中需要动态生成的部分调用freemarker的指令(类似于EL表达式),来生成我们需要的数据,再用流输出文件,就达到了写word的效果。

 

生成word的基本流程图如下:

 

 

1.       生成docx模板和xml模板

 

生成docx模板

 

按照项目需要生成固定格式的docx格式的模板。

为方便测试做了个简单的例子,docx模板的内容如下图:

 

生成xml模板

 

从docx模板中取出word/document.xml,由于docx属于zip格式,可以用winrar打开,如图:

 

 

 

除word文件夹外其它文件为基本配置文件,取出word/document.xml(存放word文件的文本内容)如下图:

 

 

 

需要把document.xml解压出来,修改里面需要从数据库导出的数据用freemarker的指令代替,例如${test} 同时可以用遍历函数

替换完成后相当于生成了xml模板

 

生成的Xml模板:

 

[html]  view plain  copy
 
  1. xml version="1.0" encoding="UTF-8" standalOne="yes"?>  
  2.   
  3. <w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14">  
  4. <w:body>  
  5. <w:p w:rsidR="009175C2" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">  
  6. <w:pPr>  
  7. <w:pStyle w:val="1"/>  
  8. <w:jc w:val="center"/>  
  9. <w:rPr>  
  10. <w:rFonts w:hint="eastAsia"/>  
  11. w:rPr>  
  12. w:pPr>  
  13. <w:bookmarkStart w:id="0" w:name="_GoBack"/>  
  14. <w:bookmarkEnd w:id="0"/>  
  15. <w:r>  
  16. <w:rPr>  
  17. <w:rFonts w:hint="eastAsia"/>  
  18. w:rPr>  
  19. <w:t>  
  20. 这是一个测试Wordw:t>  
  21. w:r>  
  22. w:p>  
  23. <w:p w:rsidR="005B5FB3" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">  
  24. <w:pPr>  
  25. <w:rPr>  
  26. <w:rFonts w:hint="eastAsia"/>  
  27. w:rPr>  
  28. w:pPr>  
  29. w:p>  
  30. <w:p w:rsidR="005B5FB3" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">  
  31. <w:pPr>  
  32. <w:rPr>  
  33. <w:rFonts w:hint="eastAsia"/>  
  34. w:rPr>  
  35. w:pPr>  
  36. w:p>  
  37. <w:p w:rsidR="005B5FB3" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">  
  38. <w:pPr>  
  39. <w:pStyle w:val="a3"/>  
  40. <w:numPr>  
  41. <w:ilvl w:val="0"/>  
  42. <w:numId w:val="1"/>  
  43. w:numPr>  
  44. <w:ind w:firstLineChars="0"/>  
  45. <w:rPr>  
  46. <w:rFonts w:hint="eastAsia"/>  
  47. w:rPr>  
  48. w:pPr>  
  49. <w:r>  
  50. <w:rPr>  
  51. <w:rFonts w:hint="eastAsia"/>  
  52. w:rPr>  
  53. <w:t>  
  54. ${test}w:t>  
  55. w:r>  
  56. <w:r>  
  57. <w:rPr>  
  58. <w:rFonts w:hint="eastAsia"/>  
  59. w:rPr>  
  60. <w:t xml:space="preserve">  
  61.  w:t>  
  62. w:r>  
  63. w:p>  
  64. <#list students as s>  
  65. <w:p w:rsidR="005B5FB3" w:rsidRDefault="005B5FB3" w:rsidP="005B5FB3">  
  66. <w:pPr>  
  67. <w:pStyle w:val="a3"/>  
  68. <w:numPr>  
  69. <w:ilvl w:val="0"/>  
  70. <w:numId w:val="1"/>  
  71. w:numPr>  
  72. <w:ind w:firstLineChars="0"/>  
  73. <w:rPr>  
  74. <w:rFonts w:hint="eastAsia"/>  
  75. w:rPr>  
  76. w:pPr>  
  77. <w:r>  
  78. <w:rPr>  
  79. <w:rFonts w:hint="eastAsia"/>  
  80. w:rPr>  
  81. <w:t>  
  82. ${s}  
  83. w:t>  
  84. w:r>  
  85. w:p>  
  86. >  
  87. <w:sectPr w:rsidR="005B5FB3" w:rsidRPr="005B5FB3">  
  88. <w:pgSz w:w="11906" w:h="16838"/>  
  89. <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/>  
  90. <w:cols w:space="425"/>  
  91. <w:docGrid w:type="lines" w:linePitch="312"/>  
  92. w:sectPr>  
  93. w:body>  
  94. w:document>  

 

 

2.       利用freemarker填充数据并生成word文件

 

这里把数据库中的数据放到map中,把map和xml模板交给freemarker来生成(填充完数据)的xml具体实现方法如下:

 

 

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

 

 

利用freemarker生成数据

调用freemarker中的process方法(上图中的方法)来填充数据。
例(用1中生成的xml为模板填充数据):


//xml的模板路径  template/test.xml
String xmlTemplate = "test.xml";
//填充完数据的临时xml
String xmlTemp = "d:\\temp.xml";
Writer w = new FileWriter(new File(xmlTemp));

//1.需要动态传入的数据
Map p = new HashMap();
List students = new ArrayList();
students.add("张三");
students.add("李四");
students.add("王二");
p.put("test", "测试一下是否成功");
p.put("students", students);

//2.把map中的数据动态由freemarker传给xml
XmlToExcel.process(xmlTemplate, p, w);

 注:下文中会给出源码这里只是方便理解。

 

导出word文件

 

利用java的zipFile 和 ZipOutputStream 及zipFile.getInputStream() 来根据docx模板导出 (需要把word/document.xml文件替换成(填充完数据)的xml)具体操作流程如下:

[java]  view plain  copy
 

推荐阅读
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • 本文介绍了在使用Laravel和sqlsrv连接到SQL Server 2016时,如何在插入查询中使用输出子句,并返回所需的值。同时讨论了使用CreatedOn字段返回最近创建的行的解决方法以及使用Eloquent模型创建后,值正确插入数据库但没有返回uniqueidentifier字段的问题。最后给出了一个示例代码。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 本文详细介绍了MySQL表分区的创建、增加和删除方法,包括查看分区数据量和全库数据量的方法。欢迎大家阅读并给予点评。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • C# WPF自定义按钮的方法
    本文介绍了在C# WPF中实现自定义按钮的方法,包括使用图片作为按钮背景、自定义鼠标进入效果、自定义按压效果和自定义禁用效果。通过创建CustomButton.cs类和ButtonStyles.xaml资源文件,设计按钮的Style并添加所需的依赖属性,可以实现自定义按钮的效果。示例代码在ButtonStyles.xaml中给出。 ... [详细]
  • 本文讨论了如何使用Web.Config进行自定义配置节的配置转换。作者提到,他将msbuild设置为详细模式,但转换却忽略了带有替换转换的自定义部分的存在。 ... [详细]
  • 本文介绍了如何使用PHP代码将表格导出为UTF8格式的Excel文件。首先,需要连接到数据库并获取表格的列名。然后,设置文件名和文件指针,并将内容写入文件。最后,设置响应头部,将文件作为附件下载。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 本文介绍了在Ubuntu系统中清理残余配置文件和无用内容的方法,包括清理残余配置文件、清理下载缓存包、清理不再需要的包、清理无用的语言文件和清理无用的翻译内容。通过这些清理操作可以节省硬盘空间,提高系统的运行效率。 ... [详细]
author-avatar
荒野中得生存
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有