Java导出数据到Word模板.

  • 前言
  • 网上的方案
  • 需求介绍
    • 模板
    • 简介
  • 使用体验
        • poi-tl
      • Freemarker
    • 操作步骤
    • 总结

前言

相信很多人都会遇到Java导出的业务,Java导出主要有导出数据到Excel和Word,但是相比较而言对于导出数据到Excel的实现方案会比较成熟一些,网上的教程也是非常之多的.但是导出到Word的方案还是有所欠缺,一些简单的导出还是可以的,但是遇到一些比较复杂的Word模板导出就会很头疼.比如说:Word模板中有相对复杂的表格样式的时候,处理起来也就相对的复杂一些。
本次项目中,我就遇到了一个需要将数据库的数据导出到Word模板中的需求,而且Word模板中包含比较复杂的关系表格。
由于本人之前没有接触过导出之类的业务,所以走了不少弯路。

网上的方案

经过网上查询发现Java导出Word主要有以下几种方案:
以下内容转自子午线,需要详细参考请跳转

  1. Jacob是Java-COM Bridge的缩写,它在Java与微软的COM组件之间构建一座桥梁。通过Jacob实现了在Java平台上对微软Office的COM接口进行调用。
  2. Apache POI包括一系列的API,它们可以操作基于MicroSoft OLE 2 Compound Document Format的各种格式文件,可以通过这些API在Java中读写Excel、Word等文件。
  3. Java2word是一个在java程序中调用 MS Office Word 文档的组件(类库)。该组件提供了一组简单的接口,以便java程序调用他的服务操作Word 文档。 这些服务包括: 打开文档、新建文档、查找文字、替换文字,插入文字、插入图片、插入表格,在书签处插入文字、插入图片、插入表格等。
  4. FreeMarker生成word文档的功能是由XML+FreeMarker来实现的。先把word文件另存为xml,在xml文件中插入特殊的字符串占位符,将xml翻译为FreeMarker模板,最后用java来解析FreeMarker模板,编码调用FreeMarker实现文本替换并输出Doc。
  5. PageOffice生成word文件。PageOffice封装了微软Office繁琐的vba接口,提供了简洁易用的Java编程对象,支持生成word文件,同时实现了在线编辑word文档和读取word文档内容。

需求介绍

本人这里,是需要将数据库中的数据查询出,并且填充到Word模板中,并提供下载和导出到指定位置。

模板

简介

在本模板中,红色框中的表格有且可能有多个,蓝色框中的表格行有且可能有多条。需要从数据库中查询出相对应的数据并且填充到Word模板中,模板中红色框中的表格只有一个,需要根据查询出的数据动态的循环出多个,蓝色框中的同理有一个循环出多行。
属于一个典型的一对多对多的数据结构。

使用体验

看到这5中方案的时候,我大概的了解了以下,发现第二种POI是最近比较流行,并且便捷的,为了方便,便毫不犹豫的选择使用POI提供的 poi-tl 。

poi-tl

poi-tl(poi template language)是基于Apache POI的Word模板引擎。纯Java组件,跨平台,代码短小精悍,通过插件机制使其具有高度扩展性。支持DOCX格式的Word模板。

poi-tl 更为详细的介绍请自行跳转,http://deepoove.com/poi-tl/
我在使用poi-tl 的时候,很快的就将蓝框中的循环行给实现了,红色框内的基本数据可以填充,但是这个时候,我发现我无法实现将红色框内的表格循环多个。这就很蛋疼,我在网上查了好久也没有找到解决方案。于是我自己想到一个比较笨的方案,就是将上面的基础信息表格单独到一个Word模板中,然后将基础信息导出到基础的Word模板中,将下面的红色框中的表格单独到一个Word模板中,然后查询到若干条数据,就导出若干个Word文档,最后将这些Word文档合并为一个文档,然后将生成的多余的Word文档删除。现在想想这种方案也是很傻。但是这种方案也没有实现,应为每次删除文档的时候有权限问题,poi-tl 会将本次服务生成的Word文档抓着不放,只有将服务重启或关闭的时候才会删除掉,这就很鸡肋,为此还咨询了好多大佬,也不了了之。

Freemarker

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据,并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。

之后我便尝试使用Freemarker来实现此功能,其实之前我是使用过的,但由于了解不是很深,以为Freemarker的list循环只可以循环一层(说起来也是尴尬)。

操作步骤

使用Freemarker首先我们需要将Word模板转换成可以被Freemarker所识别操作的xml文件,我个人感觉最麻烦的就是准备模板,不知道为什么Word文档转换成xml形式的时候里面有些标签会被分隔开来,所以一定要细心。

  1. 首先将需要填充的数据对应的标签填入到模板中。


2. 将模板另存为xml格式,并将后缀改为(.ftl)。

将xml文件后缀更改为ftl
3. 将Word文档另存为xml文件时会出现之前写入的标签位置错乱问题。

这里我们需要将错误的格式,调整为可识别的状态。
如图。将选中的蓝色部分删除



修改完成后,如图。

注意,修改模板的时候,可能会遇到图片。

需要将这一长串删除替换为 ${image} 即可。
我们可以将图片存放在项目中,然后获取图片的绝对路径,并将图片进行转码,即可正常显示在导出的Word文档中了。

//获取图片的路径
String imagePath = this.getClass().getClassLoader().getResource("image.jpg").getPath();
//获得图片的Base64码public static String getImageBase(String src) throws Exception {if (src == null || src == "") {return "";}File file = new File(src);if (!file.exists()) {return "";}InputStream in = null;byte[] data = null;try {in = new FileInputStream(file);data = new byte[in.available()];in.read(data);in.close();} catch (IOException e) {e.printStackTrace();}Base64.Encoder encoder = Base64.getEncoder();return String.valueOf(encoder.encode(data));}

在修改模板时,我们本次的重点是循环表格。
我们直接在1级列表的最外层添加标签。
嵌套循环在表格中需要再次循环的标签上加标签。

<#-- 循环外层表格 -->
<#list xxxList as listKey><w:tbl><#-- 循环表格内的行 --><#list listKey.aaaaList as act><w:tr>.........</w:tr></#list></w:tbl></#list>

到这个时候,我们的模板就准备好了。

  1. 写Java代码获取数据并填充。
//这里我就省略部分参数
Map<String, Object> datas = new HashMap<>();
datas.put("qq",qq );
datas.put("ww",ww );
//图片
datas.put("image", getImageBase(imagePath));List<Map<String, Object>> xxxList = new ArrayList<>();
Map<String, Object> xxxMap = new HashMap<>();
xxxMap.put("aa",aa);
xxxMap.put("ss",ss);List<Map<String, Object>> aaaaList = new ArrayList<>();
Map<String, Object> aaaaMap = new HashMap<>();
aaaaMap.put("zz",zz);
aaaaMap.put("xx",xx);
aaaaList.add(aaaaMap);
xxxMap.put("aaaaList",aaaaList);
xxxList.add(xxxMap);
datas.put("xxxList",xxxList);ResponseEntity<byte[]> entity = wordUtil.createDoc(datas, "xxx.doc");```
 //createDocByteArrayOutputStream outputStream = null;OutputStreamWriter writer = null;configuration.setClassForTemplateLoading(this.getClass(), "/template");configuration.setEncoding(Locale.getDefault(),"utf-8");Template t=null;try {t = configuration.getTemplate("aa.ftl","utf-8");} catch (IOException e) {e.printStackTrace();}//输出文档路径及名称File outFile = new File(fileName);FileOutputStream fos=null;try {fos = new FileOutputStream(outFile);outputStream = new ByteArrayOutputStream();writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);} catch (FileNotFoundException e1) {e1.printStackTrace();}try {t.process(dataMap, writer);writer.close();fos.close();} catch (TemplateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}//设置请求头HttpHeaders headers = new HttpHeaders();headers.add("Content-Disposition", "attchement;filename=" + fileName);headers.add("Access-Control-Expose-Headers", "*");//设置请求状态HttpStatus statusCode = HttpStatus.OK;ResponseEntity<byte[]> entity = new ResponseEntity<byte[]>(outputStream.toByteArray(), headers, statusCode);return entity;
}

哦,对了,还有的朋友可能会遇到导出后,文件无法打开的问题。
有这么几种可能,就是在修改ftl模板的时候破坏了文档的结构,
还有就是 有几个不能够替换的字符我们需要特殊的处理。

.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;")

单个表格中,换行如何处理。

.replaceAll("\n", "<w:br/>")

总结

至此,我们就完成了一次较为复杂的Word导出任务。
第一次遇到这种需求,所以学习到了很多,也走了很多弯路,希望本文可以帮助到,被类似问题所困惑的小伙伴。
谢谢大家的阅读。

Java导出数据到Word模板中相关推荐

  1. java使用poi在word模板中替换柱状图、折线图、饼图、表格、文本、图片

    介绍 java使用poi在word模板中替换柱状图.折线图.饼图.表格.文本.图片 软件架构 安装教程 环境搭建:jdk1.8.0_291.maven1.8.0_291 IDEA工具:IntelliJ ...

  2. java导出数据到word文档中

    1.功能概述: web项目中,在html文件点击下载word文件,后台获取要输出的数据再导出到word文档中 2. 操作步骤: (1).新建word模板,凡是需要填充的数据用${xxxx},编辑好wo ...

  3. 最新实用版——JAVA使用POI替换Word模板中指定字符,并可插入图片。

    JAVA替换Word模板指定字符,并可插入图片. 在一年之前还之前有写过一篇使用jacob对word插入图片的博客.点击率蛮高8800多次,当然多亏了百度搜索引擎的帮忙

  4. Freemarker填充数据到word模板中

    目录 1 环境配置 2 doc文档或docx文档 3 另存为xml格式 4 核心代码 5.填充生成到docx 5.1.创建模板docx并取出document.xml 5.2.用winrar打开test ...

  5. java导出数据到excel模板_springboot+jxls 根据Excel模板 填写数据并导出

    项目结构 pom.xml net.sf.jxls jxls-core 1.0.6compile 学生信息表模板: ExcelUtiles package cn.bdqn.utils;import ne ...

  6. java导出excel与word文档

    导出excel与word 依赖如下 <!--导出excel文档,easyexcel的依赖:为了防止poi版本冲突--><dependency><groupId>co ...

  7. python 批量打印文档_使用python将Excel数据填充Word模板并生成Word

    [项目需求] Excel中有一万多条学生学平险数据,需要给每位学生打印购买回执单,回执单包括学生姓名,身份证号,学校等信息,目前只能从Excel拷贝数据到Word模板中,然后打印,效率及其低下,寻求帮 ...

  8. java向Word模板中替换书签数据,插入图片,插入复选框,插入Word中表格的行数据,删除表格行数据

    java向Word模板中替换书签数据,插入图片,插入复选框,插入Word中表格的行数据,删除表格行数据 使用插件:spire.doc 创建工具类,上代码: import com.spire.doc.D ...

  9. java poi实现word导出(包括word模板的使用、复制表格、复制行、插入图片的使用)

    java poi实现数据的word导出(包括word模板的使用.复制表格.复制行.插入图片的使用) 1.实现的效果 实现病人基本信息.多条病历数据.多项检查项图片的动态插入(网络图片) 2.模板 把w ...

最新文章

  1. k8s的imagePullSecrets如何生成及使用
  2. lua工具库penlight--05日期和时间
  3. Google和Baidu常用的搜索技巧--转
  4. unistd.h linux,Linux 标准库下的unistd.h
  5. java eclipse 入门_Eclipse使用入门教程介绍
  6. python调用摄像头人脸识别代码_OpenCV3-Python人脸识别方法—人脸识别与标记
  7. 好消息:Dubbo Spring Boot要来了
  8. 面向对象编程,设计原则,设计模式
  9. hadoop hdfs文件给其他账号授权
  10. tesseract box_使用Qt Box Editor在自定义数据集上训练Tesseract
  11. Excel VBA编程
  12. Trapcode Particular 5 - Particle
  13. 关于富文本编辑器froala editor和百度Ueditor使用问题
  14. jmp指令流程图怎么写_NS流程图是什么?规范实用的流程图工具
  15. Java编程思想 - 并发
  16. Java socket编程详解,TCPUDP实现
  17. 浅谈阿里云混合云新一代运维平台演进与实践
  18. 论企业组织架构的扁平化管理
  19. 华容道 java_Java-华容道
  20. 怎么渗透验证 mysql_mysql-渗透测试

热门文章

  1. paramiko使用
  2. 采用GlodWave软件制作个性化铃声
  3. QT实现固高运动控制卡示波器
  4. mysql8.0约束性语语句(主码、外码、NOT NULL/NULL、DEFAULT、UNIQUE、CHECK)
  5. 职场“站队”你站对了吗?
  6. 计算机中的表格中怎么排序,如何设置Excel表格的横向排序功能
  7. pretraining+fine tuning
  8. 【鸿蒙】《校园通》--校园生活模块
  9. i3 10100f和i5 9400f哪个好?
  10. [翻译]如何用YII写出安全的WEB应用