前言:最近要做一个导出word功能,其实网上有很多的例子,但是我需要的是合并单元格的,可是查了好久都没有自己想要的。研究了几天其实挺简单的,在这儿我就简单的介绍一下吧!(此方法只是一种思路,借鉴者还有根据需求来具体写代码)

一、准备工作

1、jar包:freemarker-2.3.20.jar

2、模板:word.ftl

2.1:这个word.ftl怎么来?

首先准备一份要导出的word.doc文档;

这是一个事先写好的一个word模板,我们需要做的就是把需要导出的数据相应的插入${}到里面(其实如果你了解freemarker就会明白的,${}是个占位符,来放数据的,这里不详细介绍)。

如果下面的表格是固定的,比如像我们的课程表,那种是固定的,就特别简单了。我要做的就是下面的表格需要根据数据的不同,实现合并单元格,先看一下生成以后的效果:

大家可以看一下,前面三个格子是合并以后的,当然,如果后面两个格子的数据只有一行,那么也就是一行就行了。

2.2 将word.doc 转化成word.xml

个人觉得,其实word就是一个xml文件。打开这个word,然后另存为xml格式,然后你再用office打开这个xml,也是可打开的。

然后用notepad(其他软件随意,不过最好可以格式化这个xml或者ftl文件,否则你会头炸的,啥都看不清)打开这个

word.xml。然后你会发现,可能解析的时候,会把我们的"${}"这些给分开,没事,你手动再把他们拼好就行了。

切记:拼接的时候,千万要注意不要删除或修改了里面的什么结构,后果自负(呵呵,其实就是格式错误了,就算你导出成功,也不会打开的,因为你已经损害了这个word)

2.3 完成这个xml以后,把这个word.xml 修改成后缀为.ftl的模板文件,到此,这个模板就算完成了。

二、这里先说根据模板word.ftl将导出新的new.doc

1、其实这一步,网上多的是,我唯一有点不满意的就是,它获取模板的方法好像只有通过路径来获取,也许还有别的方法,欢迎知情者可以告诉我,哈哈!

2、先创建一个类(个人随意,实现功能就行。)DocmentHandler.class

publicclassDocumentHandler {

privateConfiguration configuration =null;

publicDocumentHandler(){

configuration = newConfiguration();

configuration.setDefaultEncoding("UTF-8");

}

publicbyte[] createDocArea (Map dataMap ,String outFilePath,String fileName)throwsException{

//this.configuration.setClassForTemplateLoading(DocumentHandler.class, "D:\\");//第一种模板路径

System.out.println("---进入createDocArea---");

this.configuration.setDirectoryForTemplateLoading(newFile("/template/"));//第二种模板路径

Template t = null;

File outFile = null;

byte[] bFile =null;

try{

t = this.configuration.getTemplate(fileName,"UTF-8");

} catch(Exception e) {

e.printStackTrace();

returnnull;

}

outFile = newFile(outFilePath);

Writer w = null;

FileOutputStream fos = null;

try{

fos = newFileOutputStream(outFile);

OutputStreamWriter osw = newOutputStreamWriter(fos,"UTF-8");

w = newBufferedWriter(osw);

} catch(Exception e) {

e.printStackTrace();

returnnull;

}

try{

t.process(dataMap, w);

if(outFile!=null){

FileInputStream fis = newFileInputStream(outFile);

bFile = newbyte[(int) outFile.length()];

fis.read(bFile);

fis.close();

}

System.out.println("--写入完成---");

} catch(Exception e) {

e.printStackTrace();

returnnull;

}finally{

w.close();

fos.close();

}

returnbFile;

}

}public class DocumentHandler {

private Configuration configuration = null;

public DocumentHandler(){

configuration = new Configuration();

configuration.setDefaultEncoding("UTF-8");

}

public byte[] createDocArea (Map<String, Object> dataMap ,String outFilePath,String fileName) throws Exception{

//this.configuration.setClassForTemplateLoading(DocumentHandler.class, "D:\\");//第一种模板路径

System.out.println("---进入createDocArea---");

this.configuration.setDirectoryForTemplateLoading(new File("/template/"));//第二种模板路径

Template t = null;

File outFile = null;

byte[] bFile = null;

try {

t = this.configuration.getTemplate(fileName,"UTF-8");

} catch (Exception e) {

e.printStackTrace();

return null;

}

outFile = new File(outFilePath);

Writer w = null;

FileOutputStream fos = null;

try {

fos = new FileOutputStream(outFile);

OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");

w = new BufferedWriter(osw);

} catch (Exception e) {

e.printStackTrace();

return null;

}

try {

t.process(dataMap, w);

if(outFile!=null){

FileInputStream fis = new FileInputStream(outFile);

bFile = new byte[(int) outFile.length()];

fis.read(bFile);

fis.close();

}

System.out.println("--写入完成---");

} catch (Exception e) {

e.printStackTrace();

return null;

}finally{

w.close();

fos.close();

}

return bFile;

}

}3、简单介绍一下思路:它是通过这个configuration来获取模板的,目前我就知道这两种,一个是通过File,另一个种是通过Class,不过我试了一下,不过这两种用哪一种,其实都是通过路径来获取的,然后它会根据在这个路径下,来通过你给的模板名称来找这个模板。所以这里路径下一定要有相应的模板。然后获取模板以后,你再定义一个File,把封装好的Map(这个map就是你要填充的数据)传过来,它会通过流,结合模板,把数据写入到你的新File中。至于你怎么处理这个File,我就不管了。

三、封装数据(关键)

1、其实很好理解,填充模板数据的方式就是用key-value这个格式写的(这个应该好理解吧!freemark),定义一个Map,map的key就是模板里面的${key}这个属性,一定要跟模板里面的对应起来,value就是你要写的数据;如果你不需要合并单元格,你就无脑的按照模板里${key},对应的放数据就行,最后把map给第二步的导出方法;

2、如果你的word里需要循环的,那就再map里放个list,至于模板里怎么循环,这就是涉及到freemarker的知识了,我就不解释了,自己百度去;(哎,给个例子吧!)

一定要判断你传的这个是否为空,否则要是空的话,会报错(它会用英文提示你,这个是空,你要判断空的情况,利用#if>,自己理解去吧!);

3、哈哈这儿才是重点:

1、其实这个word合并单元格挺简单的,就拿我上图的那个结果来说,1到4(算上前面的那个序列号)个格子是需要合并的,后面的三个不需要。上图是一个IP对应

后面五个单元格,所以其实它并不是一行,它是5行,(在这里)ip是在第一行,然后第2到第4行的ip是空的。先理解这个!

2、合并需要的属性值:和

这俩才是控制合并单元格的罪魁祸首;

3、怎么用?(看上图)当循环第一行的时候,有IP、地域、重要攻击、单位、时间;第二行,有空、空、空、单位、时间;第三行。。。。

4、然后在模板里的第一行(也就是循环第一次的时候),添加

w:val='restart'/>(只在需要合并单元格的地方添加,看下图)

简单的解释一下,一行的开始是以

w:rsidRPr="00914E05" w:rsidTr="00806640">这个开始的,以

结束的,这个是完整的一行,里面的是代表一个格子,算是前面的序列号,我上图也就

是6个放那个合并属性的时候千万别放错地方了,我的是前四个(算上序列号)需要合并,所以我就在前四个里放了这个;

然后再第二行(三行。。。循环)的时候,前面的ip是空的,这个时候要放这个属性,放的位置跟第一行的方法一样,只是这个熟悉变了;

这样的话就实现了合并单元格了;这样第一个IP对应的单元格就完成了,第二个IP就循环着来呗!

4、以上就是一个完整的导出过程了,当然,不管是封装数据,还是合并单元格,我说的可能更多的只是个思路,具体怎么封装数据,怎么想方设法的把数据放进模

板,仁者见者,智者见智吧!就到此为止吧,希望我说的大家可以看的明白,如果哪儿不明白的,或者哪儿写的不对的,欢迎吐槽!

java word合并单元格_java使用freemarker模板导出word(带有合并单元格)文档相关推荐

  1. freemarker模板导出word循环图片表格详细教程

    前言:表哥之前已经过一篇freemarker模板导出带表格word详细教程  freemarker模板导出带表格word详细教程_Java大表哥的博客-CSDN博客,为什么现在又要写一篇呢. 因为我这 ...

  2. freemarker html 换行,java使用freemarker模板导出word,合并单元格,单元格内换行

    之前使用[XWPFDocument][]动态写入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所 ...

  3. java使用freemarker模板导出word,合并单元格,单元格内换行

    之前使用XWPFDocument动态写入word,XWPFDocument不支持2003,word2003需要用HWPFDocument,HWPFDocument对于动态生成行效果不是很好,所以使用f ...

  4. java word导出带背景_Java 用Freemarker完美导出word文档(带图片)

    前言 最近在项目中,因客户要求,将页面内容(如合同协议)导出成word,在网上翻了好多,感觉太乱了,不过最后还是较好解决了这个问题. 准备材料 1.word原件 2.编辑器(推荐Firstobject ...

  5. 利用word的freemarker模板导出word文件

    前端请求 var url = window.webApi.business.exportYearWord; jQuery('<form action="' + url + '" ...

  6. 使用freemarker模板导出word文档

    1.先上模板图 2.效果图 步骤 链接:https://pan.baidu.com/s/1n204S3M-2z3slFITk6pCbw  提取码:z3s5 1.打开word模板,给需要赋值的位置先填上 ...

  7. freemarker模板导出带表格word详细教程

    前言:另外一篇是手机端的word导出,需要兼容性,不然在安卓手机会乱码 freemarker模板导出word循环图片表格详细教程_Java大表哥的博客-CSDN博客  并且另存为模版格式不同数据绑定方 ...

  8. java 图片 word文档_【Java】用Freemarker完美导出word文档(带图片)

    Java  用Freemarker完美导出word文档(带图片) 前言 最近在项目中,因客户要求,将页面内容(如合同协议)导出成word,在网上翻了好多,感觉太乱了,不过最后还是较好解决了这个问题. ...

  9. java freemarker word_Java 用Freemarker完美导出word文档(带图片)(示例代码)

    Java  用Freemarker完美导出word文档(带图片) 前言 最近在项目中,因客户要求,将页面内容(如合同协议)导出成word,在网上翻了好多,感觉太乱了,不过最后还是较好解决了这个问题. ...

最新文章

  1. python的这几个小功能,你都会用了吗?
  2. vmos框架_VMOS虚拟大师独立的安卓虚拟机系统【安卓】
  3. ONE- Open Navigator Engine 开放式浏览器引擎
  4. 【转】python装饰器
  5. Java多线程同步Synchronized使用分析
  6. keras保存模型_TF2 8.模型保存与加载
  7. Javascript----input事件实现动态监听textarea内容变化
  8. freeradius+mysql+pptpd+radiusmanager 游戏×××代理站完整实验过程
  9. Login控件:用户登录失败的消息提示。
  10. 【路径规划】基于matlab A_star算法机器人栅格地图路径规划【含Matlab源码 116期】
  11. AutoRunner 功能自动化测试项目实训之AutoRunner的下载安装(十九)
  12. ZeroClipBoard的诡异事件
  13. android 10.0禁用电源键(屏蔽关机短按长按事件)
  14. css hack *html,css hack 大全 各个浏览器的css
  15. 对敏捷宣言的原则进行风险评估
  16. P315 GCD等于XOR UVa12176 “不难发现”的解释 以及完整推导过程
  17. 推荐系统_(一)算法详解
  18. 基于ZigBee的智能家居系统设计
  19. 用三种方式实现轮播图
  20. PointCut语法介绍

热门文章

  1. Microsoft Toolkit(win8.1激活工具)v2.5.2 绿色版
  2. Redis存储购物车
  3. ESP8266 WIFI模块调试及在QT Windows下的通讯
  4. graphpad7.04多组比较p值_手把手教你用Graphpad做单因素方差分析
  5. Java笔试题(三)简答题
  6. 信息学奥赛 一本通:1194:移动路线
  7. 【英语】maintext2-Emotional Mastery译文
  8. 你还不会用python进行数据分析吗
  9. 计算机网络并行传输和串行传输,并行传输和串行传输的区别是什么
  10. 华为鸿蒙亮利剑,华为亮利剑,超级主镜头+鸿蒙OS,所有期许或将如愿以偿