java aspose word 模板根据数据导出pdf

支持以功能:

1、字符串占位符替换。

2、占位符循环替换。

3、图片替换。

4、基础图标,折现、饼图、柱状图。

本案例运行环境:

1、aspose word21.1版本。

2、jdk 18。

话不多说直接上代码。

<!-- 图表相关 --><dependency><groupId>jfree</groupId><artifactId>jfreechart</artifactId><version>1.0.13</version></dependency><!-- 文档处理 --><dependency><groupId>com.aspose</groupId><artifactId>aspose-words</artifactId><version>21.1</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/aspose-words-21.1.jar</systemPath></dependency><!-- lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency>
maven依赖
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.renderer.category.StandardBarPainter;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;import java.awt.*;
import java.text.DecimalFormat;
import java.text.NumberFormat;/***@author pengbenlei*@date 2024/12/12 11:37*@desc*/
public class ChartUtil {private static final Color[] BAR_COLORS = new Color[]{new Color(79, 129, 189),new Color(192, 80, 77),new Color(155, 187, 89),};private static final Color[] LINE_COLORS = new Color[]{new Color(237, 123, 46),new Color(90, 154, 213),new Color(164, 164, 164),};private static final Color[] PIE_COLORS = new Color[]{new Color(75, 172, 198),new Color(128, 100, 162),new Color(155, 187, 89),new Color(192, 80, 77),new Color(79, 129, 189),new Color(44, 77, 117),new Color(247, 150, 70),new Color(165, 165, 165),};private static StandardChartTheme initChartTheme() {StandardChartTheme currentTheme = new StandardChartTheme("JFree");// 横轴纵轴标题文字大小currentTheme.setLargeFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 15));// 横轴纵轴数值文字大小currentTheme.setRegularFont(new java.awt.Font("宋体", java.awt.Font.PLAIN, 13));currentTheme.setExtraLargeFont(new java.awt.Font("宋体", java.awt.Font.BOLD, 20));// 背景颜色currentTheme.setPlotBackgroundPaint(new Color(255, 255, 204, 0));// 边框线条currentTheme.setPlotOutlinePaint(new Color(0, 0, 0, 0));// 网格线条currentTheme.setRangeGridlinePaint(new Color(78, 74, 74));return currentTheme;}/*** 线图** @param title 标题* @param categoryAxisLabel 分类标签* @param valueAxisLabel 数值标签* @param dataset 数据集* @return org.jfree.chart.JFreeChart* @author Hou_fx* @date 2021.8.4 10:39*/public static JFreeChart lineChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset) {ChartFactory.setChartTheme(initChartTheme());JFreeChart chart = ChartFactory.createLineChart(title,categoryAxisLabel,valueAxisLabel,dataset,PlotOrientation.VERTICAL,true,true,false);CategoryPlot plot = chart.getCategoryPlot();LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer();// 折现点显示数值renderer.setBaseItemLabelsVisible(true);renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());// 更改线条颜色for (int i = 0; i < dataset.getRowKeys().size(); i++) {renderer.setSeriesPaint(i, LINE_COLORS[i]);}return chart;}/*** 柱状图** @param title* @param categoryAxisLabel* @param valueAxisLabel* @param dataset           数据集* @return org.jfree.chart.JFreeChart* @author Hou_fx* @date 2021.8.4 14:03*/public static JFreeChart barChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset) {ChartFactory.setChartTheme(initChartTheme());JFreeChart chart = ChartFactory.createBarChart(title,categoryAxisLabel,valueAxisLabel,dataset,PlotOrientation.VERTICAL,true,true,false);CategoryPlot plot = chart.getCategoryPlot();BarRenderer renderer = (BarRenderer) plot.getRenderer();// 纯色显示renderer.setBarPainter(new StandardBarPainter());// 柱子上显示小数字renderer.setBaseItemLabelsVisible(true);renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());// 设置柱子间隔renderer.setItemMargin(0.0);// 设置柱子颜色for (int i = 0; i < dataset.getRowKeys().size(); i++) {renderer.setSeriesPaint(i, BAR_COLORS[i]);}return chart;}/*** 饼图** @param title* @param dataset* @return org.jfree.chart.JFreeChart* @author Hou_fx* @date 2021.8.4 14:04*/public static JFreeChart pieChart(String title, DefaultPieDataset dataset) {ChartFactory.setChartTheme(initChartTheme());JFreeChart chart = ChartFactory.createPieChart(title,dataset,true,true,false);PiePlot plot = (PiePlot) chart.getPlot();// 设置扇区颜色for (int i = 0; i < dataset.getKeys().size(); i++) {plot.setSectionPaint(dataset.getKey(i), PIE_COLORS[i]);}// 设置扇区的线条颜色plot.setBaseSectionOutlinePaint(new Color(255, 255, 255));// 设置扇区的线条大小plot.setBaseSectionOutlineStroke(new BasicStroke(3));// 设置标签颜色plot.setLabelLinkPaint(new Color(255, 255, 255, 0));// 设置标签背景色plot.setLabelBackgroundPaint(new Color(255, 255, 255, 0));// 设置标签线条颜色plot.setLabelOutlinePaint(new Color(255, 255, 255, 0));// 设置标签阴影颜色plot.setLabelShadowPaint(new Color(255, 255, 255, 0));// 设置饼图阴影颜色plot.setShadowPaint(new Color(255, 255, 255, 0));// 添加标签数字百分比显示plot.setLabelGenerator(new StandardPieSectionLabelGenerator(("{0}{2}"), NumberFormat.getNumberInstance(), new DecimalFormat("0.00%")));return chart;}
}
图表相关工具类
import com.aspose.words.*;
import org.jfree.chart.ChartUtilities;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;/***@author pengbenlei*@date 2024/12/12 15:07*@desc*/
public class AsposeUtils {/*** 根据word模板生成pdf* @param template 模板路径* @param outPath  输出目录* @param dataJson  业务数据json字符串* @param sourceName 业务数据源名称* @param wordImages  图片集合* @throws Exception 异常信息*/public static void getPdfByWordTemplate(String template, String outPath, String dataJson, String sourceName, List<WordImg> wordImages) throws Exception {// 验证Assert.isTrue(StringUtils.hasLength(template), "模板文件路径不能为空!");Assert.isTrue(StringUtils.hasLength(sourceName), "模板数据源名称!");Assert.isTrue(StringUtils.hasLength(outPath), "pdf输出路径不能为空!");// 将输入流转为docDocument doc = new Document(template);// doc构建DocumentBuilder builder = new DocumentBuilder(doc);// 填充数据JsonDataLoadOptions opt = new JsonDataLoadOptions();final ReportingEngine engine = new ReportingEngine();JsonDataSource jsonDataSource = new JsonDataSource(new ByteArrayInputStream(dataJson.getBytes()), opt);engine.buildReport(doc, jsonDataSource, sourceName);// 填充图片for (WordImg wordImage : wordImages) {if (!StringUtils.hasLength(wordImage.getBookmark())) {continue;}// 定位书签位置builder.moveToBookmark(wordImage.getBookmark());if (wordImage.getType() == 1 || wordImage.getType() == 3) {// 本地图片和网络url图片builder.insertImage(wordImage.getPath());} else if (wordImage.getType() == 2) {// 字节码图片builder.insertImage(wordImage.getImageBytes());}}// 转pdfdoc.save(outPath, SaveFormat.PDF);}public static void main(String[] args) throws Exception {final String filePath = "C:\\Users\\Administrator\\Desktop\\上传整理\\新建文件夹\\temp.docx";final String outPath = "C:\\Users\\Administrator\\Desktop\\上传整理\\新建文件夹\\output.pdf";String jsonStr = "{\n" +"    \"age\": 20,\n" +"    \"birth\": \"1555-01-55\",\n" +"    \"checkNumber\": \"12349864\",\n" +"    \"idCard\": \"56456461645\",\n" +"    \"items\": [\n" +"        {\n" +"            \"checked\": false,\n" +"            \"itemName\": \"血常规\"\n" +"        },\n" +"        {\n" +"            \"checked\": false,\n" +"            \"itemName\": \"生化检验\"\n" +"        },\n" +"        {\n" +"            \"checked\": true,\n" +"            \"itemName\": \"尿常规\"\n" +"        }\n" +"    ],\n" +"    \"name\": \"张三三\",\n" +"    \"phone\": \"15445454454\",\n" +"    \"sex\": \"男\",\n" +"    \"title\": \"成都市温江区金马街道社区卫生服务中心\"\n" +"}";DefaultCategoryDataset lineDataset = new DefaultCategoryDataset();for (int i = 1; i < 10; i++) {lineDataset.addValue(i, "张儿", String.valueOf((i * 2)));}for (int i = 1; i < 5; i++) {lineDataset.addValue(i, "李儿", String.valueOf((i * 3)));}ByteArrayOutputStream bos = new ByteArrayOutputStream();// 折线图
//        ChartUtilities.writeChartAsJPEG(bos, ChartUtil.lineChart("测试折线图", "A", "B", lineDataset),
//                300, 300);// 折线图
//        ChartUtilities.writeChartAsJPEG(bos, ChartUtil.lineChart("测试折线图", "A", "B", lineDataset),
//                (int) signRect.getWidth(), (int) signRect.getHeight());// 饼图DefaultPieDataset defaultPieDataset = new DefaultPieDataset();defaultPieDataset.setValue("Category A", 40); // 类别 A 占 40%defaultPieDataset.setValue("Category B", 30); // 类别 B 占 30%defaultPieDataset.setValue("Category C", 20); // 类别 C 占 20%defaultPieDataset.setValue("Category D", 10); // 类别 D 占 10%ChartUtilities.writeChartAsJPEG(bos, ChartUtil.pieChart("测试饼图", defaultPieDataset),200, 200);
//        ChartUtilities.writeChartAsJPEG(bos, ChartUtil.barChart("测试柱状图", "A", "B", lineDataset),
//                200, 200);byte[] imageBytes = bos.toByteArray();List<WordImg> wordImages = new ArrayList<>();// 二维码WordImg wordImg1 = WordImg.builder().bookmark("qrCode").type(1).path("C:\\Users\\Administrator\\Desktop\\上传整理\\新建文件夹\\0.jpg").build();wordImages.add(wordImg1);WordImg wordImg2 = WordImg.builder().bookmark("lineImg").type(2).imageBytes(imageBytes).build();wordImages.add(wordImg2);getPdfByWordTemplate(filePath, outPath, jsonStr, "data", wordImages);}
}
文件处理工具类
import lombok.Builder;
import lombok.Data;/***@author pengbenlei*@date 2024/12/13 9:37*@desc Aspose图片数据*/
@Data
@Builder
public class WordImg {/*** 占位书签名*/private String bookmark;/*** 图片处理类型 1-本地图片 2-imageBytes  3-网络url图片*/private int type;/*** 图片路径*/private String path;/*** 图片字节数组*/private byte[] imageBytes;
}
图片

以上就能实现大部分模板替换的业务功能,下面说下模板的设计。

1、一般使用table对word模板布局。

2、占位符和模板语法查阅官方文档,或者看我的截图。

3、图片使用书签占位。

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

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

相关文章

Linux高性能服务器编程 | 读书笔记 |9.定时器

9. 定时器 网络程序需要处理定时事件&#xff0c;如定期检测一个客户连接的活动状态。服务器程序通常管理着众多定时事件&#xff0c;有效地组织这些定时事件&#xff0c;使其在预期的时间被触发且不影响服务器的主要逻辑&#xff0c;对于服务器的性能有至关重要的影响。为此&…

QT 国际化(翻译)

QT国际化&#xff08;Internationalization&#xff0c;简称I18N&#xff09;是指将一个软件应用程序的界面、文本、日期、数字等元素转化为不同的语言和文化习惯的过程。这使得软件能够在不同的国家和地区使用&#xff0c;并且可以根据用户的语言和地区提供本地化的使用体验。…

3D 生成重建034-NerfDiff借助扩散模型直接生成nerf

3D 生成重建034-NerfDiff借助扩散模型直接生成nerf 文章目录 0 论文工作1 论文方法2 实验结果 0 论文工作 感觉这个论文可能能shapE差不多同时期工作&#xff0c;但是shapE是生成任意种类。 本文提出了一种新颖的单图像视图合成方法NerfDiff&#xff0c;该方法利用神经辐射场 …

【CNN卷积神经网络算法】卷积神经网络

卷积神经网络整体架构 总结 输入层&#xff1a;原始数据&#xff08;图像&#xff09; 例如可以输入一张RGB图像&#xff0c;其可以标示为一个三维矩阵&#xff0c;宽W高H和通道数C3对应着RGB卷积层&#xff1a;提取局部特征&#xff0c;变换输入数据为丰富的特征图 网络使用多…

HarmonyOS Next 元服务新建到上架全流程

HarmonyOS Next 元服务新建到上架全流程 接上篇 这篇文章的主要目的是介绍元服务从新建到上家的完整流程 在AGC平台上新建一个项目 链接 一个项目可以多个应用 AGC新建一个元服务应用 新建一个本地元服务项目 如果成功在AGC平台上新建过元服务&#xff0c;那么这里会自动显…

Mac/Windows端长期破解myBase8方法(无需安装火绒)

提醒 不管哪个端&#xff0c;都需要先退出myBase。 Mac 进入用户根目录/Users/c0ny100&#xff0c;即下边是Macintosh HD > 用户 > [你的用户名]这个界面然后按ShiftCommond.&#xff0c;显示隐藏文件。找到.Mybase8.ini文件 打开.Mybase8.ini文件&#xff0c;删除Fir…

【网络安全】【Kali Linux】简单ICMP主机探测

一、参考资料 《Python安全攻防——渗透测试实战指南》&#xff0c;吴涛 等编著&#xff0c;机械工业出版社&#xff0c;2021年10月 二、探测原理 ICMP&#xff08;ping命令&#xff09; 三、脚本编写 1、导入所需的库&#xff1a; 2、扫描功能函数&#xff1a; 3、主函数…

Oracle进行exp导出密码中有特殊字符报EXP-00056和ORA-12154错处理

今天&#xff0c;业务人员反馈&#xff0c;在本地进行exp导出时报错&#xff0c;报错内容如下&#xff1a; 在Oracle密码中有特殊字符时&#xff0c;需要加引号&#xff0c;但引号怎么加呢&#xff1f;总结如下&#xff1a; 1、在windows系统中 exp 用户名/“““密码”””n…

MVC流程分析

DisaptcherServlet本质是servlet&#xff0c;执行init()方法&#xff0c;自启动底层执行代码&#xff0c; 作用&#xff1a; 1、读取springmvc配置文件&#xff0c;创建Controller对象&#xff0c;放入容器中&#xff0c;map<"id",对象> 2、接收用户请求&#…

fiddler设置抓取https,还抓取不到https如何解决?

一、清楚 C:\Users\Admin\AppData\Roaming\Microsoft\Crypto\RSA 目录下所有文件&#xff08;首次安装fiddler请忽略&#xff09; 二、清除电脑上的根证书&#xff0c;WINR快捷键&#xff0c;输入&#xff1a;certmgr.msc&#xff0c; 然后回车&#xff0c;查找所有fiddler证书…

【知识】总体标准差和样本标准差有什么区别

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 总体标准差和样本标准差之间的区别主要在于它们的计算方式&#xff0c;特别是在分母的选择上。这种差异是因为我们通常在实际应用中并不总是能够得到整…

.NET 9 已发布,您可以这样升级或更新

.NET 9 已经发布&#xff0c;您可能正在考虑更新您的 ASP.NET Core 应用程序。 我们将介绍更新应用程序所需的内容。从更新 Visual Studio 和下载 .NET SDK 到找出可能破坏应用程序的任何重大更改。 下载 .NET 9 SDK 这些是下载 .NET 9 SDK 所需的步骤。 更新 Visual Studi…

【Iot】前端串口serialport.js串口通信库快速入门(附经验总结)

前端串口serialport.js串口通信库快速入门(附经验总结) 一、serialport简介1.1 安装1.2 基本用法1.3 完整示例代码二、问题2.1 数据包被拆分(已解决)2.2 串口返回的多种数据,如何区分类别(待解决)公司项目需要开发一个windows客户端,提供串口modbusRTU数据读取、处理、显…

前端报错npm ERR cb() never called问题

环境使用node版本v14.21.3&#xff0c;npm版本6.14.18 1.问题描述 1.1使用npm install后报错 npm ERR! cb() never called!npm ERR! This is an error with npm itself. Please report this error at: npm ERR! ? ? <https://npm.community>npm ERR! A complete log…

【下】王树森《小红书推荐系统公开课》- 课程笔记(特征交叉、行为序列、重排/推荐系统多样性、物品冷启动、涨指标的方法)

写在前面 本文为王树森老师《小红书推荐系统公开课》的课程笔记 课程来源&#xff1a;ShusenWang的个人空间-ShusenWang个人主页-哔哩哔哩视频 (bilibili.com)课程资料&#xff1a;GitHub - wangshusen/RecommenderSystem 由于篇幅较长&#xff0c;分为【上】【下】两篇文章…

[C++]C++工具之对异常情况的处理(throw、catch、try)以及用命名空间避免同名冲突

一、C 异常处理&#x1f60a; 1.1 定义 C 中的异常处理用于应对程序运行中的异常情况&#xff08;如除零、数组越界等&#xff09;&#xff0c;通过 try-catch 机制捕获和处理错误&#xff0c;防止程序崩溃。 异常是程序运行时意外发生的事件&#xff0c;可以通过抛出&#xf…

Dynamics 365 CRM- 后端

Dynamics 365 CRM 后端插件语法示例 public IPluginExecutionContext context null;//上下文 public IOrganizationServiceFactory serviceFactory null;//组织服务工厂对象 public IOrganizationService service null;//Org服务对象//创建执行上下文 context (IPluginExe…

C语言——实现并求出两个数的最大公约数

问题描述&#xff1a;求出两个数的最大公约数 //求两个数的最大公约数 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<time.h>int main() {int a,b;printf("请您输入两个数 a 和 b\n");scanf…

采用qL-MPC技术进行小型固定翼无人机的路径跟随控制

来自论文"Predictive Path-Following Control for Fixed-Wing UAVs Using the qLMPC Framework in the Presence of Wind Disturbances" 控制架构 采用的是 ULTRA-Extra无人机&#xff0c;相关参数如下&#xff1a; 这里用于guidance law的无人机运动学模型为&#…

三维无人机航迹算法的目标函数如何确定

一、定义目标函数 在三维无人机航迹算法中,目标函数的确定通常基于具体的任务需求和飞行约束。以下是一个简单的例子,展示了如何为三维无人机航迹规划定义一个目标函数。 例子:最小化飞行时间和避障的三维无人机航迹规划 1.任务描述:无人机需要从起点飞到终点,同时避开一些…