freemarker导出pdf

2023-11-07

freemarker模板导出doc的之前有写过,这里就不再多说了,不清楚的可以看之前的文章Freemarker 模板导出(带图片)

转换后的文件展示

在这里插入图片描述

FreemarkerUtils工具类(这里用的工具类导出和之前不一样,不仅仅是页面进行下载,还有本地的保存)

package com.sinosoft.common.utils.freemarker;

import freemarker.template.Configuration;
import freemarker.template.Template;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author 庭前云落
 * @description
 * @date 2022年07月25日 10:45
 */
public class FreemarkerUtils {

    /**
     * 使用 freemarker 生成word文档
     *
     * @param templateDir  模板所在目录路径
     * @param templateName 模板 例如:xxx.ftl
     * @param data         数据
     * @param fileSavePath 文档生成后,存放的路径
     * @param fileName     生成后的文件名称
     * @param response
     * @throws Exception
     */
    public static void freemarkerExport(String templateDir, String templateName, Map<String, Object> data, String fileSavePath, String fileName, HttpServletResponse response) throws Exception {
        // 1.设置 freeMarker的版本和编码格式
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_22);
        configuration.setDefaultEncoding("UTF-8");
        // 2.设置 freeMarker生成Word文档,所需要的模板的路径
        configuration.setDirectoryForTemplateLoading(new File(templateDir));
        // 3.设置 freeMarker生成Word文档所需要的模板 ---> xxx.ftl
        Template t = null;
        try {
            // 模板文件名称
            t = configuration.getTemplate(templateName);
        } catch (IOException e) {
            throw new IOException("获取 ftl模板失败!" + e.getMessage());
        }
        File fileDir = new File(fileSavePath);
        if(!fileDir.exists()){
            fileDir.mkdirs();
        }
        // 4.生成 Word文档的全路径名称
        File outFile = new File(fileSavePath + fileName);
        System.out.println(outFile);
        // 5.创建一个 Word文档的输出流
        Writer writer = null;
        try {
            writer = new OutputStreamWriter(new FileOutputStream(outFile), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
        try {
            for (Map.Entry<String, Object> entry : data.entrySet()) {
                if (Objects.isNull(entry.getValue())) {
                    data.put(entry.getKey(), "");
                    System.out.println("您输入的" + entry.getKey() + "为空!");
                }else{
                    // String value=entry.getValue().toString().replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\n","<w:br/>");
                    if (!Objects.isNull(entry.getValue()) && entry.getValue().getClass().isInstance(String.class)) {
                        String value=entry.getValue().toString().replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\n","<w:br/>");
                        data.put(entry.getKey(),value );
                    }
                    if (!Objects.isNull(entry.getValue()) && entry.getValue().getClass().isInstance(List.class)) {
                        data.put(entry.getKey(), new ArrayList<>().add(entry.getValue()));
                    }
                    else {
                        String value = entry.getValue().toString().replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\n", "<w:br/>");
                        data.put(entry.getKey(), value);
                    }
                }
            }
            // 6.装载数据
            t.process(data, writer);
            response.setCharacterEncoding("utf-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("application/json");

            // 7.读取生成好的 Word文档
            File file = new File(fileSavePath + fileName);
            FileInputStream is = new FileInputStream(file);
            OutputStream os = response.getOutputStream();
            byte[] b = new byte[1024];
            int length;
            while ((length = is.read(b)) > 0) {
                os.write(b, 0, length);
            }
            os.flush();
            os.close();
            writer.flush();
            writer.close();
        } catch (IOException e) {
            throw new IOException(e.getMessage());
        } finally {
            deleteTempFile(fileSavePath + fileName);
        }
    }

    /**
     * 删除临时生成的文件
     */
    public static void deleteTempFile(String filePath) {
        File f = new File(filePath);
        boolean delete = f.delete();
    }
}

数据的查询及填充,不同模板的选择判断这里就不进行展示了。

   /**
     * 文书转pdf保存
     *
     * @return
     */
    @ApiOperation(value = "文书转pdf保存")
    @RequestMapping(value = "/savePetitionTemplatePdf", method = RequestMethod.GET)
    @LogAnnotation("文书转pdf保存")
    public Result savePetitionTemplatePdf(String oid, HttpServletResponse response) {
        try {
            Map<String, String> nameMap = documentApproverInfoService.getName(oid);
            String templateName = nameMap.get("templateName");
            String exportFileName = nameMap.get("fileName");
            String pdfName = nameMap.get("pdfName");
            //给文书赋值
            Map<String, Object> map = documentInfoService.obtainTemplate(oid, templateName);
            //模板所在路径
            String templateFileName = this.getClass().getResource("/").getPath() + "templates" + File.separator;
            //生成word文档
            FreemarkerUtils.freemarkerExport(templateFileName, templateName, map, folder, exportFileName, response);

            // doc转换为pdf
            Document document = new Document();
            document.loadFromFile(folder+exportFileName);
            document.saveToFile(folder+pdfName, FileFormat.PDF);

            return Result.ok().message("保存成功").data(folder+pdfName);
        } catch (Exception e) {
            log.error("保存异常", e);
            return Result.error().message("保存失败");
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

freemarker导出pdf 的相关文章

  • JFrame 图标在 Ubuntu 12.04 中不显示

    我使用一些图像图标开发了一个 Swing 应用程序 应用程序 jar 文件在 Windows 中按预期工作 但相同的 jar 文件在 Ubuntu 12 04 操作系统上不显示框架的图像图标 我的示例代码 ImageIcon ImageIc
  • 使用 REST API 实现属性/字段级安全

    我正在为支持多租户授权模型的 REST API 构建概念验证 该模型不仅控制用户可以访问哪些对象 还控制对象中的字段 此模型的目标是确保租户管理员只能修改其租户并且只能查看允许的对象属性 我有一个正在开发的现有代码库 可在以下位置公开获取
  • Zuul不转发请求到其他微服务

    我正在使用 Spring Boot 微服务 我已经配置了 eureka zuul 代理和另一个微服务 帐户 如果我直接从帐户拨打电话 则工作正常 帐户和 zuul 服务器都显示在 eureka 上 当我尝试使用 zuul 代理进行访问时 它
  • Java 扫描仪问题 (JFrame)

    我正在尝试使用扫描仪来编辑塔防游戏的级别 但是 它不会将级别 图块图像 更新为自定义文件的级别 0 是草 1 是石头 1 是什么都没有 等等 我发现了错误 但如何修复它 我需要添加 更改什么才能消除这个错误 java lang NullPo
  • 在 Java 中,三个 true 输入的 XOR 返回 true。为什么?

    下面的代码 System out println 1 0 0 true false false System out println 1 0 1 true false true System out println 1 1 0 true t
  • 如何通过双击图标来执行JAVA程序?

    我写了一个java程序 现在我想在没有 IDE Eclipse 等的情况下打开我的控制台 java 应用程序 只需双击桌面上的可执行版本即可 我已将 java 项目导出为 Runnable JAR 文件 但无法打开 当我尝试使用cmd打开应
  • Java Swing 自定义形状(2D 图形)

    我需要绘制自定义形状 现在 当用户单击面板上的几个点时 我使用多边形创建一个形状 public void mouseClicked MouseEvent e polygon addPoint e getX e getY repaint 但我
  • CreationException:无法在 Play 2.5.18 中创建注入器错误,以使用 com.google.inject.AbstractModule 替换 GlobalSettings Java 代码

    我正在将 Play 应用程序从 2 5 12 升级到 2 5 18 当我启动该应用程序时 使用sbt 我收到此错误 CreationException 无法创建注入器 看到以下错误 1 Error injecting constructor
  • Java setLocation() 事故

    我正处于创建一个程序来操作员工 客户系统的开始阶段 现在我刚刚创建了登录 GUI 但我遇到了一些问题 setLocation 方法 我将其设置为 250 250 但这使我的 GUI 高度变得非常疯狂 如果有人能够解决这个问题 我的代码如下
  • 如何用Java捕获音频数据

    我想访问我的麦克风用 Java 录制的音频数据 我该怎么做呢 我的目标是保存录制的音频数据并同时向用户播放 如果您不需要 JMF 中的任何附加功能 我会避免使用它 因为开发已经停止 最后一个版本是 2004 年 它与 Java 6 存在兼容
  • 从两个数组中查找公共文件

    我正在尝试从两个数组中查找通用名称文件 我已将两个不同文件夹的文件名保存在两个不同的数组中 现在我正在创建一个通用文件数组 其中包含具有通用名称的文件 filenames 1 包含文件夹 1 中文件名称的数组 filename2 包含文件夹
  • Java检测音频文件(mp3)

    我有这段代码可以读取 mp3 文件 import java io File import java io IOException import javax sound sampled AudioSystem import javax sou
  • Jlist 自定义渲染器

    我正在尝试添加一个我猜你会称其为列表中每个项目的子列表 我构建了一个自定义渲染器 它提供以下输出 正如你所看到的 有些东西不对劲 我没能找到问题的答案 我猜我需要更改面板布局中的某些内容才能获得正确的结果 但不知道是什么 https i s
  • 无法使用 Jsoup HTML 解析器 Java 实现某些功能

    我无法使用 Jsoup Java 库解析以下场景的一些文本 1 This is b My Text b some other b b text as well b b b non empty tag1 b other text 预期输出 s
  • 解析XML文件以获取所有命名空间信息

    我希望能够从给定的 XML 文件中获取所有名称空间信息 例如 如果输入 XML 文件类似于
  • 在硬件级别模拟按键 - Windows

    我正在寻找一种语言或库 使我能够在最大可能的水平上模拟击键 而无需实际按下按键 我对击键级别的具体衡量标准是 当我的计算机已经运行按键侦听器 例如鼠标键和粘滞键 时 它是否会产生与物理按键相同的输出 我尝试过很多击键模拟的方法 java A
  • 使用 Swift 在 iOS 和 Android 之间共享核心代码

    我想要的是 使用 Swift 在 Android 和 iOS 之间共享非 UI 代码 问题 Android 具有 NDK 支持 允许您使用 Java 本机接口 JNI 运行 C 和 C 代码 不是 Objective C 我是一名Java程
  • Jersey:返回字符串列表

    我尝试以 JSON 和 XML 形式返回 Jersey 中的字符串列表 我以为这会是微不足道的 我的第一次尝试是写这样的东西 GET Produces MediaType APPLICATION JSON MediaType APPLICA
  • java银行程序帐户ID不上去?

    每次创建银行帐户时 帐户 ID 都应增加 1 但每次我尝试提取 Id 时 我只会得到帐户 ID 为 0 任何建议 因为我完全按照我学习的书中的方式进行操作而且它仍然没有更新 帐户构造函数 public class BankAccount p
  • 寻找基于循环固定大小数组的双端队列

    我正在寻找一个Deque其具有以下特点 它有固定的大小 如果我在头 尾添加元素 则另一端的元素会丢失 它是基于数组的 所以我可以在恒定时间内访问随机元素 我可以在前面或末尾添加元素 双端队列 我检查了Deque的实施JCF但我没有找到任何合

随机推荐

  • 100天精通Python(基础篇)——第30天:数据容器-list列表索引

    从前往后索引 name list 0 name list 123 666 print name list 0 print name list 1 print type name list 从后向前索引 name list 1 name li
  • 【数据结构与算法】1.树、二叉树、字典树、红黑树

    文章目录 简介 1 树 Tree 2 二叉树 Binary Tree 2 1 二叉树数据结构 2 2 二叉树的三种遍历方式 3 二叉查找树 Binary Search Tree 3 1 二叉查找树的概念和定义 3 2 二分查找算法 4 字典
  • 手动安装Python第三库vtk库

    我们在使用py进行可视化操作时大概率会用到vtk库 一般方法是通过pip 安装 但是这玩意得看人品 本人人品十分不好 哈哈哈哈 所以我们就要自己下载轮子手动安装 附上第三方库地址 https www lfd uci edu gohlke p
  • 真实!大概五分之一的年轻人存款在一万元以内。

    近日 有调查称 大概五分之一的年轻人存款在一万元以内 10万元存款是一个 坎 存款超过10万就会超过53 7 的人 年轻人 存款 两个词碰撞在一起 引来了广泛的关注和讨论 你认为年轻人存款难吗 可以从以下几个角度发表你的看法 角度一 你的目
  • 计算机应用问题,计算机应用的现状与发展的问题

    计算机应用的现状与发展的问题 来源 职称阁时间 2018 07 27 11 59热度 这篇论文主要介绍的是计算机应用的现状与发展的问题的相关内容 本文作者就是通过对计算机的应用现状等内容做出详细的阐述与介绍 特推荐这篇优秀的论文供相关人士参
  • 【C++设计模式】依赖倒转原则

    2023年8月30日 周三上午 目录 概述 含义 举个简单的例子 传统做法 使用依赖倒转原则 代码说明 再举一个具体的例子 以生活为例 概述 依赖倒转原则 Dependency Inversion Principle DIP 是面向对象设计
  • Hadoop 端口

    1 系统 8080 80 用于tomcat和apache的端口 22 ssh的端口 2 Web UI 用于访问和监控Hadoop系统运行状态 Daemon 缺省端口 配置参数 HDFS Namenode 50070 dfs http add
  • Shiro源码分析-----认证流程/授权流程----------Subject

    本文转载自 认证流程和授权流程 源码分析的第二篇以Subject的初始化为题 一 回顾Apache Shiro创建Subject的步骤如下 1 获取SecurityManager工厂 此处使用Ini配置文件初始化SecurityManage
  • csgo删除服务器地图在哪个文件夹,CSGO de_cache地图

    资源说明 CSGO de cache地图 由 Volcano 制作 需要的玩家不要错过哦 资源详情 Sal Volcano Garozzo发布了其最新制作的CS GO地图de cache Volcano制作的首个地图de nuke ve 相
  • Java请求合并与分而治之

    在系统设计的时候 你是否也遇到过这两个问题 1 大量请求造成数据库压力过大 2 大量数据库查询造成请求执行时间过长 本文将介绍在高并发 大数据环境下 以上两种问题的应对思路 一 请求合并 首先思考一个场景 在高并发的系统中 在每秒内有大量的
  • 全连接神经网络单层模型原理

    全连接神经网络单层模型原理 前言 单层MLP 1 前向传播 2 激活函数 2 1 Sigmoid函数 2 2 tanh函数 2 3 ReLu函数 2 4 Leaky ReLu函数 3 损失函数 4 梯度下降 前言 深度学习是学习样本数据的内
  • ​少儿机器人编程与三大主课关系

    说到机器人编程 在常规概念里 很难将其和三大主课联系到一起 回首过去 国家并不提倡未成年人去学专业技术含量较高的机器人编程教育的 格物斯坦提示 但随着现在老龄化的社会现象的出现 国家需要大批有志少年用高科技方式去改造社会 这就要精通机器人编
  • SpringBoot启动控制台的banner是怎么回事

    前言 每次启动SpringBoot项目时 总是能看到控制台打印了一串字符 隐约能辨认出是 Spring 不知大家是否也好奇过是怎么实现的 是直接打印固定的字符串 还是根据什么算法去生成的 于是闲暇无事 探究一番 只想修改banner可以跳到
  • 时间序列分解VMD和长短记忆神经网络lstm

    这篇记一下时间序列分解和长短记忆神经网络lstm如何一起用 vmd lstm 用python实现 首先预设的流程是 读取数据 vmd时间分解 把信号分解成5行 最大最小归一化 给模型设置参数 编译 fit函数 训练 反归一化 得到的五个信号
  • 内存的分区

    内存 物理内存 虚拟内存 物理内存 计算机真正的内存 虚拟内存 为了减缓物理内存的使用 将硬盘的一部份容量虚拟成虚拟成内存 程序员视野中看到的是虚拟地址 在32的操作系统内 每个进程的寻址范围是2 32 地址一般我们使用16进制表示 0x0
  • HTTP协议是什么?有什么作用?

    HTTP协议 Hyper Text Transfer Protocol HTTP 全称为 超文本传输协议 是客户端浏览器或者是其他的程序和Web服务器之间的应用层通信协议 它通常运行在TCP之上 它指定了客户端可能发送给服务器什么样的消息以
  • python学习(一) windows开发环境搭建+linux运行环境

    朋友向我推荐了python 说怎么怎么好 计划用10 12次学习完成python的初步掌握和了解 学习一门语音 最快的方法就是自己搭建环境 并且写hello world 所以第一节就从开发环境搭建和运行环境搭建开始 一 目标 开发环境和运行
  • Android系统签名介绍

    一 签名原理介绍 apk的签名 简单说开发者可以通过签名 对应用进行标识和更新 包名在一个设备上是唯一的 这样可以避免被相同包名应用随意覆盖安装 这是一个非常重要的安全功能 系统中的签名文件 也是对系统中应用进行签名 编译应用是可以指定签名
  • Echarts中tooltip添加单位

    案例 代码 tooltip trigger axis axisPointer type cross crossStyle color 999 formatter function params var relVal params 0 nam
  • freemarker导出pdf

    freemarker模板导出doc的之前有写过 这里就不再多说了 不清楚的可以看之前的文章Freemarker 模板导出 带图片 转换后的文件展示 FreemarkerUtils工具类 这里用的工具类导出和之前不一样 不仅仅是页面进行下载