当前位置: 首页 > news >正文

动态导出word文件支持转pdf

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、功能说明
  • 二、使用步骤
    • 1.controller
    • 2.工具类 DocumentUtil
  • 导出样式


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、功能说明

将要导出的文件已动态方式进行下载

在这里插入图片描述

二、使用步骤

1.controller

代码如下(示例):

 @ApiOperation("导出维权word模板")@GetMapping("/export/{id}")public ResponseEntity<byte[]> exportWord(@PathVariable("id") Long id) throws IOException {// 获取 SupervisionDocument 对象SupervisionDocument supervisionDocument = service.getById(id);// 创建并填充数据模型HashMap<String, Object> dataMap = new HashMap<>();//将base64的内容进行解码String s = new String(Base64.getDecoder().decode(supervisionDocument.getSupervisionOrderText()));dataMap.put("content", s);//编号判断如果获取为空则默认空格dataMap.put("number", supervisionDocument.getSupervisionOrderNumber());//整改时限dataMap.put("time", new SimpleDateFormat("yyyy年MM月dd日").format(supervisionDocument.getRectificationDeadline()));//录入时间dataMap.put("entryTime", new SimpleDateFormat("yyyy年MM月dd日").format(supervisionDocument.getCreatedAt()));//录入单位dataMap.put("entryUnit", supervisionDocument.getEntryUnit());//被堵办单位dataMap.put("supervisedUnit", supervisionDocument.getSupervisedUnit());//获取附件dataMap.put("attachment", splitUrl(supervisionDocument.getAttachments()));if (supervisionDocument.getDocumentType().equals("1")) {// 生成文档的字节流ByteArrayOutputStream outputStream = DocumentUtil.generateDocAsStream("word/提示函.docx",dataMap);// 设置文件下载的文件名String fileName = "提示函_" + id + ".docx";// 设置响应头确保文件下载HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);headers.setContentDispositionFormData("attachment", new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));// 返回文件流内容作为响应体return new ResponseEntity<>(outputStream.toByteArray(), headers, HttpStatus.OK);}

2.工具类 DocumentUtil

代码如下(示例):

 package com.ruoyi.common.core.utils;import com.deepoove.poi.XWPFTemplate;
import com.openhtmltopdf.pdfboxout.PdfRendererBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;/*** 文档处理工具类。* <p>* 提供生成Word和PDF文档的方法。* </p>* @author Administrator*/
public class DocumentUtil {private static final Logger logger = LoggerFactory.getLogger(DocumentUtil.class);/*** 生成Word文档** @param templatePath 模板文件路径* @param outputPath   输出文件路径* @param data         数据模型* @throws IOException 如果文档生成失败*/public static void generateDoc(String templatePath, String outputPath, Map<String, Object> data) throws IOException {logger.info("开始生成Word文档,模板路径:{},输出路径:{}", templatePath, outputPath);if (Files.exists(Paths.get(outputPath))) {throw new IOException("文件已存在:" + outputPath);}XWPFTemplate template = XWPFTemplate.compile(templatePath);try {template.render(data);try (FileOutputStream out = new FileOutputStream(outputPath)) {template.write(out);}} catch (Exception e) {logger.error("生成Word文档时发生错误", e);throw new IOException("生成Word文档时发生错误:" + e.getMessage(), e);} finally {template.close();}logger.info("Word文档生成成功,输出路径:{}", outputPath);}/*** 生成Word文档并返回文件流** @param templatePath 模板文件路径* @param data         数据模型* @return 文件流* @throws IOException 如果文档生成失败*/public static ByteArrayOutputStream generateDocAsStream(String templatePath, Map<String, Object> data) throws IOException {// 从 classpath 中读取模板文件流try (InputStream templateStream = DocumentUtil.class.getClassLoader().getResourceAsStream(templatePath)) {if (templateStream == null) {throw new IOException("模板文件未找到:" + templatePath);}// 创建 XWPFTemplate 实例并渲染数据XWPFTemplate template = XWPFTemplate.compile(templateStream);ByteArrayOutputStream outputStream = new ByteArrayOutputStream();try {template.render(data); // 将数据渲染到模板template.write(outputStream); // 将模板内容写入输出流} catch (Exception e) {logger.error("生成Word文档时发生错误", e);throw new IOException("生成Word文档时发生错误:" + e.getMessage(), e);} finally {template.close();}logger.info("Word文档生成成功");return outputStream;}}/*** 生成PDF文件** @param htmlContent HTML内容* @param outputPath  输出文件路径* @throws IOException 如果PDF生成失败*/public static void generatePdf(String htmlContent, String outputPath) throws IOException {logger.info("开始生成PDF文件,输出路径:{}", outputPath);if (Files.exists(Paths.get(outputPath))) {throw new IOException("文件已存在:" + outputPath);}try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {PdfRendererBuilder builder = new PdfRendererBuilder();builder.useFastMode();builder.withHtmlContent(htmlContent, null);builder.toStream(os);builder.run();try (FileOutputStream fos = new FileOutputStream(outputPath)) {fos.write(os.toByteArray());}} catch (Exception e) {logger.error("生成PDF文件时发生错误", e);throw new IOException("生成PDF文件时发生错误:" + e.getMessage(), e);}logger.info("PDF文件生成成功,输出路径:{}", outputPath);}/*** 生成PDF文件并返回文件流** @param htmlContent HTML内容* @return 文件流* @throws IOException 如果PDF生成失败*//*** 生成PDF文件并返回文件流** @param htmlContent HTML内容* @return 文件流* @throws IOException 如果PDF生成失败*/public static ByteArrayOutputStream generatePdfAsStream(String htmlContent) throws IOException {logger.info("开始生成PDF文件");ByteArrayOutputStream outputStream = new ByteArrayOutputStream();try {PdfRendererBuilder builder = new PdfRendererBuilder();builder.useFastMode();// 设置中文字体路径String fontPath = DocumentUtil.class.getClassLoader().getResource("SimSun.ttf").toExternalForm();// 嵌入中文字体builder.useFont(() -> DocumentUtil.class.getClassLoader().getResourceAsStream("SimSun.ttf"), "SimSun");// 在HTML中使用该字体htmlContent = htmlContent.replace("<head>", "<head>\n<style>@font-face { font-family: 'SimSun'; src: url('" + fontPath + "'); }</style>");htmlContent = htmlContent.replace("&nbsp;", "&#160;");htmlContent = htmlContent.replace("&ldquo;", "“");htmlContent = htmlContent.replace("&rdquo;", "”");// 去除html body 里的字体样式 只去除body里的htmlContent = htmlContent.replace("<body>", "<body style=\"font-family: 'SimSun', Arial, sans-serif;\">");htmlContent = cleanHtmlBodyFonts(htmlContent);builder.withHtmlContent(htmlContent, null);builder.toStream(outputStream);builder.run();} catch (Exception e) {logger.error("生成PDF文件时发生错误", e);throw new IOException("生成PDF文件时发生错误:" + e.getMessage(), e);}logger.info("PDF文件生成成功");return outputStream;}/*** 生成包含复杂内容的PDF文件** @param outputPath 输出文件路径* @throws IOException 如果PDF生成失败*/public static void generateComplexPdf(String outputPath) throws IOException {String htmlContent = "<!DOCTYPE html>\n" +"<html lang=\"en\">\n" +"<head>\n" +"    <meta charset=\"UTF-8\" />\n" +"    <style>\n" + "    body {\n" +"        font-family: 'SimSun', Arial, sans-serif;\n" +"    }" +"        h1 {\n" +"            color: #333;\n" +"        }\n" +"        p {\n" +"            font-size: 14px;\n" +"            line-height: 1.5;\n" +"        }\n" +"        table {\n" +"            width: 100%;\n" +"            border-collapse: collapse;\n" +"        }\n" +"        table, th, td {\n" +"            border: 1px solid black;\n" +"        }\n" +"        th, td {\n" +"            padding: 8px;\n" +"            text-align: left;\n" +"        }\n" +"        img {\n" +"            width: 100px;\n" +"            height: auto;\n" +"        }\n" +"    </style>\n" +"    <title>Complex PDF Example</title>\n" +"</head>\n" +"<body>\n" +"    <h1>PDF生成示例</h1>\n" +"    <p>这是一个包含不同内容的PDF示例。</p>\n" +"    <h2>表格</h>\n" +"    <table>\n" +"        <tr>\n" +"            <th>名称</th>\n" +"            <th>年龄</th>\n" +"            <th>城市</th>\n" +"        </tr>\n" +"        <tr>\n" +"            <td>张三</td>\n" +"            <td>30</td>\n" +"            <td>北京</td>\n" +"        </tr>\n" +"        <tr>\n" +"            <td>李四</td>\n" +"            <td>25</td>\n" +"            <td>上海</td>\n" +"        </tr>\n" +"    </table>\n" +"    <h2>图像</h2>\n" +"    <img src=\"https://via.placeholder.com/100\" alt=\"示例图像\" />\n" +"</body>\n" +"</html>";generatePdf(htmlContent, outputPath);}/*** 生成包含复杂内容的PDF文件并返回文件流** @return 文件流* @throws IOException 如果PDF生成失败*/public static ByteArrayOutputStream generateComplexPdfAsStream() throws IOException {String htmlContent = "<!DOCTYPE html>\n" +"<html lang=\"en\">\n" +"<head>\n" +"    <meta charset=\"UTF-8\" />\n" +"    <style>\n" + "    body {\n" +"        font-family: 'SimSun', Arial, sans-serif;\n" +"    }" +"        h1 {\n" +"            color: #333;\n" +"        }\n" +"        p {\n" +"            font-size: 14px;\n" +"            line-height: 1.5;\n" +"        }\n" +"        table {\n" +"            width: 100%;\n" +"            border-collapse: collapse;\n" +"        }\n" +"        table, th, td {\n" +"            border: 1px solid black;\n" +"        }\n" +"        th, td {\n" +"            padding: 8px;\n" +"            text-align: left;\n" +"        }\n" +"        img {\n" +"            width: 100px;\n" +"            height: auto;\n" +"        }\n" +"    </style>\n" +"    <title>Complex PDF Example</title>\n" +"</head>\n" +"<body>\n" +"    <h1>PDF生成示例</h1>\n" +"    <p>这是一个包含不同内容的PDF示例。</p>\n" +"    <h2>表格</h2>\n" +"    <table>\n" +"        <tr>\n" +"            <th>名称</th>\n" +"            <th>年龄</th>\n" +"            <th>城市</th>\n" +"        </tr>\n" +"        <tr>\n" +"            <td>张三</td>\n" +"            <td>30</td>\n" +"            <td>北京</td>\n" +"        </tr>\n" +"        <tr>\n" +"            <td>李四</td>\n" +"            <td>25</td>\n" +"            <td>上海</td>\n" +"        </tr>\n" +"    </table>\n" +"    <h2>图像</h2>\n" +"    <img src=\"https://via.placeholder.com/100\" alt=\"示例图像\" />\n" +"</body>\n" +"</html>";return generatePdfAsStream(htmlContent);}public static String cleanHtmlBodyFonts(String htmlContent) {// 清除内联样式中的字体相关属性String cleaned = htmlContent.replaceAll("font-family:\\s*[^;\"']+;?", ""  // 清除 font-family).replaceAll("style=\"\\s*\"", ""  // 清除空的style属性).replaceAll("<body[^>]*>", "<body style=\"font-family: 'SimSun', Arial, sans-serif;\">"  // 替换body标签);// 清除仿宋_GB2312等特定字体类cleaned = cleaned.replaceAll("font-family:\\s*[仿宋楷体]+((_GB2312)|(_GBK))?[^;\"']*;?", "");return cleaned;}
}

该处使用的url网络请求的数据。


导出样式

相关文章:

动态导出word文件支持转pdf

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、功能说明二、使用步骤1.controller2.工具类 DocumentUtil 导出样式 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff…...

登陆harbor发现证书是错误的, 那么如何更新harbor的证书呢

Error response from daemon: Get "https://172.16.21.35/v2/": tls: failed to verify certificate: x509: certificate is valid for 127.0.0.1, ::1, 172.16.21.30, not 172.16.21.35 版本 v2.10.1-b7b88476 不需要从头看, 直接看最下面的成功的证书创建 这里面首…...

【Leetcode Top 100】199. 二叉树的右视图

问题背景 给定一个二叉树的 根节点 r o o t root root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 数据约束 二叉树的节点个数的范围是 [ 0 , 100 ] [0,100] [0,100] − 100 ≤ N o d e . v a l ≤ 100…...

React自学:如何使用localStorage,以及如何实现删除笔记操作

1. 初始化notes 以下这段代码完成了这些操作&#xff1a; 调用 localStorage.getItem("notes") 从浏览器的本地存储中获取名为 “notes” 的数据。使用 JSON.parse 将获取到的字符串解析成数组。如果本地存储中没有 “notes” 数据&#xff08;返回值为 null&#…...

go语言使用websocket发送一条消息A,持续接收返回的消息

在Go语言中实现一个WebSocket客户端&#xff0c;可以使用gorilla/websocket这个非常流行的库来处理WebSocket连接。下面是一个简单的示例&#xff0c;展示了如何创建一个WebSocket客户端&#xff0c;向服务器发送消息"A"&#xff0c;并持续接收来自服务器的响应。 首…...

如何对小型固定翼无人机进行最优的路径跟随控制?

控制架构 文章继续采用的是 ULTRA-Extra无人机&#xff0c;相关参数如下&#xff1a; 这里用于guidance law的无人机运动学模型为&#xff1a; { x ˙ p V a cos ⁡ γ cos ⁡ χ V w cos ⁡ γ w cos ⁡ χ w y ˙ p V a cos ⁡ γ sin ⁡ χ V w cos ⁡ γ w sin ⁡ χ…...

C++常见面试题-初级2

1. C和C有什么区别&#xff1f; C是面向对象的语言&#xff0c;而C是面向过程的语言&#xff1b;C引入new/delete运算符&#xff0c;取代了C中的malloc/free库函数&#xff1b;C引入引用的概念&#xff0c;而C中没有&#xff1b;C引入类的概念&#xff0c;而C中没有&#xff1…...

Spring Security 6 系列之二 - 基于数据库的用户认证和认证原理

之所以想写这一系列&#xff0c;是因为之前工作过程中使用Spring Security&#xff0c;但当时基于spring-boot 2.3.x&#xff0c;其默认的Spring Security是5.3.x。之后新项目升级到了spring-boot 3.3.0&#xff0c;结果一看Spring Security也升级为6.3.0&#xff0c;关键是其风…...

mfc140.dll是什么东西?mfc140.dll缺失的几种具体解决方法

mfc140.dll是Microsoft Foundation Classes&#xff08;MFC&#xff09;库中的一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;它是微软基础类库的一部分&#xff0c;为Windows应用程序的开发提供了丰富的类库和接口。MFC库旨在简化Windows应用程序的开发过程&…...

【STM32 Modbus编程】-作为主设备写入多个线圈和寄存器

作为主设备写入多个线圈和寄存器 文章目录 作为主设备写入多个线圈和寄存器1、硬件准备与连接1.1 RS485模块介绍1.2 硬件配置与接线1.3 软件准备2、写入多个线圈2.1 数据格式2.2 发送数据2.3 结果3、写入多个寄存器3.1 数据格式3.2 发送数据3.3 结果本文将实现STM32作为ModBus主…...

Windows安全中心(病毒和威胁防护)的注册

文章目录 Windows安全中心&#xff08;病毒和威胁防护&#xff09;的注册1. 简介2. WSC注册初探3. WSC注册原理分析4. 关于AMPPL5. 参考 Windows安全中心&#xff08;病毒和威胁防护&#xff09;的注册 本文我们来分析一下Windows安全中心&#xff08;Windows Security Center…...

微积分复习笔记 Calculus Volume 2 - 4.2 Direction Fields and Numerical Methods

4.2 Direction Fields and Numerical Methods - Calculus Volume 2 | OpenStax...

深入理解旋转位置编码(RoPE)及其在大型语言模型中的应用

文章目录 前言一、 旋转位置编码原理1、RoPE概述2、 复数域内的旋转1、位置编码生成2、 应用位置编码二、RoPE的实现细节1、RotaryEmbedding类设计2、apply_rotary_pos_emb函数3、demo_apply_rotary_pos_emb函数三、完整RoPE代码Demo前言 随着自然语言处理(NLP)领域的快速发…...

内网穿透的应用-在OpenWrt上轻松搭建SFTP服务,安全传输文件不再难!

文章目录 前言1. 安装openssh-sftp-server2. 安装cpolar工具3.配置SFTP远程访问4.固定远程连接地址 前言 本次教程我们将在OpenWRT系统上安装SFTP服务&#xff0c;并结合cpolar内网穿透&#xff0c;创建安全隧道映射22端口&#xff0c;实现在公网环境下远程OpenWRT SFTP&#…...

【图像处理lec3、4】空间域的图像增强

目录 1. 空间域图像增强的背景与目标 2. 空间域处理的数学描述 3. 灰度级变换 4. 幂律变换&#xff08;Power-Law Transformation&#xff09; 5、 分段线性变换 Case 1: 对比度拉伸 Case 2: 灰度切片 Case 3: 按位切片 6、对数变换&#xff08;Logarithmic Transform…...

【算法day13】二叉树:递归与回溯

题目引用 找树左下角的值路径总和从中序与后序遍历构造二叉树 今天就简简单单三道题吧~ 1. 找到树左下角的值 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1: 输入: root [2,1,3] 输出: 1 我们…...

上海亚商投顾:创业板指缩量下跌 多只高位股午后跌停

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 市场全天震荡调整&#xff0c;创业板指领跌&#xff0c;高位股开始出现退潮&#xff0c;建设工业、星光股份、…...

单步调试Android Framework——App冷启动

纸上得来终觉浅&#xff0c;绝知此事要躬行。 —— [宋]陆游 基于aosp_cf_x86_64_phone-trunk_staging-eng &#xff0c; 下面是具体断点位置。 第一部分&#xff0c;桌面launcher进程 com.android.launcher3.touch.ItemClickHandler onClickonClickAppShortcutstartAppShor…...

统计一个目录下的文件及目录数量-linux010

要统计一个目录下的文件数量&#xff08;包括子目录中的文件&#xff09;&#xff0c;可以使用以下命令&#xff1a; 1. 统计所有文件数量&#xff08;包括子目录&#xff09; 在终端中运行以下命令&#xff1a; find /path/to/directory -type f | wc -l 解释&#xff1a;…...

spring RestTemplate使用说明

rest-template是spring对httpclient的逻辑封装&#xff0c;它底层还是基于httpclient&#xff0c;所以一些配置其实跟httpclient是强相关的。 基本配置 rest-template可以不带参数&#xff0c;使用默认配置&#xff0c;也可以指定ClientHttpRequestFactory参数&#xff0c;Cl…...

thinkphp:try-catch捕获异常

使用简单的例子&#xff0c;实现了一个简单的try-catch捕获异常的实例 //开始事务Db::startTrans(); try{ //有异常抛出异常 if(存在错误){ throw new \Exception("异常信息"); } // 提交事务 Db::commit(); // 返回成功信息 ... } catch (\…...

shardingsphere分库分表跨库访问 添加分片规则

shardingsphere分库分表跨库访问 添加分片规则 建立 JDBC 环境 创建表 t_order&#xff1a; CREATE TABLE t_order (tid bigint(20) NOT NULL,tname varchar(255) DEFAULT NULL,goods_id bigint(20) DEFAULT NULL,tstatus varchar(255) DEFAULT NULL,PRIMARY KEY (tid) ) E…...

c++:std::map下标运算符的不合理使用

这是我分析之前遗留代码时发现的一个隐藏点&#xff1b;不过我并不认为这样使用std::map是合理的。 看看简化后的代码&#xff0c;v1、v2的值应该是多少呢&#xff1f; #include <map>std::map<int, int> cm[2];int get_cm_value(int device, int ctrl) { auto …...

KeyFormer:使用注意力分数压缩KV缓存

Keyformer: KV Cache Reduction through Key Tokens Selection for Efficient Generative Inference 202403&#xff0c;发表在Mlsys Introduction 优化KV cache的策略&#xff0c;主要是集中在系统级别的优化上&#xff0c;比如FlashAttention、PagedAttention&#xff0c;它…...

MetaGPT源码 (ContextMixin 类)

目录 理解 ContextMixin什么是 ContextMixin&#xff1f;主要组件实现细节 测试 ContextMixin示例&#xff1a;ModelX1. 配置优先级2. 多继承3. 多继承重写4. 配置优先级 在本文中&#xff0c;我们将探索 ContextMixin 类&#xff0c;它在多重继承场景中的集成及其在 Python 配…...

MATLAB生成.exe独立程序过程(常见问题解决方法)(2024.12.14)

本文只记录我执行过程中遇到的关键问题、以及解决方法&#xff0c;不讲诉整个流程。 电脑环境 win11系统 matlab 2024b 版本 整体流程 1.下载matlab运行时库,简写为MCR 2.配置MCR环境 3.打包程序 4.目标机器安装程序 一、下载MCR 下载这个折腾了大半天&#xff0c;大概问题就是…...

PHP排序算法:数组内有A~E,A移到C或者C移到B后排序,还按原顺序排序,循环

效果 PHP代码 public function demo($params){function moveNext($arr){$length count($arr);$lastElement $arr[$length - 1];for ($i $length - 1; $i > 0; $i--) {$arr[$i] $arr[$i - 1];}$arr[0] $lastElement;return $arr;}function moveAndReplace($array, $from…...

ChatGPT搜索全新升级,向全体用户开放,近屿智能助力AI行业发展

12月17日&#xff0c;OpenAI在第八天直播中正式宣布ChatGPT搜索功能全面升级&#xff0c;并即日起对所有ChatGPT用户开放。此次更新不仅带来了显著的性能提升&#xff0c;还引入了多项突破性功能&#xff0c;如更快的搜索速度、全新的地图体验以及YouTube视频嵌入&#xff0c;为…...

win10配置免密ssh登录远程的ubuntu

为了在终端ssh远程和使用VScode远程我的VM上的ubuntu不需要设置密码&#xff0c;需要在win10配置免密ssh登录远程的ubuntu。 在win10打开cmd&#xff0c;执行下面的代码生成密钥对&#xff08;会提示进行设置&#xff0c;按照默认的配置就行&#xff0c;一直回车&#xff09;&…...

skywalking 搭建 备忘录

基础环境 apache-skywalking-apm-9.6.0.tar.gz apache-skywalking-java-agent-9.1.0.tgz elasticsearch 7.14.1 采用dockers搭建 或者手动部署 kibana 可视化 应用 微服务版 consumer.jar eureka.jar 注册中心 provider.jar skywalking 地址 https://skywalkin…...