freemarker动态生成word和pdf

2023-11-14

1、使用freemarker生成word

freemarker生成word的方法网上有很多,比较简单,基本上都差不多

所需工具

freemarker

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

准备模板

准备一个word文档,为了防止有的用户还在使用非常老的word版本,这里选择生成2003版的 .doc 文件(也可以根据需求使用 .docx 文件),注意先将文档中要替换的内容写成 ${} 的形式,方便使用freemarker进行内容替换(文档中加入了一张图片,是为了演示怎么在生成word文档时添加图片)
在这里插入图片描述
另存为xml文件
在这里插入图片描述
生成的xml文件内容没有格式化,不方便查看,可以先将文件内容格式化(比如使用idea),然后找个文档编辑器,nodepad++,ueditor等都可以,直接在idea里编辑也可以,搜索一下占位符 $ 的位置,有的占位符可能会出现位置错乱,比如可能出现以下情况,这种情况就需要手动处理一下
在这里插入图片描述
这里特殊说明一下图片,图片是以base64编码的形式存在的,生成xml后直接将对应的base64字符串替换成占位符即可,比如 ${photo}
在这里插入图片描述
准备好模板文件后,将模板后缀改成 .ftl 放到工程resource目录下或文件系统目录下即可

代码

FreeMarkerForDocUtil.java

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * word文档生成工具类
 *
 * @author blank
 */
public class FreeMarkerForDocUtil{
   

    private static Logger logger = LoggerFactory.getLogger(FreeMarkerForDocUtil.class);

    /**
     * 生成word文档,并保存成文件
     * @param templatePath 文档模板所在的文件夹
     * @param templateFileName 文档模板的名称
     * @param dataMap 模板中需要替换的数据
     * @param targetFilePath 目标文件路径
     * @param targetFileName 目标文件名
     * @return File
     * @throws IOException
     * @throws TemplateException
     */
    public static File generateWord(String templatePath, String templateFileName, Map<String,Object> dataMap,String targetFilePath,String targetFileName) throws IOException, TemplateException {
   
        byte[] wordBytes = createWord(templatePath, templateFileName, dataMap);
        File filePath = new File(targetFilePath);
        if(filePath.isDirectory() && !filePath.exists()){
   
            filePath.mkdirs();
        }
        File file = new File(targetFilePath+File.separator+targetFileName);
        FileOutputStream fOut = new FileOutputStream(file);
        fOut.write(wordBytes);
        fOut.close();
        return file;
    }

    /**
     * 生成word文档,并返回byte数组
     * @param templatePath 文档模板所在的文件夹
     * @param templateFileName 文档模板的名称
     * @param dataMap 模板中需要替换的数据
     * @return 二进制数组
     * @throws IOException
     * @throws TemplateException
     */
    public static byte[] generateWord(String templatePath, String templateFileName, Map<String,Object> dataMap) throws IOException, TemplateException {
   
        byte[] wordBytes = createWord(templatePath, templateFileName, dataMap);
        return wordBytes;
    }

    /**
     * 生成word文档
     * @param templatePath 文档模板所在的文件夹
     * @param templateFileName 文档模板的名称
     * @param dataMap 模板中需要替换的数据
     * @return 二进制数组
     */
    private static byte[] createWord(String templatePath, String templateFileName, Map<String,Object> dataMap) throws IOException, TemplateException {
   
        Configuration configuration = getConfiguration(templatePath);
        Template template = configuration.getTemplate(templateFileName);

        for(Map.Entry<String,Object> entry:dataMap.entrySet()){
   
            String value = entry.getValue().toString();
            // 处理转义字符
            value = transformForDoc(value);
            entry.setValue(value);
        }

        StringWriter stringWriter = new StringWriter();
        Writer out = new BufferedWriter(stringWriter);
        try {
   
            template.process(dataMap,out);
        } catch (TemplateException e) {
   
            logger.error(e.getMessage(
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

freemarker动态生成word和pdf 的相关文章

  • 幸有一事,生死可许

    已然到了岁末 2014就要结束 迎来崭新的2015 颇多感慨 颇多难忘 与其说是2014年是我职业生涯中至关重要的一年 倒不如说是我人生道路上极为重要的一步来的更为贴切 这一年忙忙碌碌 一刻不得清闲 却是极为充实 没有迷茫 没有挣扎 有的只
  • 【自监督学习】 MAE阅读笔记

    1 MAE Masked Autoencoders Are Scalable Vision Learners bert ViT MAE的主要目的是进行迁移学习的预训练 1 Abstract 随即盖住一些图片中的块 patches 并重建被盖
  • Python学习第九天——time、datetime

    1 time 以当前时间为准 让大家快速认识三种形式的时间 print time time 时间戳 1487130156 419527 print time strftime Y m d X 格式化的时间字符串 2017 02 15 11
  • springboot 全局异常处理类

    目录标题 springboot 全局异常处理类 依赖 代码 springboot 全局异常处理类 依赖
  • hadoop环境配置

    hadoop解压后需要配置多个文件 1 hadoop env sh 2 core site xml 3 hdfs site xml 4 mapred site xml 5 yarn site xml 具体配置语句网上很多直接找了复制进去并修
  • Ubuntu20.04(linux)离线安装nacos

    一 解压 1 首先local目录得有nacos server 2 0 4 tar gz包 切换目录cd usr local执行以下命令 tar zxvf nacos server 2 0 4 tar gz 二 创建nacos service
  • 记录使用ESP32做WiFi模块使用的学习

    这里使用ESP32作为WiFi模块 使用STA模式或者AP模式 目录 前言 二 配置WiFi模式 1 STA模式 2 AP模式 3 AP STA模式 三 实现ESP32与电脑端通信 ESP32的数据接收与传输 ESP32的完整代码 前言 因
  • 力扣-图解算法数据结构

    常见的数据结构可分为 线性数据结构 与 非线性数据结构 具体为 数组 链表 栈 队列 树 图 散列表 堆 数组 数组是将相同类型的元素存储于连续内存空间的数据结构 其长度不可变 如下图所示 构建此数组需要在初始化时给定长度 并对数组每个索引
  • 两个指针相减

    特别特殊的点 include
  • CreateThread函数,无法将参数 3 从“DWORD (__cdecl *)(LPVOID)”转换为“LPTHREAD_START_ROUTINE” PVZCheater

    问题 HANDLE CreateThread LPSECURITY ATTRIBUTES SIZE T LPTHREAD START ROUTINE LPVOID DWORD LPDWORD 无法将参数 3 从 DWORD cdecl LP
  • 从端到端打通模型端侧部署流程(NCNN)

    文章目录 背景介绍 为什么要做端侧推理 端侧深度学习部署流程 一条主要技术路线 ONNX NCNN框架 NCNN的官方介绍 NCNN问题解决 NCNN使用样例 快速在NCNN框架下验证自己的模型 一般流程 YOLOv5的demo测试 全新部
  • sklearn评分函数roc_auc_score和f1_score中参数average的说明

    roc auc score和f1 score中参数average的说明 本文记录在python第三方库sklearn的两个评分函数 sklearn metrics roc auc score 计算AUC 和 sklearn metrics
  • 高德地图的缩放和位移监听

    最近项目采用高德地图 高德地图的文档 demo都很详细 想实现的功能基本上都有 在项目里有一个功能 是类似根据地图的中心经纬度实现数据请求 为了不无限的请求 所以要分别监听 地图的缩放 地图位移 这里就有一个方法 gadMap setOnC
  • torch将多个tensor张量合并为一个张量,只提高迷你批次的纬度

    在自己写pytorch的数据集加载函数时 会遇到一个问题 如何将多张图片张量合并到一起 提升迷你批次batch的纬度 但是不影响图片的大小和RGB通道数 解决方法 函数torch cat inputs dim 这里的inputs是你要合并的
  • 六月学习记录

    六月学习记录 6 1 Android消息传递之Handler消息机制 four articles http www cnblogs com whoislcj p 5590615 html 6 2 代码审查工具phabricator 6 4
  • 这梦想笑开了花---Day15

    题记 散尽这满腔的爱和忧伤 任这一往无前的气势澎湃 我在这 要走下去 转正快要一个月了 来这博客也有半个月了 算是在这个行业入了门 每天的忙碌略感疲惫 但这白天公司里编写后台的代码 晚上回家自己钻研着前端的开发 倒也乐此不疲的享受着 有朋友
  • 三、MySql 数据类型

    文章标题 Mysql数据类型 Int 类型 INT N 是什么 字符类型 排序规则 时间类型 前文 mysql权限 Mysql数据类型 Int 类型 有无符号 在项目中使用 BIGINT 而且是有符号的 演示 create table te
  • 解一元二次方程——Java

    解一元二次方程 可以使用下面的公式求元二次方程ax x bx c 0的两个根 b b 4ac称作一元二次方程的判别式 如果它是正值 那么一元二次方程就有两个实数根 如果它为0 方程式就只有一个根 如果它是负值 方程式无实数根 编写程序 提示
  • 【学习笔记】经典目标检测算法

    定义 目标检测任务的目标是找到图像中的所有感兴趣区域 并确定这些区域的位置和类别 目标检测领域的深度学习方法主要分为两大类 两阶段式 Two stage 目标检测算法和单阶段式 One stage 目标检测算法 两步模型有独立地 显式地提取
  • ubuntu21.10搭建ebpf环境,BCC和bpftrace

    1 安装虚拟机 虽说centos是生产环境中的标准系统 但是从个人学习角度还是推荐ubuntu 各种软件安装包都能方便地找到 操作界面时也很漂亮 之前一直在centos7 6上折腾 自己升级内核版本 自己安装各种高版本依赖 有一段时间被折磨

随机推荐

  • TCP拥塞控制原理

    一 拥塞控制的一般原理 1 产生拥塞的原因 在某段时间 若对网络中某一资源的需求超过了该资源所能提供的可用部分 网络的性能就会变坏 即对资源的需求 可用资源 注意拥塞控制与流量控制的区别 拥塞控制是防止过多的数据注入网络中 使得网络中路由器
  • CentOS7平台命令安装Anaconda3、配置Python3开发环境

    要在 CentOS 7 上安装 Anaconda3 您可以按照以下步骤进行操作 1 下载 Anaconda3 安装包 首先 访问 Anaconda 官方网站以获取最新版本的 Anaconda3 安装包的下载链接 可以使用 wget 命令来下
  • 【数据库原理及应用教程(第4版

    文章目录 一 选择题 二 填空题 三 简答题 Reference 一 选择题 1 2 3 4 5 6 7 8 9 10 B C B D A 1 在 SQL Server 中不是对象的是 A 用户 B 数据 C 表 D 数据类型 2 声明了变
  • studio和solo哪个好_beats studio3 和solo3的区别再哪里?

    首先两款机子在外观上就有很大的区别 前者是solo3 后者是studio3 仔细观察可以发现solo3的耳罩比较小 是圆形的 studio3的是椭圆形的 两款都是头戴式 外观设计 录音师是包耳的 SOLO是压耳的 体积的话 录音师大 SOL
  • async与await

    async await 是ES7提出的基于Promise的解决异步的最终方案 一 async async是一个加在函数前的修饰符 被async定义的函数会默认返回一个Promise对象resolve的值 因此对async函数可以直接then
  • UI 自动化测试框架:PO 模式+数据驱动 【详解版】

    目录 1 PO 设计模式简介 什么是 PO 模式 PO 模式的优点 2 工程结构简介 工程结构 框架特点 3 工程代码示例 page 包 action 包 business process 包 util 包 conf 包 1 PO 设计模式
  • 基于Centos 7虚拟机的磁盘操作(添加磁盘、分区、格式分区、挂载)

    目录 一 添加硬盘 二 查看新磁盘 三 磁盘分区 3 1新建分区 3 2 格式分区 3 3 挂载分区 3 4 永久挂载新分区 3 5 取消挂载分区 一 添加硬盘 1 在虚拟机处选择编辑虚拟机设置 然后选择添加 2 选择硬盘 然后选择下一步
  • 敏捷宣言以及敏捷开发的特点

    敏捷宣言 敏捷宣言 也叫做敏捷软件开发宣言 正式宣布了对四种核心价值和十二条原则 可以指导迭代的以人为中心的软件开发方法 敏捷宣言强调的敏捷软件开发的四个核心价值是 个体和互动高于流程和工具 工作的软件高于详尽的文档 客户合作高于合同谈判
  • Go_流程、跳转控制语详解

    流程控制语句分类 流程控制语句可以控制代码的执行顺序和条件 顺序结构 普通的代码 由上而下依次执行 分支结构 if switch 循环结构 for if语句 条件表达式值必须是bool类型 不可省略括号 且左大括号不能另起一行 格式1 if
  • AI绘图Midjourney手把手教程

    以下是使用Midjourney AI绘画程序的注册和入门指南 Midjourney是一款功能强大的绘图软件 通过输入一段图片的文字描述即可生成精美的绘画 我们将为您提供详细的操作步骤 让您轻松上手 下面是使用Midjourney AI绘画程
  • Android绘制笔记——Color、Shader

    Android 颜色Color 1 颜色 1 十六进制ARGB颜色值表示 Int color 0xFFFF0000 红色 2 Color类常量 本质为十六进制表示 Int color Color RED 红色 ColorInt public
  • ffmpeg-android dlopen failed: library “libclang_rt.ubsan_standalone-aarch64-android.so“ not found

    NDK编译的ffmpeg 库 在android上使用 提示动态库错误 15 08 54 276 18357 18357 E AndroidRuntime java lang UnsatisfiedLinkError dlopen faile
  • 报时机器人的rasa shell执行流程分析

    本文以报时机器人为载体 介绍了报时机器人的对话能力范围 配置文件功能和训练和运行命令 重点介绍了rasa shell命令启动后的程序执行过程 一 报时机器人项目结构 1 对话能力范围 1 能够识别欢迎语意图 greet 和拜拜意图 good
  • Linux 或者 Docker 容器通过 date 设置系统时间

    目录 1 Linux 2 Docker 容器 2 1 进入容器内部修改 2 2 可能会遇到的问题 1 Linux 要在Linux系统中设置日期和时间 可以使用date命令 使用以下命令格式来设置日期和时间 sudo date s YYYY
  • kubernetes二进制单节点和多节点部署(多节点+dashbord)

    kubernetes二进制单节点和多节点部署 多节点 dashbord kubernetes单节点部署 环境准备 在 master01 节点上操作 上传 master zip 和 k8s cert sh 到 opt k8s 目录中 解压 m
  • YOLOv5 Focus C3 各模块详解及代码实现

    目录 yolov5s yaml yolov5s yaml基本参数含义 一些基本参数 BackBone Head Focus 一 Focus模块的作用 Focus的参数量 Yolov3和Yolov5的改进对比 关于Focus的补充 网络结构图
  • 轻量级人像分割深度学习模型PP-HumanSeg树莓派部署

    人像分割是图像分割领域的高频应用 PaddleSeg推出在大规模人像数据上训练的人像分割系列模型PP HumanSeg 包括超轻量级模型PP HumanSeg Lite 满足在服务端 移动端 Web端多种使用场景的需求 本项目将PP Hum
  • Ceph分布式存储详解

    一 Ceph概述 1 存储发展史 企业中使用存储按照其功能 使用场景 一直在持续发展和迭代 大体上可以分为四个阶段 DAS Direct Attached Storage 即直连存储 第一代存储系统 通过SCSI总线扩展至一个外部的存储 磁
  • ChatGPT泄露用户聊天记录标题;Adobe加入AIGC战局;阿里大模型前带头人杨红霞加盟字节跳动丨每日大事件...

    数据智能产业创新服务媒体 聚焦数智 改变商业 企业动态 诸葛智能推出 诸葛CDP 2 0 等三大产品升级 3月22日 容联云旗下场景化数据智能服务商 诸葛智能 举办2023春季发布会 推出客户数据管理平台 诸葛CDP 2 0 一站式用户行为
  • freemarker动态生成word和pdf

    1 使用freemarker生成word freemarker生成word的方法网上有很多 比较简单 基本上都差不多 所需工具 freemarker