freemarker+Aspose.word实现模板生成word并转成pdf

需求:动态生成pdf指定模板

实现途径:通过freemarker模板,导出word文档,同时可将word转为pdf。

技术选择思路

思路一:直接导出pdf

使用itext模板导出pdf
适用范围

业务生成的 pdf 是具有固定格式或者模板的文字及其图片等内容,使用模板,只需要将不一致的地方改成文本域,然后进行文字填充就可以了;如果涉及的业务不能有模块化可以提取出来东西,从开头一步一步去绘画。

参考链接

JAVA 使用Itext模板生成pdf,解决图片插入,文本域超出字体缩放,半自动换行[https://blog.csdn.net/a_lllk/article/details/109450972]
java根据模板生成pdf文件并导出https://blog.csdn.net/TOP__ONE/article/details/65442390

缺点

超出文本域的部分的文字(若不设置自动调整文字大小)则会不显示,无法自动分页。(暂未找到解决方案)

思路二:先导出word再转成pdf

1)导出word

  • FreemarkerFreemarker 将数据填入 .ftl 模板导出 word(.doc/.docx)
    (注意:需要循环展示的内容还需要在xml文件中处理)

    FreeMarker 是一个用Java语言编写的模板引擎,它基于模板输出文本。FreeMarker 与 Web 容器无关,即在Web运行时,它并不知道 Servlet 或 HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等。
    在这里插入图片描述

Java 程序准备的数据来显示(比如 SQL 查询),FreeMarker 仅仅使用模板生成文本页面来呈现已经准备好的数据。

Freemarker 的使用步骤

 1)、创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号;2)、设置模板文件所在的路径;3)、设置模板文件使用的字符集。一般就是UTF-8;4)、加载一个模板,创建一个模板对象;5)、创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map;6)、创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名;7)、调用模板对象的process方法输出文件;8)、关闭流;

参考链接:

SpringBoot整合Freemarker导出word文档表格

freemarker导出Word,文本,可循环表格,合并单元格,可循环图片,目录更新(一)

缺点:

导出的 .doc / .docx 实际上是 xml 文件,用办公软件能正常打开使用。但是转 PDF 的时候发现转不成功。转过之后的 PDF 显示的不是 word 的格式字符,而是像 xml 文件的标签及字符。

Freemarker 结合 .docx 格式的本质将数据填入 .docx 里面的 document.xml 文件导出 .docx

参考链接:

freemarker动态生成word并将生成的word转为PDF

优点:

可转换为 pdf

相关错误:

A. Date 格式的数据传输报错!
解决方案:

${(initialTime?string("yyyy-MM-dd HH:mm:ss"))!}

附:

a. 循环行及表单行是否显示功能参考链接:

SpringBoot整合Freemarker导出word文档表格

freemarker合并单元格,if、else标签的使用,null、空字符串处理

  • dock4j结合 .docx 格式的本质将数据填入 .docx 里面的 document.xml 文件导出 .docx

    docx4j 中模板的使用

  • POI

  • Aspose.word(需要license)

2)word转pdf

思路一:

将目标word文件另存为xml文件,将里面的需要动态生成的内容用freemarker的表达式${}替换.

用freemarker生成word的工具类,动态生成word. 这样生成的word实际上是xml文件,用办公软件能正常打开使用.

但是转PDF的时候发现转不成功.转过之后的PDF显示的不是word的格式字符,而是像xml文件的标签及字符,失败!

  • dock4j将.docx转pdf

    • 使用 docxToPdf() 将 .docx 文件转换为 .pdf 时,中文的可以顺利换行,但是一连串的英文就会超出表格,无法自动换行。
  • Spire.Doc 实现 word (.doc / .docx)转 pdf

    有付费版和免费版,免费版仅支持三页内的 word 转 pdf

  • aspose.word 将 word 转 pdf

使用freemarker生成动态的word文档的步骤如下:

前提:ftl文件是模板。通过word生成:先把模板word转换成.xml文件,进行修改后将后缀改成.ftl文件。
在这里插入图片描述
下面是我的word文件:在这里插入图片描述
生成后的word长这样
在这里插入图片描述
在xml文件中,如果要实现循环列表:
在这里插入图片描述
在这里插入图片描述

代码实现:

1.添加依赖

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

2.创建freemarker配置对象

Configuration configuration = new Configuration(Configuration.VERSION_2_3_20);

3.设置模板文件所在的目录

configuration.setDirectoryForTemplateLoading(new File("templates"));

4.获取模板文件

Template template = configuration.getTemplate("template.ftl");

5.创建数据模型

Map<String, Object> data = new HashMap<>();
data.put("title", "动态生成Word文档");
data.put("content", "这是一篇使用Freemarker生成的Word文档。");

6.创建输出流

File outFile = new File("output.doc");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8"));

7.将数据模型和模板文件合并,并输出到文件中

template.process(data, out);

完整代码如下:

/*** 通过模板导出word格式文件** @param dataMap      导出数据* @param templateName 模板名称* @param path         导出word的路径以及文件名称*/public static void exportWord(Map<String, Object> dataMap, String templateName, String path) {try {//Configuration 用于读取ftl文件Configuration configuration = new Configuration();configuration.setDefaultEncoding("utf-8");//指定路径(根据某个类的相对路径指定)configuration.setClassForTemplateLoading(WordPDFUtil.class, "/template");//输出文档路径及名称File outFile = new File(path);FileOutputStream os = new FileOutputStream(outFile);//以utf-8的编码读取ftl文件Template template = configuration.getTemplate(templateName, "utf-8");Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"), 10240);template.process(dataMap, out);//导出成word时,\n换行替换成 <w:br/> 标签,不起作用,无法换行,所以用Document保存wordDocument doc = new Document(path);doc.save(os, SaveFormat.DOC);out.close();os.close();} catch (Exception e) {e.printStackTrace();}}

# Freemaker设置HTML自动转义

freemarker作为"通用"模版引擎, 默认情况下不会对model中的值进行html转义, 然而在web项目中, 为了防止跨站脚本攻击等问题, 必须在对model中的值进行转义.

解决办法:

https://www.iteye.com/blog/maria3905-2098745

Apose.word实现word转pdf:

/*** word、pdf处理工具类*/
public class WordPDFUtil {protected static Logger logger = LoggerFactory.getLogger(WordPDFUtil.class);// 读取license.xml的内容public static boolean getLicense() {boolean result = false;Resource resource = new ClassPathResource("static/license.xml");try (InputStream is = resource.getInputStream()) {License aposeLic = new License();aposeLic.setLicense(is);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** word转pdf文件** @param Address    原文件地址* @param pdfAddress 保存的pdf文件地址*/public static void wordConvertPdf(String Address, String pdfAddress) throws IOException {// 验证License 若不验证则转化出的pdf文档会有水印产生if (!getLicense()) {return;}FileOutputStream os = null;try {// 新建一个空白pdf文档File file = new File(pdfAddress);os = new FileOutputStream(file);// Address是将要被转化的word文档Document doc = new Document(Address);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换doc.save(os, SaveFormat.PDF);} catch (Exception e) {e.printStackTrace();} finally {if (null != os)os.close();}}

用到的import:

import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;
import freemarker.template.Configuration;
import freemarker.template.Template;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;import java.io.*;
import java.util.Map;import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/269479.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Spark精讲】RDD特性之数据本地化

首选运行位置 上图红框为RDD的特性五&#xff1a;每个RDD的每个分区都有一组首选运行位置&#xff0c;用于标识RDD的这个分区数据最好能够在哪台主机上运行。通过RDD的首选运行位置可以让RDD的某个分区的计算任务直接在指定的主机上运行&#xff0c;从而实现了移动计算而不是移…

搜索引擎蜘蛛池的原理是什么,蜘蛛池如何搭建?

搜索引擎蜘蛛池是一种利用蜘蛛程序抓取互联网上的网页并返回相关数据的技术。它的原理主要是通过模拟搜索引擎蜘蛛的行为&#xff0c;将大量的网页链接提交给搜索引擎&#xff0c;从而增加网站在搜索引擎中的曝光率和排名。 如何联系蚂蚁seo&#xff1f; baidu搜索&#xff1…

Java - Spring中Bean的循环依赖问题

什么是Bean的循环依赖 A对象中有B属性。B对象中有A属性。这就是循环依赖。我依赖你&#xff0c;你也依赖我。 比如&#xff1a;丈夫类Husband&#xff0c;妻子类Wife。Husband中有Wife的引用。Wife中有Husband的引用。 Spring解决循环依赖的机理 Spring为什么可以解决set s…

Centos7 首次 安装Mysql8.0

随笔记录 背景介绍&#xff1a;重装Centos7 系统&#xff0c;没有安装mysql 目录 1. 查看否有MariaDB与MySQL 2. MySQL官网下载适用于centos7的mysql安装包 2.1 查询服务器是x86_64架构还是arm架构 2.2 查系统版本 2.3 下载适用于系统版本安装包 2.3.1 国内镜像源下载…

JVM面试

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.JVM 的整体结构2.类加载做了哪些事情?类加载器有哪些&#xff1f;双亲委派和沙箱安全 3.Java虚拟机栈是什么4.方法区的理解HotSpot 中方法区的演进方法区的内部结…

12月12日作业

设计一个闹钟 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include <QTime> #include <QTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass …

【Unity学习笔记】光照简介

本节主要是简单介绍一些常见的光照组件和渲染设置。 文章目录 灯光类型平行光Directional Light点光源Point Light聚光灯Spot Light面积光 Area Light 阴影设置全局光照明光照模式直接光照与间接光照Mixed Lighting 光照探针Light Probe Group光照探针组 反射探针 灯光类型 在…

GeMap:Online Vectorized HD Map Construction using Geometry

参考代码&#xff1a;GeMap 动机与出发点 出了原本针对单点的L1损失&#xff0c;车道线具备的几何结构信息作为监督信息也可以再被挖掘挖掘&#xff0c;像车道线实例中点和点之间的距离与夹角、线与线之间的夹角、不同线上点与点之间的关系都可用来作为监督约束&#xff0c;但…

手持式心电图机|12道便携式心电图机主板方案定制

心电图机被广泛应用于心脏状况的监测&#xff0c;可以从多个角度观察心脏情况&#xff0c;及时反映患者的病情&#xff0c;以便医生和患者了解。触摸屏使得控制和信息录入变得轻松。心电图报告提供多种语言选择&#xff0c;便于上传信息&#xff0c;实现无纸化报告。同时&#…

Jemeter,提取响应体中的数据:正则表达式、Json提取器

一、正则表达式 1、线程组--创建线程组&#xff1b; 2、线程组--添加--取样器--HTTP请求&#xff1b; 3、Http请求--添加--后置处理器--正则表达式提取器&#xff1b; 4、线程组--添加--监听器--查看结果树&#xff1b; 5、线程组--添加--取样器--调试取样器。 响应体数据…

各地加速“双碳”落地,数字能源供应商怎么选?

作者 | 曾响铃 文 | 响铃说 随着我国力争2030年前实现“碳达峰”、2060年前实现“碳中和”的“双碳”目标提出&#xff0c;为各地区、各行业的低碳转型和绿色可持续发展制定“倒计时”时间表&#xff0c;一场围绕“数字能源”、“智慧能源”、“新能源”等关键词的创新探索进…

matlab 最小二乘拟合空间直线(方法三)

目录 一、算法原理1、算法过程2、参考文献二、代码实现三、结果展示四、相关链接博客长期更新,GPT与爬虫自重,你也未必能爬到最新版本。 一、算法原理 1、算法过程 空间直线的点向式方程为: