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

poi-tl+kkviewfile实现生成pdf业务报告

需求背景,需要把ai生成的一些业务数据,生成一份pdf报告

需求分析

简单来说,就是json生成pdf的方案。

  1. 直接生成pdf。适合一些pdf样式简单的场景,一般就是纯文本按序渲染,或者是纯表格。如果需要一些复杂的排布,比如图片、水印、页眉页脚之类的,用pdf直接渲染的话就会复杂很多,而且后续有个什么改动,都很麻烦。我试了一下初步排除了这个方案。
  2. 先生成word,之后再word转pdf。先说缺点,word转pdf需要引入额外的服务,会比较重。但事情都是一体两面的,是缺点的同时也是优点,json生成word的技术,和word转pdf的技术都是比较成熟的,效果也不错,市面上都有很优秀的开源包或者开源系统可以使用。属于一种一劳永逸的方案吧。

方案选择

最后的方案是

  1. json生成word,采用poi-tl,一款简单好用的word模板渲染工具。大部分的样式都可以在word上提前用占位符的方式写好,代码层面只需要做数据填充即可,不用在后端代码里做样式渲染这种事情。(当然,部分场景也避免不了,不可能完全解耦)。基础用法不做赘述,官方文档很详细。后面会补一些我自己遇到的小问题。
  2. 第二步,word转pdf。这一步试了几种方案。aspose收费且有水印,排除;jacob不支持linux,排除;jodconverter+openOffice效果不错且免费,但是openoffice不适合与业务服务部署在一起,单独部署的话需要再包一层,成本会略大。但好在这个事情有人已经做过了,kkviewfile就是市面上基于openoffice而开源的一个pdf预览转换服务。github上也有详细的部署文档,不做赘述。

使用过程中的几个小问题

  1. poi-tl种的区块对是一个很好用的原生插件,但是如果想在区块对中嵌套一些其他样式,比如列表的话,直接使用不会生效,需要额外指定。
// 比如这里的events是一个事件列表占位符名称,NumberingRenderPolicyEva是我自定义的一个列表插件
builder.bind("events", new NumberingRenderPolicyEva()).build();
  1. word转pdf的时候,有些样式会有偏差,首先是因为word和pdf的格式不会是完全兼容的,一些隐藏的属性,在word中的展示和pdf中完全不一样。大部分属性都是可以在word中设置或者poi中指定的(poi会暴露常见的属性),比如我遇到的一个问题:word中设置好指定的行距,到了pdf中会失效,变成固定的行距,明显宽了很多,导致页数增加。
    试了几个样式,发现只有页眉没问题,所以确定是预设样式的属性原因。
    在这里插入图片描述
    最后发现是这个属性的问题在这里插入图片描述
    当然,还有一些隐藏更深的属性,可以把word解压出来,在xml中对照着看,然后修改自己需要的属性即可,eg:
    在这里插入图片描述
    在这里插入图片描述
  2. 最后补充一个小建议,这种和业务耦合不是很高的技术需求,使用cursor会有奇效哦

相关文章:

poi-tl+kkviewfile实现生成pdf业务报告

需求背景,需要把ai生成的一些业务数据,生成一份pdf报告 需求分析 简单来说,就是json生成pdf的方案。 直接生成pdf。适合一些pdf样式简单的场景,一般就是纯文本按序渲染,或者是纯表格。如果需要一些复杂的排布&#x…...

【Uniapp-Vue3】scroll-view可滚动视图区域组件

如果我们有一个区域有限的大盒子&#xff08;黑&#xff09;&#xff0c;而我们要在盒子中装的东西&#xff08;灰&#xff09;过多&#xff0c;我们就会用到滚动视图&#xff1a; 表现在代码上就是下面这个样子&#xff1a; <template><view class"scrollView&…...

asp.net core webapi中的数据注解与数据验证

在这一课中&#xff0c;主要讲解了如何在 Web API 中使用数据注解&#xff08;Data Annotations&#xff09;和进行数据验证&#xff0c;以确保请求数据的有效性和完整性。 在 Web API 中&#xff0c;数据验证是确保客户端传递的数据符合业务规则和格式要求的关键步骤。数据注…...

PixPin—— 高效截图工具的下载与使用攻略

在日常的工作和学习中&#xff0c;一款好用的截图工具能极大地提高我们的效率。今天就来给大家介绍一款功能强大的截图工具 ——PixPin。 下载篇 PixPin 的下载非常简单&#xff0c;只需访问下载网站&#xff0c;在首页就能找到适合你操作系统的下载链接。如果你使用的是 Win…...

Go语言的 的多态性(Polymorphism)基础知识

Go语言的多态性&#xff08;Polymorphism&#xff09;基础知识 在编程语言中&#xff0c;多态性是一个核心概念&#xff0c;它允许同一接口被不同的数据类型所实现&#xff0c;从而在不影响代码结构的情况下增强代码的灵活性和可扩展性。在Go语言中&#xff0c;多态性通过接口…...

Vue框架主要用来做什么?Vue框架的好处和特性.

在快速发展的互联网时代&#xff0c;前端开发技术的变革日新月异&#xff0c;为开发者带来了前所未有的机遇与挑战。Vue.js&#xff0c;作为前端开发领域的一颗璀璨新星&#xff0c;以其轻量级、高效灵活的特性&#xff0c;赢得了广大开发者的青睐。本文将深入探讨Vue框架的主要…...

科普CMOS传感器的工作原理及特点

在当今数字化成像的时代&#xff0c;图像传感器无疑是幕后的关键 “功臣”&#xff0c;它宛如一位神奇的 “光影魔法师”&#xff0c;通过光电效应这一奇妙的物理现象&#xff0c;将光子巧妙地转换成电荷&#xff0c;为图像的诞生奠定基础。而在众多类型的图像传感器中&#xf…...

tensorflow 内存错误

使用tensorflow训练多个模型时&#xff0c;训练过程中容易出现内存错误&#xff0c;在这里记录一下解决办法。希望能帮到各位。 2025-01-02 22:31:03.489713: W tensorflow/core/common_runtime/bfc_allocator.cc:275] Allocator (GPU_0_bfc) ran out of memory trying to all…...

spring boot解决swagger中的v2/api-docs泄露漏洞

在配置文件中添加以下配置 #解决/v2/api-docs泄露漏洞 springfox:documentation:swagger-ui:enabled: falseauto-startup: false 处理前&#xff1a; 处理后&#xff1a;...

计算机网络 (25)IPV6

前言 IPv6&#xff0c;全称为“互联网协议第6版”&#xff08;Internet Protocol Version 6&#xff09;&#xff0c;是由互联网工程任务组&#xff08;IETF&#xff09;设计的用于替代IPv4的下一代IP协议。 一、产生背景 IPv4&#xff0c;即互联网协议第4版&#xff0c;是现行…...

小程序组件 —— 30 组件 - 背景图片的使用

在编写小程序的样式文件时&#xff0c;可以使用 background-image 属性来设置元素的背景图像&#xff1b;但是这个属性在微信小程序中使用时存在坑&#xff1b; 注意事项&#xff1a;微信小程序中的 background-iamge 不支持本地路径&#xff01;需要使用网络图片&#xff0c;…...

《Opencv》信用卡信息识别项目

目录 一、项目介绍 二、数据材料介绍 1、模板图片&#xff08;1张&#xff09; 2、需要处理的信用卡图片&#xff08;5张&#xff09; 三、实现过程 1、导入需要用到的库 2、设置命令行参数 3、模板图像中数字的定位处理 4、信用卡图像处理 5、模板匹配 四、总结 一…...

Matlab贝叶斯估计MCMC分析药物对不同种群生物生理指标数据评估可视化

全文链接&#xff1a;https://tecdat.cn/?p38756 摘要&#xff1a;本文着重探讨了如何利用Matlab实现贝叶斯估计。阐述了具体的实现流程&#xff0c;涵盖数据加载、先验常数设定、马尔可夫链蒙特卡洛&#xff08;MCMC&#xff09;属性指定、模型构建、运行链条以及结果查看等环…...

java 转义 反斜杠 Unexpected internal error near index 1

代码&#xff1a; String str"a\\c"; //出现异常&#xff0c;Unexpected internal error near index 1 //System.out.println(str.replaceAll("\\", "c"));//以下三种都正确 System.out.println(str.replace(\\, c)); System.out.println(str.r…...

网络安全常见的问题

1. 什么是 DDoS 攻击&#xff1f;如何防范&#xff1f; 答&#xff1a;DDoS 攻击是指利用大量的计算机或者其他网络设备&#xff0c;同时向目标网络或者服务器 发送 大量的数据流量&#xff0c;以致其无法正常工作&#xff0c;从而导致网络瘫痪或者服务器宕机的攻击行 为。 …...

在ubuntu22.04中使用bear命令追踪内核编译报错的原因分析和解决方案

1.说明 我在ubuntu22.04中使用bear命令追踪内核编译时发生如下报错&#xff1a; 如图&#xff0c;在链接名为libexec.so的动态库时发生错误 2 分析及解决过程 打印变量 LIB 发现其为空&#xff0c;也就是说 bear会去 /usr/bear/ 去找 libexec.so 去看一下 /usr/bear/是否存…...

【软考网工笔记】操作系统管理与配置——Windows

1-域名解析 Cache 域名解析 Cache 即 DNS 快取&#xff0c;DNS 快取需要应用客户机域名解析服务 DNSClient&#xff0c;其进程名为 svchost.exe -k NetworkService&#xff0c;可以输入命令&#xff1a;net stop dnscache 将其结束。原理是在 Windows 系统中&#xff0c;加入了…...

vue3 css实现文字输出带光标显示,文字输出完毕,光标消失的效果

Vue实现过程如下&#xff1a; <template><div ><p ref"dom_element" class"typing" :class"{over_fill: record_input_over}"></p></div> </template> <script setup> import {onMounted, ref} from…...

什么情况会导致JVM退出?

大家好&#xff0c;我是锋哥。今天分享关于【什么情况会导致JVM退出?】面试题。希望对大家有帮助&#xff1b; 什么情况会导致JVM退出? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM&#xff08;Java Virtual Machine&#xff09;在不同情况下可能会退出&am…...

CentOS7修改Docker默认存储路径

当你使用Docker时&#xff0c;Docker的默认配置是将镜像、容器和卷存储在系统/var/lib/docker/目录下&#xff0c;如果docker镜像安装的太多会导致磁盘不够&#xff0c;你可以尝试以下方法来释放空间&#xff1a; 清理无用的镜像和容器&#xff1a;使用docker命令删除不再使用…...

基于 SpringBoot 的生活信息分享平台,从 0 到 1 完整实现(附源码 + 数据库)

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…...

避坑指南:OpenSIPS 3.1在Docker下的5个常见配置错误(附NAT解决方案)

OpenSIPS 3.1容器化部署实战&#xff1a;5个关键配置陷阱与高效排错手册 当你第一次尝试在Docker中部署OpenSIPS 3.1时&#xff0c;是否遇到过容器正常启动却无法建立会话的情况&#xff1f;这就像在黑暗迷宫中摸索——明明每个转角都看似正确&#xff0c;却总在关键时刻碰壁。…...

5分钟搞定Augment实战:从VSCode到Cursor的无缝衔接与风控破解

1. Augment插件迁移实战指南 作为一名长期在AI领域摸爬滚打的老兵&#xff0c;我最近发现越来越多的开发者开始从VSCode转向Cursor这款新兴编辑器。但在这个过程中&#xff0c;Augment插件的迁移问题让不少朋友头疼。今天我就用最直白的语言&#xff0c;手把手带你完成从VSCode…...

像素史诗·智识终端Web应用开发全栈指南:从后端API到前端交互

像素史诗智识终端Web应用开发全栈指南&#xff1a;从后端API到前端交互 1. 项目概述与核心价值 在当今AI技术快速落地的背景下&#xff0c;如何将强大的AI能力整合到Web应用中成为开发者关注的重点。本文将完整演示如何以像素史诗智识终端为AI引擎&#xff0c;开发一个具备聊…...

从轮子直径到PID调参:编码器测速数据如何精准换算成实际速度(附单位换算避坑指南)

从脉冲到速度&#xff1a;编码器测速全流程实战指南 当你的机器人或智能车项目需要精确控制移动速度时&#xff0c;编码器测速的准确性直接决定了闭环控制的效果。但很多开发者都会遇到这样的困惑&#xff1a;为什么编码器读数看起来很大&#xff0c;但实际速度却与预期不符&am…...

从混乱到有序:用pd.to_numeric()高效清洗数据中的数字陷阱

1. 数据清洗中的数字陷阱&#xff1a;为什么需要pd.to_numeric() 刚入行数据分析时&#xff0c;我接手过一个电商价格分析项目。原始数据是从20个Excel表格合并而来&#xff0c;打开一看差点崩溃——价格字段里混着"199"、"199元"、"199.00"、&…...

Android 13 网络策略调优:实现以太网与WIFI的智能协同

1. 为什么需要以太网与WIFI智能协同&#xff1f; 在智能家居控制面板、工业手持终端这类设备上&#xff0c;我们经常遇到一个头疼的问题&#xff1a;插着网线时WIFI自动断连。Android系统默认的"以太网优先"策略&#xff0c;就像个非黑即白的直男——只要检测到网线插…...

【Day 10 Java转Python】@property——把方法当属性用,Python的封装艺术

Java老兵写Python时最常问的问题&#xff1a;“私有字段呢&#xff1f;getter和setter呢&#xff1f;没有这些&#xff0c;封装还叫封装吗&#xff1f;” 别急&#xff0c;Python告诉你&#xff1a;封装不是为了写一堆getXxx()/setXxx()&#xff0c;而是为了在需要时优雅地插入…...

如何永久备份微信聊天记录?这个免费工具让你轻松掌握数字记忆的主动权

如何永久备份微信聊天记录&#xff1f;这个免费工具让你轻松掌握数字记忆的主动权 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Tr…...

5个实战技巧解决ComfyUI ControlNet Aux预处理器的模型管理难题

5个实战技巧解决ComfyUI ControlNet Aux预处理器的模型管理难题 【免费下载链接】comfyui_controlnet_aux ComfyUIs ControlNet Auxiliary Preprocessors 项目地址: https://gitcode.com/gh_mirrors/co/comfyui_controlnet_aux 在AI绘画工作流中&#xff0c;ComfyUI Con…...