基于Freemarker和xml实现Java导出word

作者:经典鸡翅 时间:2022-07-11 23:15:12 

前言

最近做了一个调查问卷导出的功能,需求是将维护的题目,答案,导出成word,参考了几种方案之后,选择功能强大的freemarker+固定格式之后的wordxml实现导出功能。导出word的代码是可以直接复用的,于是在此贴出,并进行总结,方便大家拿走。

实现过程概览

先在word上,调整好自己想要的样子。然后存为xml文件。保存为freemarker模板,以ftl后缀结尾。将需要替换的变量使用freemarker的语法进行替换。最终将数据准备好,和模板进行渲染,生成文件并返回给浏览器流。

详细的实现过程准备好word的样式

我们新建一个word,我们应该使用Microsoft office,如果使用wps可能会造成样式有些不兼容。在新建的office中,设置好我们的表格样式。我们的调查问卷涉及到四种类型,单选,多选,填空,简答。我们做出四种类型的示例。

基于Freemarker和xml实现Java导出word

样式没有问题后,我们选择另存为word xml 2003版本。将会生成一个xml文件。

基于Freemarker和xml实现Java导出word

格式化xml,并用freemarker语法替换xml

我们可以先下载一个工具 firstobject xml editor,这个可以帮助我们查看xml,同时方便我们定位我们需要改的位置。
复制过去之后,按f8可以将其进行格式化,左侧是标签,右侧是内容,我们只需要关注w:body即可。

基于Freemarker和xml实现Java导出word

像右侧的调查问卷这个就是个标题,我们实际渲染的时候应该将其进行替换,比如我们的程序数据map中,有title属性,我们想要这里展示,我们就使用语法${title}即可。

基于Freemarker和xml实现Java导出word

freemarker的具体语法,可以参考freemarker的问题,在这里我给出几个简单的例子。

比如我们将所有的数据放置在dataList中,所以我们需要判断,dataList是不是空,是空,我们不应该进行下面的逻辑,不是空,我们应该先循环题目是必须的,答案是需要根据类型进行再次循环的。语法参考文档,这里不再赘述。

程序端引入freemarker


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

将我们的flt文件放在resources下的templates下。

后端代码实现

此代码可以复用,在此贴出


public class WordUtils {

private static Configuration configuration = null;
 private static final String templateFolder = WordUtils.class.getClassLoader().getResource("").getPath()+"/templates/word";
 static {
   configuration = new Configuration();
   configuration.setDefaultEncoding("utf-8");
   try {
     configuration.setDirectoryForTemplateLoading(new File(templateFolder));
   } catch (IOException e) {
     e.printStackTrace();
   }
 }

/**
  * @Description:导出word,传入request,response,map就是值,title是导出问卷名,ftl是你要使用的模板名
  */
 public static void exportWord(HttpServletRequest request, HttpServletResponse response, Map map, String title, String ftlFile) throws Exception {
   Template freemarkerTemplate = configuration.getTemplate(ftlFile);
   File file = null;
   InputStream fin = null;
   ServletOutputStream out = null;
   try {
     file = createDocFile(map,freemarkerTemplate);
     fin = new FileInputStream(file);
     String fileName = title + ".doc";
response.setCharacterEncoding("utf-8");
response.setContentType("application/msword");
response.setHeader("Content-Disposition", "attachment;filename="
      +fileName);
out = response.getOutputStream();
     byte[] buffer = new byte[512];
     int bytesToRead = -1;
     while((bytesToRead = fin.read(buffer)) != -1) {
       out.write(buffer, 0, bytesToRead);
     }
   }finally {
     if(fin != null) fin.close();
     if(out != null) out.close();
     if(file != null) file.delete();
   }
 }

/**
  * @Description:创建doc文件
  */
 private static File createDocFile(Map<?, ?> dataMap, Template template) {
   File file = new File("init.doc");
   try {
     Writer writer = new OutputStreamWriter(new FileOutputStream(file), "utf-8");
     template.process(dataMap, writer);
     writer.close();
   } catch (Exception e) {
     e.printStackTrace();
   }
   return file;
 }

}

有了工具类后,我们准备好我们的map数据。map里面的数据大家可以自行定义。然后调用utils中的导出方法即可。

WordUtils.exportWord(request, response, dataMap, "word", "demo.ftl");

来源:https://www.cnblogs.com/jichi/p/11921541.html

标签:Freemarker,xml,Java
0
投稿

猜你喜欢

  • Java静态代理与动态代理案例详解

    2021-12-09 19:55:44
  • Springboot 跨域配置无效及接口访问报错的解决方法

    2021-10-02 01:04:11
  • 详解Dagger2在Android开发中的新用法

    2021-08-23 22:39:40
  • 基于JWT的spring boot权限验证技术实现教程

    2022-07-20 01:48:58
  • java自动生成ID号的方法

    2023-11-18 11:17:56
  • 深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解

    2021-07-09 06:14:19
  • Java模拟有序链表数据结构的示例

    2023-09-26 22:25:30
  • C++实现softmax函数的面试经验

    2023-06-16 02:07:47
  • C# Partial:分部方法和分部类代码实例

    2022-04-07 11:28:26
  • 简单聊一聊Java线程池ThreadPoolExecutor

    2021-10-23 15:56:58
  • Java ThreadLocal的使用详解

    2023-11-29 04:48:43
  • springboot项目访问静态资源的配置代码实例

    2021-11-16 02:07:49
  • Spring Bean生命周期之属性赋值阶段详解

    2022-09-28 04:34:11
  • C#文件上传的简单实现

    2021-06-02 19:06:04
  • C# ListBox中的Item拖拽代码分享

    2022-04-12 14:06:41
  • 解决spring.thymeleaf.cache=false不起作用的问题

    2022-03-25 04:27:15
  • Spring boot工具类静态属性注入及多环境配置详解

    2022-10-02 16:12:37
  • 基于C#实现Windows服务状态启动和停止服务的方法

    2022-07-27 12:17:57
  • Java string类型转换成map代码实例

    2021-06-07 12:19:29
  • springmvc限流拦截器的示例代码

    2021-09-08 02:50:55
  • asp之家 软件编程 m.aspxhome.com