根据模板动态生成word(一)使用freemarker生成word

编程入门 行业动态 更新时间:2024-10-23 21:33:42

根据<a href=https://www.elefans.com/category/jswz/34/1770549.html style=模板动态生成word(一)使用freemarker生成word"/>

根据模板动态生成word(一)使用freemarker生成word

文章目录

  • 一、准备模板
  • 1、创建模板文件
    • 2、处理模板
      • 2.1 处理普通文本
      • 2.2 处理表格
      • 2.3 处理图片
    • 二、项目代码
    • 1、引入依赖
    • 2、生成代码
  • 三、验证生成word

一、准备模板

1、创建模板文件

首先先建立一个word文件,输入模板内容freemaker的内容,下面是本次演示的word文件。

然后将word文件另存为 .xml 文件,然后再把文件后缀改成.ftl 。将项目的resource目录下建立一个templates目录(非必须步骤)将 模板文件放到templates目录下


打开模板文件按 Ctrl + Shift + L 将模板内容格式化。

2、处理模板

2.1 处理普通文本

处理文本比较简单,将需要替换文本中直接用占位符 ${} 替换即可。

这里发现一个问题因为之前在word格式时我就已经替换了变量,但是在ftl变量却被 拆分成多段了(见图1)。但是这样是freemaker是无法成功替换变量的,所以需要手动处理成到一个段里(如图2),关于这点实在太无语了,因为没有找到比较好的处理办法,只能手工处理,在实际的开发工作中曾经花了几个小时来做这件事情。
图1:

图2

2.2 处理表格

如果模板里需要用变量填充表格,建议模板里的表格像word文件一样建一个两行的表格。在模板中<<w:tbl>> 表示一个表格 、<w: tr> 表示一行、<w: tc> 表示一列。因为FreeMarker 是利用列表一行一行循环填充的,所以我们可以根据关键字找到<<w:tbl>>标签,因为第一个 <w: tr>是表头注意不要改到了,找到第二个<w: tr>在前后分别加上如下语句即可,后面的表格里后面的行<w: tr>需要删掉,建议模板里的表格像word文件一样建一个两行的表格即可这样就不用删了:

<#list itemList as item>
</#list>

替换后的模板如下:

2.3 处理图片

如果模板里需要用变量填充图片,建议先在word文件里插入一张图片,这样在模板文件里找到<pkg:binaryData>标签直接里面把里面的图片base64字符替换成变量即可,word里可以通过植入base64字符来展示图片:

替换前:

替换后:

<pkg:binaryData>${image1}</pkg:binaryData>

到此模板已经调整完成,接下来就可以开始写代码了。

二、项目代码

1、引入依赖

在项目的pom文件里引入如下依赖

	<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.31</version></dependency>

2、生成代码

将图片转成Base64字符串的公共方法:

public static String getImageBase64Str(String imgFile) {try( InputStream in = new FileInputStream(imgFile)) {byte[] data = new byte[in.available()];in.read(data);BASE64Encoder encoder = new BASE64Encoder();return encoder.encode(data);} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}}

根据模板文件生成word,主要生成的word的文件后缀必须是doc不能是docx,不然生成的文件无法打开。

public static void crateWord(Map<String, Object> dataMap, String templatePath, String targetFile){String path = templatePath.substring(0,templatePath.lastIndexOf("/"));String templateName = templatePath.substring(templatePath.lastIndexOf("/") + 1);try (FileOutputStream out = new FileOutputStream(targetFile);Writer writer = new BufferedWriter(new OutputStreamWriter(out, "utf-8"))){Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);configuration.setDefaultEncoding("utf-8");configuration.setClassForTemplateLoading(FreeMakerTest.class, path);//除了ClassForTemplateLoading外,另一种模板加载方式DirectoryForTemplateLoading,也可用//ClassPathResource resource = new ClassPathResource(path);//configuration.setDirectoryForTemplateLoading(resource.getFile());//加载模板Template template = configuration.getTemplate(templateName);//渲染模板template.process(dataMap, writer);} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (UnsupportedEncodingException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);} catch (TemplateException e) {throw new RuntimeException(e);}}

三、验证生成word

新建的列表数据实体类:

public class Arrears{private String name;private Integer num;private String endDay;public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getNum() {return num;}public void setNum(Integer num) {this.num = num;}public String getEndDay() {return endDay;}public void setEndDay(String endDay) {this.endDay = endDay;}
}

准备模板填充数据

private static Map<String, Object> prepareParam(){LocalDate currentDate = LocalDate.now();LocalDate endDate = currentDate.plusYears(1L);List<Arrears> arrearsList = new ArrayList<>();arrearsList.add(new Arrears(){{setName("一顿老魏");setNum(1);setEndDay("三月内");}});arrearsList.add(new Arrears(){{setName("贵州大黄牛");setNum(1);setEndDay("一年内");}});arrearsList.add(new Arrears(){{setName("v我50");setNum(1);setEndDay("一月内");}});//填充所需要的数据Map<String, Object> dataMap = new HashMap<>();dataMap.put("debtor", "陈有楚");dataMap.put("nowYear", String.valueOf(currentDate.getYear()));dataMap.put("nowMonth", String.valueOf(currentDate.getMonthValue()));dataMap.put("nowDay", String.valueOf(currentDate.getDayOfMonth()));dataMap.put("arrears", "一顿老魏、贵州大黄牛、v我50");dataMap.put("endYear", String.valueOf(endDate.getYear()));dataMap.put("endMonth", String.valueOf(endDate.getMonthValue()));dataMap.put("endDay", String.valueOf(endDate.getDayOfMonth()));dataMap.put("arrearsList", arrearsList);dataMap.put("image1", getImageBase64Str("D:\\picture\\其他\\24-05-23-142418.png"));dataMap.put("creditor", "知北游");return dataMap;}

测试代码:

public static void main(String[] args) throws IOException {//准备参数Map<String, Object> dataMap = prepareParam();crateWord(dataMap,"/templates/qiantiao.ftl","D:\\test\\qiantiao.doc");}

测试结果:

更多推荐

根据模板动态生成word(一)使用freemarker生成word

本文发布于:2024-03-05 00:51:33,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1710869.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模板   动态   freemarker   word

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!