java word导出表格_Java Word模板导出包含表格单元格合并

java通过freemarker导出word循环合并表格单元格

本文主要讲解通过freemarker模板引擎来导出word,并且在word中包含表格的合并部分需要循环生成。

一、Java需要通过模板导出的word

b2a54ed78f2f4f5084ca40178c73a306.png

如上图所示。物品的信息是循环部分。但是前面的表格是合并固定的。接下来我们将通过freemarker模板的方式来导出上述格式

二、创建freemarker模板

2.1首先将word的源文件另存为xml格式文件,如下

603.html

用文本工具打开xml文件。notepad++ 或者sublimetext都可以

603.html

打开后如上图,看起来很乱。这时候需要进行xml格式化。欢迎使用本站xml格式化工具

格式化以后如下:

603.html

格式化以后就好看多了。

首先我们需要去找到我们需要循环的表格

603.html

物品信息就是我们要循环的开始部分。

在这之前需要科普下word的xml是如何实现单元格合并的

主要就是

两个标签的组合。

首先了解下word的表格标签

物品信息

物品名称

物品数量

2

上面是合并单元格的首行,所以你可以找到标签

标签说明:

 ---行标签

 ---单元格标签

我们继续看下面的一行xml

第二行表格xml:

物品说明

刀非常

锋利

继续第三行:

上架时间

2

019

-

08

-

09

上架人

小左

从第二行,第三行可以找到标签,标识这这列产生了合并

并且就在第一个单元格内。

那么模板就好改了。思路:

首先循环判断是否第一条数据

第一条数据那么就使用行1的格式。后面的都使用合并后的格式

提取需要做模板的几行进行组建,通过上面我们可以知道,其实我们就是要循环以下三行表格:

物品信息

物品名称

物品数量

2

物品说明

刀非常

锋利

上架时间

2

019

-

08

-

09

上架人

小左

接下来就针对这部分进行模板标签的编写

说明:Java代码后面给出,现在说明的是集合的key为 goodsList(物品集合)

循环片段代码格式缩进后如图

图6

上图其实就是判断了是否第一条记录,第一条记录和后面记录的区别就是第一行的第一个单元格,第一条记录的第一个单元格是写的”物品信息“后面的记录第一个单元格都是合并单元格的cell代码。

以下为循环片段代码:

物品信息

物品名称

${goods.name}

物品数量

${goods.number}

物品说明

${goods.description}

上架时间

${goods.time}

上架人

${goods.user}

物品名称

${goods.name}

物品数量

${goods.number}

物品说明

${goods.description}

上架时间

${goods.time}

上架人

${goods.user}

#if>

#list>

将上面代码放入demo.xml文件中替换掉原来的两个假数据行。替换后如下:(由于数据多,这里就截图展示)

603.html

将上诉的demo.xml保存并改为demo.ftl即完成freemarker的模板。

提示:这里说下为啥要if else ,因为第一次生成的行需要展示合并的单元格,后面的整个数据都是一个合并标签。当然简单化也可以在第一行的第一个单元格做if else不需要像我这样整个循环体做if else

三、编写freemarker模板导出复杂格式word代码

首先把上面制作的demo.ftl放入Java项目的classpath目录下

Java数据模型Goods

$title(Goods.java)

package demo;

public class Goods {

public Goods(String name, Integer number, String description, String time, String user) {

this.name = name;

this.number = number;

this.description = description;

this.time = time;

this.user = user;

}

String name;

Integer number;

String description;

String time;

String user;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Integer getNumber() {

return number;

}

public void setNumber(Integer number) {

this.number = number;

}

public String getDescription() {

return description;

}

public void setDescription(String description) {

this.description = description;

}

public String getTime() {

return time;

}

public void setTime(String time) {

this.time = time;

}

public String getUser() {

return user;

}

public void setUser(String user) {

this.user = user;

}

}

导出代码:

$title(ComplexWordExport.java)

package demo;

import freemarker.template.Configuration;

import freemarker.template.Template;

import java.io.*;

import java.text.SimpleDateFormat;

import java.util.*;

public class ComplexWordExport {

public static void main(String[] args) {

try {

// 创建模拟数据

List goodsList = new ArrayList<>();

for (int i = 0; i < 4; i++) {

goodsList.add(new Goods("刀" + i, i + 2, "到很好不错,数量多+" + i,

new SimpleDateFormat("HH:mm:ss:SSS").format(new Date()), "用户" + i));

}

Map dataMap=new HashMap<>();

dataMap.put("goodsList",goodsList);//注意这里的key与目标中的数据对应

File wordFile = new File("d:/demo.doc");// 注意这里只能输出doc,不能直接输出docx

Configuration configuration = new Configuration();

configuration.setDefaultEncoding("UTF-8");

configuration.setClassForTemplateLoading(WordTest.class, "/");

// 模板来源

// 1.创建一个word文件可以是doc或者docx的

// 2.在需要使用变量的地方用占位符占位

// 3.将word文档另存为xml文件

// 4.打开xml文件将里面的占位符替换为freemarker的表达式

// 5.重命名xml为ftl

// 6.完成

Template template = configuration.getTemplate("demo/demo.ftl", "UTF-8");//路径相对于项目的classpath

try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(wordFile),"UTF-8"))) {

template.process(dataMap, out);

out.flush();

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

四、导出结果

603.html

注意:导出文件必须是.doc因为docx会验证xml里面的一些数据导致文件打不开。

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页

打赏作者

余知兮

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值