Spring Boot集成OpenPDF和Freemarker实现PDF导出功能并附水印

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

Spring Boot 集成 OpenPDF 和 Freemarker 实现 PDF 导出功能

  • 前言
  • 概述
  • 实战开始
    • ❶ 项目初始化
    • ❷ 配置 Freemarker
    • ❸ 创建 HTML 模板
    • ❹ 基于HTML模版 PDF 生成逻辑
    • ❺ 基于后端编码形式生成
    • ❻ 创建 Controller
    • ❼ 测试和运行
  • 一点点建议
  • 总结

前言

本文对应代码下载地址:https://download.csdn.net/download/lhmyy521125/89590079 无需积分!无需积分!

在我们日常开发中,生成 PDF 文件是一项常见的需求。无论是生成单据、报表、发票还是其他文档,PDF 格式因其便捷的打印和跨平台支持而被广泛使用。本文将介绍如何在 Spring Boot 项目中使用 flying-saucer-pdfFreemarker 来实现 HTML 模板到 PDF 的导出功能

flying-saucer-pdf + html输出的单据效果:

在这里插入图片描述
OpenPDF后端编码形式输出的单据效果:

在这里插入图片描述


概述

Flying Saucere介绍
项目地址:https://github.com/flyingsaucerproject/flyingsaucer

Flying Saucer是一个纯Java库,用于使用CSS 2.1 / CSS 3呈现任意格式良好的XML(或XHTML),用于布局和格式化,输出到Swing面板,PDF和图像

使用文档:https://flyingsaucerproject.github.io/flyingsaucer/r8/guide/users-guide-R8.html

OpenPDF介绍
项目地址:https://github.com/LibrePDF/OpenPDF

OpenPDF是一个用于创建和编辑PDF文件的Java库,具有LGPL和MPL开源许可证。OpenPDF是iText的LGPL/MPL开源继承者,基于iText 4 svn标签的一些分支

不同版本的OpenPDF,它们需要不同版本的Java

  • 2.0.x分支需要Java 17或更高版本。
  • 1.4.x分支需要Java 11或更高版本。
  • 1.3.x分支需要Java 8或更高版本。

为什么要把这两个放在一起说?

如果大家有看了Flying SaucereGitHub上的介绍,你会发现 flying-saucer-pdf 实际上是依赖于OpenPDF
在这里插入图片描述
也就是说无论我们是要基于HTML模版来生成,还是采用后端编码的形式生成,我们都只需要引入 flying-saucer-pdf 依赖即可,比如博主文章开始的效果截图


实战开始

❶ 项目初始化

首先,创建一个新的 Spring Boot 项目,在在 pom.xml 文件中添加相关依赖

<dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Starter Freemarker --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!-- 实际上 flying-saucer-pdf 使用OpenPDF实现 --><dependency><groupId>org.xhtmlrenderer</groupId><artifactId>flying-saucer-pdf</artifactId><version>9.9.0</version></dependency>
</dependencies>

❷ 配置 Freemarker

application.yml 文件中添加 Freemarker 的基本配置

# freemarker配置 实际上也可以直接默认Springboot装配配置
# 更多是只需要修改模版后缀 和 模版路径
spring:freemarker:suffix: .ftlcharset: utf-8template-loader-path: classpath:/templates/expose-request-attributes: trueexpose-session-attributes: trueexpose-spring-macro-helpers: true

❸ 创建 HTML 模板

src/main/resources/templates 目录下创建一个 Freemarker 模板文件 template.ftl

<!DOCTYPE html>
<html>
<head><meta charset="utf-8" /><title>测试导出单据模版</title><link href="https://demo.ruoyi.vip/css/bootstrap.min.css?v=3.3.7" rel="stylesheet" type="text/css"/><link href="https://demo.ruoyi.vip/css/style.min.css?v=20210831" rel="stylesheet"/><link href="https://demo.ruoyi.vip/ruoyi/css/ry-ui.css?v=4.7.9" rel="stylesheet"/><style>@page {size: 210mm 297mm; /*设置纸张大小:A4(210mm 297mm)、A3(297mm 420mm) 横向则反过来*/margin: 0.5in;@bottom-center{content:"版权所有";font-family: SimSun;font-size: 12px;color:red;};@top-center { content: element(header) };@bottom-right{content:"第" counter(page) "页  共 " counter(pages) "页";font-family: SimSun;font-size: 12px;color:#000;};}body{font-family: SimSun;}img {width: 50px;}</style>
</head><body class="gray-bg">
<div><div class="row"><div class="col-sm-12"><div class="ibox-content"><div class="row"><div class="col-sm-6 text-right"><h4>单据编号:</h4><h4 class="text-navy">H+-000567F7-00</h4><address><strong>${companyName}</strong><br/>${address}<br/><abbr title="Phone">总机:</abbr> ${tel}</address><p><span><strong>日期:</strong> 2014-11-11</span></p></div></div><div class="table-responsive m-t"><table class="invoice-table" style="width: 100%; line-height: 60px"><thead><tr><th>图片</th><th>清单</th><th>数量</th><th>单价</th><th>总价</th></tr></thead><tbody><#if products?? && (products?size> 0)><#list products as p><tr><td><img src="${p.productImg}" /></td><td><strong>${p.productName}</strong></td><td>${p.quantity}</td><td>&yen;${p.price}</td><td>&yen;${p.total}</td></tr></#list></#if></tbody></table></div><!-- /table-responsive --><table class="invoice-total" style="width: 100%; line-height: 30px"><tbody><tr><td><strong>总价:</strong></td><td>&yen;${total}</td></tr><tr><td><strong>税:</strong></td><td>&yen;${tax}</td></tr><tr><td><strong>总计</strong></td><td>&yen;${aggregate}</td></tr></tbody></table><div class="well m-t"><strong>注意:</strong> 请保存好单据</div></div></div></div>
</div>
</body>
</html>

❹ 基于HTML模版 PDF 生成逻辑

创建一个 PdfService 类,用于生成 PDF 文件

package com.toher.project.openpdf;import com.lowagie.text.*;
import com.lowagie.text.Font;
import com.lowagie.text.pdf.*;
import freemarker.cache.ClassTemplateLoader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.util.Map;@Service
public class PdfService {@Autowiredprivate FreeMarkerConfigurer freeMarkerConfigurer;public byte[] generatePdf(Map<String, Object> data) throws Exception {// 生成HTMLString html = FreeMarkerTemplateUtils.processTemplateIntoString(freeMarkerConfigurer.getConfiguration().getTemplate("template.ftl"), data);ByteArrayOutputStream out = new ByteArrayOutputStream();ITextRenderer renderer = new ITextRenderer();//加载/resource/static/font的字体ClassTemplateLoader classTemplateLoader = new ClassTemplateLoader(PdfService.class, "/static/font");ITextFontResolver fontResolver = (ITextFontResolver)renderer.getSharedContext().getFontResolver();String fontPath = classTemplateLoader.getBasePackagePath() + "simsun.ttc";fontResolver.addFont(fontPath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);renderer.setDocumentFromString(html);renderer.layout();renderer.createPDF(out,false);PdfWriter writer = renderer.getWriter();//设置水印BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);Font docFont = new Font(bfChinese, 10, Font.UNDEFINED, Color.BLACK);writer.setPageEvent(new PdfPageEventHelper() {@Overridepublic void onEndPage(PdfWriter writer, Document document) {PdfContentByte waterMar = writer.getDirectContentUnder();String text = "Micro麦可乐";addTextFullWaterMark(waterMar, text, bfChinese);}});renderer.finishPDF();return out.toByteArray();}public static void addTextFullWaterMark(PdfContentByte waterMar, String text, BaseFont bfChinese) {waterMar.beginText();PdfGState gs = new PdfGState();// 设置填充字体不透明度为0.2fgs.setFillOpacity(0.1f);waterMar.setFontAndSize(bfChinese, 40);// 设置透明度waterMar.setGState(gs);// 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度for (int x = 0; x <= 700; x += 200) {for (int y = 0; y <= 800; y += 200) {waterMar.showTextAligned(Element.ALIGN_RIGHT, text, x, y, 35);}}// 设置水印颜色waterMar.setColorFill(Color.GRAY);//结束设置waterMar.endText();waterMar.stroke();}
}

❺ 基于后端编码形式生成

有些项目不一定是采用html模版形式生成PDF,这里博主就简单演示一下,使用OpenPDF后端编码形式生成PDF

package com.toher.project.openpdf;import com.lowagie.text.Font;
import com.lowagie.text.*;
import com.lowagie.text.Image;
import com.lowagie.text.alignment.HorizontalAlignment;
import com.lowagie.text.alignment.VerticalAlignment;
import com.lowagie.text.html.simpleparser.HTMLWorker;
import com.lowagie.text.pdf.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.xhtmlrenderer.pdf.ITextRenderer;import java.awt.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.Map;@Service
public class OpenPdfService {@Autowiredprivate FreeMarkerConfigurer freeMarkerConfigurer;public byte[] generatePdf(Map<String, Object> data) throws Exception {ByteArrayOutputStream out = new ByteArrayOutputStream();// 创建PDF文档Document document = new Document();PdfWriter writer = PdfWriter.getInstance(document, out);//如果需要定义字体,将自己的字体放在 resources/fonts目录下//BaseFont font = BaseFont.createFont("fonts/Viaoda_Libre/ViaodaLibre-Regular.ttf", BaseFont.IDENTITY_H, false);BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);Font docFont = new Font(bfChinese, 10, Font.UNDEFINED, Color.BLACK);//设置水印writer.setPageEvent(new PdfPageEventHelper() {@Overridepublic void onEndPage(PdfWriter writer, Document document) {PdfContentByte waterMar = writer.getDirectContentUnder();String text = "Micro麦可乐";addTextFullWaterMark(waterMar, text, bfChinese);}});// 设置边距document.setMargins(20, 20, 20, 20);// 打开文档document.open();/*** 01 表格演示*/String[] tableTitle = new String[]{"清单", "数量", "单价", "总价"};Table table = new Table(tableTitle.length);table.setWidths(new float[]{70, 10, 10, 10});// 设置表格前的间距table.setSpacing(0);// 设置表格在页面中所占的宽度百分比table.setWidth(100);table.setBorder(0);//模拟5行表格数据for (int row = 0; row < 5; row++) {for (int i = 0; i < tableTitle.length; i++) {Chunk chunk;if (row == 0) {chunk = new Chunk(tableTitle[i], docFont);} else {chunk = new Chunk(row + "行 模拟数据" + i, docFont);}// 建立单元格Cell cell = new Cell(chunk);// 设置水平对齐cell.setHorizontalAlignment(HorizontalAlignment.CENTER);// 设置垂直对齐cell.setVerticalAlignment(VerticalAlignment.CENTER);table.addCell(cell);}}document.add(table);/*** 02 写入图片*/byte[] byteArray = new byte[0];InputStream inputStream = this.getClass().getResourceAsStream("/static/img/test.png");if (inputStream != null) {byteArray = new byte[inputStream.available()];inputStream.read(byteArray);}Image image = Image.getInstance(byteArray);// 图片进行缩放image.scaleAbsolute(200, 200);document.add(image);/*** 03 写入html内容*/HTMLWorker htmlWorker = new HTMLWorker(document);String html = "<p style='color: crimson'>Hello, micro</p>";htmlWorker.parse(new StringReader(html);// 关闭文档document.close();return out.toByteArray();}public static void addTextFullWaterMark(PdfContentByte waterMar, String text, BaseFont bfChinese) {waterMar.beginText();PdfGState gs = new PdfGState();// 设置填充字体不透明度为0.2fgs.setFillOpacity(0.2f);waterMar.setFontAndSize(bfChinese, 40);// 设置透明度waterMar.setGState(gs);// 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度for (int x = 0; x <= 700; x += 200) {for (int y = 0; y <= 800; y += 200) {waterMar.showTextAligned(Element.ALIGN_RIGHT, text, x, y, 35);}}// 设置水印颜色waterMar.setColorFill(Color.GRAY);//结束设置waterMar.endText();waterMar.stroke();}
}

❻ 创建 Controller

创建一个 PdfController 类,用于处理生成 PDF 的请求

package com.toher.project.openpdf;import com.lowagie.text.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;@RestController
public class PdfController {@Autowiredprivate PdfService pdfService;@Autowiredprivate OpenPdfService openPdfService;/*** 采用flying-saucer-pdf html转pdf* @return*/@GetMapping("/generate-pdf")public ResponseEntity<byte[]> generatePdf() {// 模拟数据库查询结果Map<String, Object> data = new HashMap<>();data.put("img", "https://demo.ruoyi.vip/img/profile.jpg");data.put("companyName", "阿里巴巴集团");data.put("address", "中国杭州市华星路99号东部软件园创业大厦6层(310099)");data.put("tel", "(+86) 571-8502-2088");data.put("creatTime", "2024-07-27");data.put("total", 1026.00);data.put("tax", 235.98);data.put("aggregate", 1261.98);List<ProductVo> products = new ArrayList<>();ProductVo productVo = new ProductVo();productVo.setProductImg("https://demo.ruoyi.vip/img/profile.jpg");productVo.setProductName("尚都比拉2013冬装新款女装 韩版修身呢子大衣 秋冬气质羊毛呢外套");productVo.setQuantity(1);productVo.setPrice(new BigDecimal("26"));productVo.setTotal(productVo.getPrice().multiply(productVo.getPrice()));products.add(productVo);ProductVo productVo1 = new ProductVo();productVo1.setProductImg("https://demo.ruoyi.vip/img/profile.jpg");productVo1.setProductName("11*11夏娜 新款斗篷毛呢外套 女秋冬呢子大衣 韩版大码宽松呢大衣");productVo1.setQuantity(2);productVo1.setPrice(new BigDecimal("80"));productVo1.setTotal(productVo.getPrice().multiply(productVo.getPrice()));products.add(productVo1);ProductVo productVo2 = new ProductVo();productVo2.setProductImg("https://demo.ruoyi.vip/img/profile.jpg");productVo2.setProductName("2013秋装 新款女装韩版学生秋冬加厚加绒保暖开衫卫衣 百搭女外套");productVo2.setQuantity(3);productVo2.setPrice(new BigDecimal("280"));productVo2.setTotal(productVo.getPrice().multiply(productVo.getPrice()));products.add(productVo2);data.put("products", products);byte[] pdfBytes = null;try {pdfBytes = pdfService.generatePdf(data);} catch (Exception e) {e.printStackTrace();}HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_PDF);headers.setContentDispositionFormData("attachment", "example.pdf");return ResponseEntity.ok().headers(headers).body(pdfBytes);}/*** 采用openpdf 生成pdf* @return*/@GetMapping("/generate-openpdf")public ResponseEntity<byte[]> generateOpenPdf() {byte[] pdfBytes = null;try {pdfBytes = openPdfService.generatePdf();} catch (Exception e) {e.printStackTrace();}HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_PDF);headers.setContentDispositionFormData("attachment", "example.pdf");return ResponseEntity.ok().headers(headers).body(pdfBytes);}
}

❼ 测试和运行

启动 Spring Boot 应用程序,然后在浏览器中访问以下 URL:

#Html模版形式生成
http://localhost:8080/generate-pdf #后端编码形式生成
http://localhost:8080/generate-openpdf

浏览器将会下载生成的 PDF 文件 example.pdf,其中包含动态生成的内容,并且附加了水印

一点点建议

博主的代码中仅仅是为了让大家能快速熟悉,一些细节问题还需要大家在实际项目中进行优化调整

  • 模板设计:在设计 Freemarker 模板时,可以使用 CSS 来控制 PDF 的样式,使生成的 PDF 更加美观。
  • 水印设置:通过 CSS 设置水印样式,可以根据需求调整水印的位置、透明度、大小等属性。
  • 错误处理:在实际项目中,需增加错误处理和日志记录,确保在生成 PDF 过程中出现问题时能够及时发现并处理。
  • 性能优化:对于大批量生成 PDF 的场景,可以考虑使用异步处理或批处理机制,提高系统的处理能力。

总结

本文介绍了如何在 Spring Boot 项目中使用 Flying SaucerFreemarker 实现 PDF 导出功能,并附加水印,并也演示了直接在后端编码形式生成PDF
通过 Freemarker 模板引擎生成 HTML,再使用 Flying SaucerHTML 转换为 PDF,此方法灵活且易于扩展,可以根据业务需求生成复杂的 PDF 文档

如果本文对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论!


在这里插入图片描述

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

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

相关文章

关于@JsonSerialize序列化与@JsonDeserialize反序列化注解的使用(密码加密与解密举例)

注&#xff1a;另一种方式参考 关于TableField中TypeHandler属性&#xff0c;自定义的类型处理器的使用&#xff08;密码加密与解密举例&#xff09;http://t.csdnimg.cn/NZy4G 1.简介 1.1 序列化与反序列化 学习注解之前&#xff0c;我们可以先了解一下什么是序列化与反序列…

遵义网站建设安全性保证

随着互联网的发展和普及&#xff0c;网站的建设成为了一个重要的工作&#xff0c;也是企业宣传的重要渠道。然而&#xff0c;随之而来的安全问题也是不容忽视的。为了保证遵义网站建设的安全性&#xff0c;我们需要采取一系列的措施。 首先&#xff0c;要选择合适的服务器和主机…

【Unity2D 2022:Data】读取csv格式文件的数据

一、创建csv文件 1. 打开Excel&#xff0c;创建xlsx格式文件 2. 编辑卡牌数据&#xff1a;这里共写了两类卡牌&#xff0c;第一类是灵物卡&#xff0c;具有编号、卡名、生命、攻击四个属性&#xff1b;第二类是法术卡&#xff0c;具有编号、卡名、效果三个属性。每类卡的第一…

(39)智能电池

文章目录 前言 1 通过任务规划器进行设置 2 补充信息 3 限制条件 4 参数说明 前言 虽然还不是很普遍&#xff0c;但智能电池更容易从飞行器上安装和拆卸&#xff0c;并且能够提供更多关于电池状态的信息&#xff0c;包括容量、单个电池电压、温度等。 ArduPilot 支持几种…

开发环境搭建——Node.js

在启动前端项目的时候我们通常会用到Node.js&#xff0c;下面是对Node.js的下载安装以及配置的讲解 一、Node.js的安装 1.1、通过Node.js官网下载&#xff1a;Node.js — Run JavaScript Everywhere 下载后双击.msi安装文件后一直点击下一步即可 1.2、配置node 1.2.1、查看…

js 替换json中的转义字符 \

例如有以下字符串 "\"{\\\"account\\\":\\\"66\\\",\\\"name\\\":\\\"66\\\"}\"" 想得到如下字符串 {"account":"66","name":"66"} 执行替换字符串 "\"{…

组队学习——决策树(以泰坦尼克号公共数据集为例)

本次我们挑战的数据集为泰坦尼克号公共数据集&#xff0c;为了降低难度&#xff0c;我们在原有数据集的基础上进行了优化&#xff0c;具体数据集介绍如下&#xff1a; 在这里也介绍一下数据的含义吧 数据介绍&#xff1a; Survived&#xff1a;是否存活&#xff08;label&#…

paraFoam 运行 报错 usr/lib/x86_64-linux-gnu/libQt5Core.so 已解决

在日常项目开发中。使用ubuntu 视图开发的时候。报错 缺少 libQt5Core 核心组件&#xff01; whereis libQt5Core.so.5sudo strip --remove-section.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 完美解决&#xff0c;并且能正常打开&#xff0c;前提是&#xff0c…

【python】python生活管理费系统(源码+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

加载chatglm3模型时出现ValueError: too many values to unpack (expected 2)的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

基于Libero的工程创建

基于Libero的工程创建 第一步&#xff1a;双击进入到工程界面&#xff0c;编写项目详细信息。 Project Name&#xff1a;标识您的项目名称。不要使用空格或保留的Verilog或VHDL关键字。 Project Location&#xff1a;在磁盘上标识您的项目位置。 Description&#xff1a;关于…

Linux系统下安装MySQL

前言&#xff1a; 本篇教程是使用Centos8来进行安装部署&#xff0c;如果使用的Linux系统发行版不同安装部署过程中可能会有差异&#xff0c;相同环境下可以跟着操作流程进行部署。本篇文章的主要目的是为了学习分享使用如有疑问欢迎提出并共同讨论。 1、安装前的准备工作 移除…

Power App学习笔记以及基础项目管理demo

Power App学习笔记以及基础项目管理demo 最近学习了一点Power App&#xff0c;感觉挺有意思。配置式组件开发。浅浅记录一下自己实现的项目管理系统&#xff08;即Excel数据的增删改查&#xff09;关于函数的一点皮毛认识。 效果图 筛选数据 编辑 详情 数据源 PowerApp 网…

SpringCloud - Nacos配置中心、命名空间

一、 Nacos配置中心 1、在gulimall-common公共模块添加依赖 <!--服务注册发现--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--…

为RTEMS Raspberrypi4 BSP添加SPI支持

为RTEMS Raspberrypi4 BSP添加SPI支持 主要参考了dev/bsps/shared/dev/spi/cadence-spi.c RTEMS 使用了基于linux的SPI框架&#xff0c;SPI总线驱动已经在内核中实现。在这个项目中我需要实习的是 RPI4的SPI主机控制器驱动 SPI在RTEMS中的实现如图&#xff1a; 首先需要将S…

day06 项目实践:router,axios

vue组件的生命周期钩子 今天几乎没有讲什么新内容&#xff0c;就是一起做项目&#xff0c;只有一个小小的知识点&#xff0c;就是关于vue组件的生命周期钩子&#xff0c;其中最重要的四个函数—— beforeCreate()&#xff1a;组件创建之间执行 created()&#xff1a;组件创建…

[Meachines] [Easy] Admirer Adminer远程Mysql反向+Python三方库函数劫持权限提升

信息收集 IP AddressOpening Ports10.10.10.187TCP:21,22,80 $ nmap -p- 10.10.10.187 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 22/tcp open ssh OpenSSH 7.4p1 Debian 10deb9u7 (protocol 2.0) | ssh-hostkey: | …

前端三大主流框架对比

在现代前端开发中&#xff0c;React、Vue和Angular是三大流行的框架/库。它们各自有独特的优缺点&#xff0c;适用于不同的开发需求和项目规模。下面是对这三者的详细比较&#xff1a; 一、 React 简介&#xff1a; 由Facebook开发和维护&#xff0c;是一个用于构建用户界面…

yolov8标注细胞、识别边缘、计算面积、灰度值计算

一、数据标注 1. 使用labelme软件标注每个细胞的边界信息&#xff0c;标注结果为JSON格式 2. JSON格式转yolo支持的txt格式 import json import os import glob import os.path as osp此函数用来将labelme软件标注好的数据集转换为yolov5_7.0sege中使用的数据集:param jsonfi…

【vue前端项目实战案例】之Vue仿饿了么App

本文将介绍一款仿“饿了么”商家页面的App。该案例是基于 Vue2.0 Vue Router webpack ES6 等技术栈实现的一款外卖类App&#xff0c;适合初学者进行学习。 项目源码下载链接在文章末尾 1 项目概述 该项目是一款仿“饿了么”商家页面的外卖类App&#xff0c;主要有以下功能…