简介

之前项目中有一个生成word文档的功能,根据数据库的数据进行word文档的生成,当时实现了该功能,但没有打笔记忘记了,特此打个笔记记录一下

我使用的freemarker的技术来实现word的生成,网上也都比较推荐该方式,他是通过根据一个模板,进行填充的方式实现word的生成

准备工作

定义word模板

我们要使用freemarker生成word,首先要自己去定义一个doc模板,模板中要填充的数据使用字符串模板的方式定义  ${ 字段名 }

定义完我们的模板之后,我们要将文档保存为xml的格式

修改保存的xml文件

保存完的xml文件是一行的不好查看,我们可以提前复制到idea中,使用ctrl + alt  + l  进行格式化,就变成标准的xml格式了

保存为xml常见的问题就是${name}被拆开了,我们要进行修改

修改为下面这样(多余的wr直接删除即可)

基础信息的定义

基础信息的定义只要保证我们转化成的xml文件中的${name} , ${age}格式没错误即可

表格的定义

遍历实现,表格的数据填充

在xml文件中我们的 <w:tbl>  代表是我们的表格 ,<w:tr>  代表的是我们的行  ,<w:tc>  代表我们的列

我们要想使用表格的方式,肯定大部分是要使用我们的list集合进行数据填充的,我们可以通过下面的方式进行遍历填充数据

我们在表格的表头下的<w:tr>上添加

 <#list bookList as book>

在我们</w:tr>下添加

</#list>

其中bookList代表我们要遍历的集合,book代表出来的结果,book.month代表book中的字段

实现单元格的合并

有两个标签

该标签表示,从这个开始进行合并

<w:vMerge w:val="restart"/>

该标签表示,只要带这个标签他就与上面的这个标签合并

<w:vMerge/>

我们将这两个标签定义到我们要合并的单元格的<w:tcPr>中

<w:tcPr><w:tcW w:w="2765" w:type="dxa"/><#-- 表示居中--><w:vAlign w:val="center"/><#-- 将month 等于1 和 2的进行合并--><#if book.month == 1><w:vMerge w:val="restart"/></#if><#if book.month == 2><w:vMerge/></#if>
</w:tcPr>

图片的插入

首先我们要在指定位置添加一个图片,我们保存为xml文件后,我们的图片信心会变为base64转码的字符串,将这部分进行删除,替换为${images},所以我们进行填充时也要是base64转码后的数据

修改xml文件为ftl文件

最后将我们的文件修改为 .ftl   格式的文件复制到我们 templates文件夹下

代码实现

首先要导入我们的freemarker依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency>

定义我们要填充的数据

    public Map<String,Object> dataMap() throws IOException {//获取基础数据Map<String , Object> map = new HashMap<>();map.put("name","qtt");map.put("age","25");//获取表格数据List<Map<String,Object>> bookList = new ArrayList<>();for (int i = 0; i < 5; i++) {Map<String, Object> map1 = new HashMap<>();map1.put("month",i);map1.put("income", i);map1.put("expense", i +100);bookList.add(map1);}map.put("bookList",bookList);//获取图片流且进行base64转码File file = new File("C:\\Users\\Administrator\\Desktop\\teacher\\01.jpg");FileInputStream fileInputStream = new FileInputStream(file);byte[] bytes = new byte[fileInputStream.available()];fileInputStream.read(bytes);BASE64Encoder base64Encoder = new BASE64Encoder();String encode = base64Encoder.encode(bytes);map.put("images",encode);//关闭流fileInputStream.close();return map;}

定义我们我们的填充方法

    @Testpublic void insertWord() throws IOException, TemplateException {//定义我们的编码方式Configuration configuration = new Configuration();configuration.setDefaultEncoding("UTF-8");//指定我们word的目录configuration.setDirectoryForTemplateLoading(new File("src/main/resources/templates"));//指定我们要使用的word模板.ftlTemplate template = configuration.getTemplate("模板.ftl", "UTF-8");//指定输出流到的位置BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:/222/demo.doc"), "UTF-8"));//执行填充输出template.process(this.dataMap(),bufferedWriter);//关闭io流bufferedWriter.flush();bufferedWriter.close();}

我们还可以直接定义为下载,不用使用输出流指定下载地址,直接通过下载的方式指定地址

    @GetMapping("/upload")public void upload(HttpServletResponse response){try {//定义我们的编码方式Configuration configuration = new Configuration();configuration.setDefaultEncoding("UTF-8");//指定我们word的目录configuration.setDirectoryForTemplateLoading(new File("src/main/resources/templates"));//指定我们要使用的word模板.ftlTemplate template = configuration.getTemplate("模板.ftl", "UTF-8");//返回word文档SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");String format = simpleDateFormat.format(new Date());String fileName = URLEncoder.encode("接口文档" + format, "UTF-8");response.setCharacterEncoding("UTF-8");//请求头定义为下载response.setHeader("Content-Disposition","attachment;filename="+fileName+".doc");//获取apiDoc所需要的数据Map<String, Object> map = dataMap();//渲染模板template.process(map, response.getWriter());//response的Writer不需要我们手动关,tomcat会帮我们关的} catch (Exception e) {log.error("导出word异常:", e);}}

遇到的坑

1.优为注意:freemarker是不支持  null 的,所以我们的数据要么全部附上值,要么给为空的值设置为 " " ,否则会报错

2.我们在定义表格l遍历填充的时候,一定要注意传入的表格字段类型是list,不能是map,否则会报错

3.和并单元格的时候,查看的文章,它定义的标签是m是小写,实现不了合并,看其他文章都为大写M,修改实现了合并,有大小写区分

无法合并的情况

<w:vmerge w:val="restart"/>
<w:vmerge/>

修改后可以合并

<w:vMerge w:val="restart"/>
<w:vMerge/>

java实现生成word文档相关推荐

  1. 关于用java编写生成word文档,动态添加数据到word文档的一些心得

    关于用java编写生成word文档,动态添加数据到word文档的一些心得,经过翻阅了无数的有用的和无用的资料以后,总算找到了一种靠谱的方法 1.概述 经过反反复复的查阅资料,总算找到了一个靠谱的生成w ...

  2. Java freemarker 生成word文档

    工具类 package cn.gh.util;import freemarker.template.Configuration; import freemarker.template.Template ...

  3. java itext 生成word文档

    /**       *  创建word文档 步骤:          * 1,建立文档          * 2,创建一个书写器          * 3,打开文档          * 4,向文档中 ...

  4. Java动态生成word文档(图文并茂)

    很多情况下,软件开发者需要从数据库读取数据,然后将数据动态填充到手工预先准备好的Word模板文档里,这对于大批量生成拥有相同格式排版的正式文件非常有用,这个功能应用PageOffice的基本动态填充功 ...

  5. java导出生成word文档_java使用freemarker 生成word文档

    最近需要做一个导出word的功能, 在网上搜了下, 有用POI,JXL,iText等jar生成一个word文件然后将数据写到该文件中,API非常繁琐而且拼出来的样式也不美观,于是选择了另一种方式--- ...

  6. Java POI 生成Word文档

    在开发中有时候我们需要导出 word文档.最近因为需要做一个生成word文件的功能.就将这块拿出来和大家分享. 生成word文件和我们写word文档是相同的概念,只不过在这里我们换成了用代码来操作.下 ...

  7. java导出生成word文档并进行下载的方法

    前端html内容展示 <div class="col-md-1 col_top_daochu">导出内容并进行下载 </div> 前端js内容展示 < ...

  8. Java poi 生成word文档并下载

    我使用的是Springboot框架开发的.首先需要在pom.xml文件中引入以下maven包: <dependency><groupId>org.apache.poi</ ...

  9. Java使用FreeMarker自动生成Word文档(带图片和表单)

    Java使用FreeMarker自动生成Word文档(带图片和表单) 1 背景 2 目标效果 3 创建Word模板 3.1 创建模板文档 3.2 转换模板文档 3.3 处理模板文档中的占位符 3.4 ...

最新文章

  1. 资源 |​ 史上最全机器学习笔记
  2. 关于Sqlite的一个demo
  3. 在项目中代替DevExpress(一)
  4. 解析远程服务器响应错误,远程服务器返回一个意外的响应:(400)错误的请求,WCF...
  5. wxWidgets:wxArchiveClassFactory类用法
  6. Angular源代码里字母Theta的含义
  7. 从Linux到Meego
  8. python协成_Python协程技术的演进
  9. (数据库系统概论|王珊)第三章关系数据库标准语言SQL-第二、三节:数据定义
  10. 【jQuery笔记Part2】03-jQuery-addBack()与end()的区别-children()与find()的区别
  11. tomcat start 无法启动_解密Springboot内嵌Tomcat
  12. Android病毒家族及行为(一)
  13. linux硬盘检测工具下载,硬盘健康检测软件(HDSentinel Linux服务器版)
  14. 5G终端难占用锚点小区导致无法驻留5G
  15. java logger 乱码_Log4j乱码
  16. VIP邮箱移动办公平台软件,疫情居家办公小助手
  17. 视觉注意力的循环神经网络模型
  18. 使用PHPstudy在Windows服务器下部署PHP系统
  19. flag.Args()和 flag.NArg()的用法
  20. ip地址映射-方便开发微信公众号,小程序等

热门文章

  1. java oom分析_Java OOM 分析
  2. Andoid鬼点子 近期项目总结(2) 日历
  3. 修改系统环境变量path
  4. 网络协议及网络软件框架设计网络协议
  5. node安装步骤以及环境配置
  6. DNS、HTTP 与 HTTPS
  7. 【五月英语——我该如何去奔跑!】
  8. 教你在Android手机上使用全局代理!
  9. 挣1万,可能靠的是体力。挣10万,也许靠的是脑力。挣100万靠什么?
  10. 给字符数组赋值java_给字符数组赋值的方法