`
爱宝贝丶
  • 浏览: 7429 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

基于springboot的freemarker创建指定格式的word文档

 
阅读更多

       在web或其他应用中,经常我们需要导出或者预览word文档,比较实际的例子有招聘网站上预览或者导出个人简历,使用POI导出excel会非常的方便,但是如果想导出word,由于其格式控制非常复杂,故而使用POI将会非常麻烦,而FreeMarker则可以较好的解决这个问题;并且,根据FreeMarker的实现原理,预览word也会变得非常简单。

       FreeMarker主要有三个部分:模板,数据源以及数据的存储。可想而知,在导出word的时候,我们必须得告诉FreeMarker我们需要导出的word的格式以及将要填充到这个word中的数据,因而模板和数据源是我们需要准备的部分。这里需要另外说明的是,FreeMarker关心的不是模板文件的类型或具体内容,其关心的是模板文件中的ftl标签和其中获取数据的表达式(这部分将在后续进行讲解)。FreeMarker的强大之处也就在这个位置,这里的模板可以是任意类型的模板,而数据源由我们按照指定的格式封装即可。那么也就是说,对于预览操作,我们如果事先制作一个html模板,点击预览后由FreeMarker向按照该模板向新建的html文件中填充数据,接着在前台js中新开窗口将该html文件(填充数据后即为一个静态页面)显示出来即可达到预览的效果。

       这里我们以word文件的导出为例来讲解FreeMarker的使用,我们使用的IDE为Intellij IDEA,框架为springboot,项目是使用Maven构建的。

       模板文件的创建可以使用word2007及以上版本完成,首先我们创建一个如下格式的word文档:

       创建后将该文件以xml格式存储


       使用xml文本编辑器打开该xml文件,检查其中的取值表达式是否发生格式错误,如果发生格式错误就将其中错误的部分删除,使其恢复我们填写的格式(格式错误一般会发生在取值表达式中含有特殊字符的时候)。

        如图中所示,${user.password}就发生了格式错误,我们将中间错误部分删除后如下:

        接着将该模板文件另存为UserList.ftl,文件格式为全部文件:

       将该文件复制到项目中,打开并格式化,找到其中${user.username}和${user.password},仔细分析该ftl文件可以发现,在word文档中表格的每一行在xml文件中即为一个<w:tr></w:tr>标签,而在该标签中,每一个<w:tc></w:tc>则对应一个单元格。了解这个之后,我们就要使用ftl语法对该模板文件进行改造。这里我们需要导出的是一个用户列表的文件,每个用户包含一个用户名和密码,那么这里用户所在的这一行(<w:tr></w:tr>)就需要使用ftl中的<#list></#list>标签包含起来:

<#list users as user>
<w:tr>
<w:tc>
...
用户名:
...
</w:tc>
<w:tc>
...
${user.username}
...
</w:tc>
<w:tc>
...
密码:
...
</w:tc>
<w:tc>
...
${user.password}
...
</w:tc>
</w:tr>
</#list>

        到此为止,我们的ftl模板就制作完毕了。接下来我们创建后台服务端的代码,实体类创建如下:

 

public class User {
  
  private String username;
  private String password;

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public User() {
  }

  public User(String username, String password) {
    this.username = username;
    this.password = password;
  }
}

        Controller层创建如下:

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/word")
public class WordController {

  @Autowired
  private WordService wordService;

  @RequestMapping(value = "/createUserListWord", method = RequestMethod.GET)
  public ResponseEntity<Void> createUserListWord() {
    wordService.createUserListWord();
    return ResponseEntity.ok().build();
  }
}
        Service层的接口及其实现类如下:
public interface WordService {
  void createUserListWord();
}
 
import javax.transaction.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Service;
@Service
public class WordServiceImpl implements WordService {
  public void createUserListWord() {
    Map<?, ?> root = initData();  //数据源对象
    String template = "/template/UserList.ftl";  //模板文件的地址
    String path = "E:\\UserList.doc";  //生成的word文档的输出地址
    WordUtil.process(root, template, path);
  }

  private Map<?, ?> initData() {
    Map<String, Object> root = new HashMap<String, Object>();

    List<User> users = new ArrayList<User>();
    User zhangsan = new User("张三", "123");
    User lisi = new User("李四", "456");
    User wangwu = new User("王五", "789");
    users.add(zhangsan);
    users.add(lisi);
    users.add(wangwu);

    root.put("users", users);
    root.put("title", "用户列表");

    return root;
  }
}
        这里需要说明的一点是,在FreeMarker中,数据一般是以Map,List以及实体类对象的形式存储,这里数据的初始化函数中则将三种形式的数据存储方式都用到了。在模板中取值的时候,对于Map对象中的数据,使用${key}即可获取,这里key表示Map中的键,对于List,则可以使用下标的方式,也可以使用循环的方式,这里我们是将User对象存储于List中,在模板中则可以使用users[i]来获取List中第i个User对象,如users[i].username;也可以使用循环来对List集合进行遍历,如
<#list users as user>
  ${user.username}
</#list>
        这里users表示存储List的Map的key的值。

 

       最后则是FreeMarker中生成word文档的核心函数:

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

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

public final class WordUtil {
  private static Configuration configuration = null;

  private WordUtil() {
    throw new AssertionError();
  }

  /**
   * 根据模板生成相应的文件
   * @param root 保存数据的map
   * @param template 模板文件的地址
   * @param path 生成的word文档输出地址
   * @return
   */
  public static synchronized File process(Map<?, ?> root, String template, String path) {

    if (null == root ) {
      throw new RuntimeException("数据不能为空");
    }

    if (null == template) {
      throw new RuntimeException("模板文件不能为空");
    }

    if (null == path) {
      throw new RuntimeException("输出路径不能为空");
    }

    File file = new File(path);
    String templatePath = template.substring(0, template.lastIndexOf("/"));
    String templateName = template.substring(template.lastIndexOf("/") + 1, template.length());

    if (null == configuration) {
      configuration = new Configuration(Configuration.VERSION_2_3_23);  // 这里Configurantion对象不能有两个,否则多线程访问会报错
      configuration.setDefaultEncoding("utf-8");
      configuration.setClassicCompatible(true);
    }
    configuration.setClassForTemplateLoading(WordUtil.class, templatePath);

    Template t = null;
    try {
      t = configuration.getTemplate(templateName);
      Writer w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "utf-8"));
      t.process(root, w);  // 这里w是一个输出地址,可以输出到任何位置,如控制台,网页等
      w.close();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    return file;
  }

}
        至此,使用FreeMarker生成word文档的核心代码已经全部书写完毕,最后打开浏览器访问http://localhost:8081/word/createUserListWord,在E盘根目录下就会生成一个word文档,其内容如下:

        这只是FreeMarker的一个简单应用,关于FreeMarker生成html文件,这里有一点需要说明,word2007及以上版本保存文件的格式可以为xml文件,也可以为html文件,检查该html文件中取值表达式的格式无误之后按照上述步骤也可以生成我们需要的html文件,但是生成的html文件的格式不一定是我们需要的格式,并且在修改ftl模板的时候,由于模板中标签元素的样式等较多,因而修改较为复杂。若想达到预览的效果,我们可以不使用上述方法生成的html模板,而是手动书写一份格式一致的html文件,然后保存为ftl格式模板,这个过程并不复杂,并且可读性较强。
       以上就是本篇博客的全部内容,希望大家喜欢。
  • 大小: 5.3 KB
  • 大小: 83.3 KB
  • 大小: 163.5 KB
  • 大小: 164.1 KB
  • 大小: 67.1 KB
  • 大小: 7.2 KB
分享到:
评论

相关推荐

    springboot中使用freemarker动态生成word文档,以及使用POI导出自定义格式Excel

    Springboot项目中: 1. 使用Apache POI 3.9 自定义样式导出Excel文件...2. 使用freemarker动态生成word .doc文档(带图片Word以及复杂格式word) 详细说明见个人博客及 github: https://github.com/DuebassLei/excel-poi

    SpringBoot Freemarker定制word文档下载,支持文档内图文导出.rar

    3. **创建模板文件**:使用Freemarker语法编写Word文档的模板,模板文件通常以.ftl为扩展名。在模板中,我们可以定义文本、图片占位符,以及复杂的逻辑结构。 4. **构建数据模型**:根据业务需求,准备要填充到模板...

    Springboot+freemarker生成word

    接下来,我们需要创建一个FreeMarker模板文件(例如:`template.ftl`),定义Word文档的结构和内容。FreeMarker模板语言允许我们使用变量和控制结构来动态生成文档。例如: ```ftl &lt;!DOCTYPE html&gt; ${title} ${...

    SpringBoot_Freemarker生成Word_多个表格+两层嵌套循环

    SpringBoot_Freemarker生成Word_多个表格+两层嵌套循环; 步骤说明: 1.用Microsoft Office Word打开word原件;将文档中需要动态生成的内容,替换为属性名 ${name} 2.另存为,选择保存类型Word 2003 XML 文档(*....

    springboot的实现word文档下载.zip

    下载后的文件即为由Freemarker模板生成的Word文档。 通过以上步骤,我们就成功地实现了Spring Boot应用中使用Freemarker动态生成并提供Word文档下载的功能。这个示例展示了Spring Boot的灵活性以及与Freemarker集成...

    基于SpringBoot技术博客实现论文设计

    【标题】:基于SpringBoot技术博客实现论文设计 【摘要】:随着信息技术和网络技术的飞速进步,博客作为一种新型的表达方式应运而生,它不仅承载着个人的情感表达,还包含了丰富的智慧、意见和思想。博客平台的兴起...

    Freemarker导出word示例,包括jfreechart图表

    开发者可以创建一个Map或JavaBean作为数据模型,然后将这个模型传递给Freemarker,使其填充到模板中,生成最终的Word文档。 在描述中提到,我们还会用到JFreeChart库,这是一个用于生成各种图表的Java库,支持多种...

    freemarker 中文乱码解决

    1. **模板文件的编码**:如果模板文件的编码与Freemarker期望的编码不一致,就可能出现乱码。 2. **数据模型的编码**:当数据模型中的中文字符编码与模板引擎的默认编码不匹配时,也会导致乱码。 3. **页面输出的...

    freemarker + xml模板动态生成word 文档 源码

    Freemarker动态生成word,包含文字替换,freemarker嵌入自定义java函数,动态生成表格列,插入图片的示例,同时使用spire将wordxml格式转换成word文档(doc格式),还包含文件下载示例

    freemarker模板导出word循环图片表格源码和详细教程

    在导出Word文档时,SpringBoot框架可以很好地与Freemarker集成。首先,我们需要添加相应的依赖,如`spring-boot-starter-freemarker`和可能的Word处理库(如Apache POI)。然后,配置Freemarker模板的路径,创建一个...

    基于SpringBoot的开源数据库表结构导出word文档工具.zip

    标题 "基于SpringBoot的开源数据库表结构导出word文档工具.zip" 暗示了这是一个利用SpringBoot框架开发的开源工具,其主要功能是将数据库的表结构转换为Word文档格式。SpringBoot是Java生态系统中的一个流行框架,它...

    freemarker导出doc及docx

    总的来说,“freemarker导出doc及docx”涉及到了Freemarker模板引擎的使用、SpringBoot的集成、以及利用Apache POI等库处理Word文档的技巧。实际操作时,你需要根据项目需求定制模板,设置数据模型,最后通过编程...

    freemarker+xml动态模板生成doc文件技术

    `Freemarker`是一个强大的、基于模板的Java表达式语言,它被广泛用于生成HTML、XML以及其他文本格式的文件。结合XML模板,我们可以创建出高度可配置的文档生成方案。本篇文章将深入探讨如何利用`Freemarker`和XML来...

    Spring Boot 系列教程 freemarker导出word下载

    创建一个控制器方法,接收请求并使用FreeMarker模板引擎生成Word文档。Spring Boot提供了`FreemarkerTemplateUtils`工具类,可以帮助我们方便地处理模板和数据模型的合并。 ```java @Autowired private ...

    freeMarker导出word两种方式最全代码样例.rar

    首先,你需要在SpringBoot项目中配置FreeMarker模板引擎,然后创建一个FTL(FreeMarker模板)文件,该文件包含Word文档的结构和样式。在运行时,Java代码会填充模板中的变量,生成HTML字符串。接着,可以使用第三方...

    springboot参考指南中文word文档

    - **创建POM**: 使用Maven创建项目时需要定义POM文件。 - **添加classpath依赖**: 引入所需的Spring Boot Starter依赖。 - **编写代码**: - **@RestController和@RequestMapping注解**: 用于处理HTTP请求。 - **@...

    springboot医院核酸检测预约挂号微信小程序(java毕业设计完整源码+说明文档+LW).zip

    springboot医院核酸检测预约挂号微信小程序(java毕业设计完整源码+说明文档+LW) 系统主要包括管理员和用户;主要包括:首页、个人中心、用户管理、医院信息管理、预约时间段管理、核酸检测管理、核酸预约管理、...

    springmvc采用freemarker动态生成带图片的word

    在本项目中,我们将探讨如何利用SpringMVC与Freemarker来动态生成带有图片的Word文档。 SpringMVC是Spring框架的一部分,它是一个强大的Model-View-Controller(MVC)架构,用于开发Java Web应用程序。它提供了模型...

    基于Springboot的office文件处理服务组件

    包含以下服务: 1、基于JXLS实现excel动态图表模板导出功能 2、基于Freemarker实现word模板导出功能 3、基于OpenOffice实现word转pdf功能 4、基于itextpdf实现pdf添加水印功能

    Springboot vue导出功能实现代码

    Springboot Vue 导出功能实现代码知识点总结 一、Springboot Vue 导出功能实现代码概述 本文主要介绍了 Springboot Vue 导出功能实现代码,通过示例代码详细介绍了如何使用 Vue 2 和 Springboot 2.x 实现导出功能...

Global site tag (gtag.js) - Google Analytics