springboot集成thymeleaf实战

news/2024/9/20 7:28:16/ 标签: spring boot, 后端, java

引言

笔者最近接到一个打印标签的需求,由于之前没有做过类似的功能,所以这也是一次学习探索的机会了,打印的效果图如下:
在这里插入图片描述
这个最终的打印是放在58mm*58mm的小标签纸上,条形码就是下面的35165165qweqweqe序列号生成的,也是图片形式。序列号应该放在条形码的正下方居中位置的,但是由于笔者前端技术有点拉跨,碰到样式啥的就头疼,这也是尽力后的效果了。下面看集成过程吧。

一、引入pom相关依赖包

笔者的环境是JDK17,pom相关版本如下,具体用什么版本不固定,不报错就行。

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.1</version></dependency><dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.4.1</version></dependency><dependency><groupId>ognl</groupId><artifactId>ognl</artifactId><version>3.4.3</version></dependency><!-- Flying Saucer --><dependency><groupId>org.xhtmlrenderer</groupId><artifactId>flying-saucer-pdf</artifactId><version>9.1.20</version></dependency><!--itext--><dependency><groupId>com.lowagie</groupId><artifactId>itext</artifactId><version>2.1.7</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency>

二、条形码工具类

java">package com.hulei.thymeleafproject;import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.oned.Code128Writer;
import org.apache.commons.lang3.StringUtils;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;/*** @author hulei* @Date 2024/7/26 14:15* @Description: 条形码工具类**/
public class BarCodeUtils {/*** 默认图片宽度*/private static final int DEFAULT_PICTURE_WIDTH = 400;/*** 默认图片高度*/private static final int DEFAULT_PICTURE_HEIGHT = 200;/*** 默认条形码宽度*/private static final int DEFAULT_BAR_CODE_WIDTH = 300;/*** 默认条形码高度*/private static final int DEFAULT_BAR_CODE_HEIGHT = 30;/*** 默认字体大小*/private static final int DEFAULT_FONT_SIZE = 15;/*** 图片格式*/private static final String FORMAT = "png";/*** 字符集*/private static final String CHARSET = "utf-8";/*** 设置 条形码参数*/private static final Map<EncodeHintType, Object> hints = new HashMap<>();static {hints.put(EncodeHintType.CHARACTER_SET, "utf-8");}/*** 获取条形码图片** @param codeValue 条形码内容* @return 条形码图片*/public static BufferedImage getBarCodeImage(String codeValue) {return getBarCodeImage(codeValue, DEFAULT_BAR_CODE_WIDTH, DEFAULT_BAR_CODE_HEIGHT);}/*** 获取条形码图片** @param codeValue 条形码内容* @param width     宽度* @param height    高度* @return 条形码图片*/public static BufferedImage getBarCodeImage(String codeValue, int width, int height) {// CODE_128是最常用的条形码格式return getBarCodeImage(codeValue, width, height, BarcodeFormat.CODE_128);}/*** 获取条形码图片** @param codeValue     条形码内容* @param width         宽度* @param height        高度* @param barcodeFormat 条形码编码格式* @return 条形码图片*/public static BufferedImage getBarCodeImage(String codeValue, int width, int height, BarcodeFormat barcodeFormat) {Code128Writer writer = switch (barcodeFormat) {case CODE_128 ->// 最常见的条形码,但是不支持中文new Code128Writer();case PDF_417 ->// 支持中文的条形码格式new Code128Writer();// 如果使用到其他格式,可以在这里添加default -> new Code128Writer();};// 编码内容, 编码类型, 宽度, 高度, 设置参数BitMatrix bitMatrix;bitMatrix = writer.encode(codeValue, barcodeFormat, width, height, hints);return MatrixToImageWriter.toBufferedImage(bitMatrix);}/*** 获取条形码** @param codeValue 条形码内容* @param bottomStr 底部文字*/public static BufferedImage getBarCodeWithWords(String codeValue, String bottomStr) {return getBarCodeWithWords(codeValue, bottomStr, "", "", "");}/*** 获取条形码* @param codeValue   条形码内容* @param bottomStr   底部文字* @param topLeftStr  左上角文字* @param topRightStr 右上角文字*/public static BufferedImage getBarCodeWithWords(String codeValue,String bottomStr,String bottomStr2,String topLeftStr,String topRightStr) {return getCodeWithWords(getBarCodeImage(codeValue),bottomStr,bottomStr2,topLeftStr,topRightStr,DEFAULT_PICTURE_WIDTH,DEFAULT_PICTURE_HEIGHT,0,-20,0,0,0,0,DEFAULT_FONT_SIZE);}/*** 获取条形码** @param codeImage       条形码图片* @param firstBottomStr  底部文字首行* @param secondBottomStr 底部文字次行* @param topLeftStr      左上角文字* @param topRightStr     右上角文字* @param pictureWidth    图片宽度* @param pictureHeight   图片高度* @param codeOffsetX     条形码宽度* @param codeOffsetY     条形码高度* @param topLeftOffsetX  左上角文字X轴偏移量* @param topLeftOffsetY  左上角文字Y轴偏移量* @param topRightOffsetX 右上角文字X轴偏移量* @param topRightOffsetY 右上角文字Y轴偏移量* @param fontSize        字体大小* @return 条形码图片*/public static BufferedImage getCodeWithWords(BufferedImage codeImage,String firstBottomStr,String secondBottomStr,String topLeftStr,String topRightStr,int pictureWidth,int pictureHeight,int codeOffsetX,int codeOffsetY,int topLeftOffsetX,int topLeftOffsetY,int topRightOffsetX,int topRightOffsetY,int fontSize) {BufferedImage picImage = new BufferedImage(pictureWidth, pictureHeight, BufferedImage.TYPE_INT_RGB);Graphics2D g2d = picImage.createGraphics();// 抗锯齿setGraphics2D(g2d);// 设置白色setColorWhite(g2d, picImage.getWidth(), picImage.getHeight());// 条形码默认居中显示int codeStartX = (pictureWidth - codeImage.getWidth()) / 2 + codeOffsetX;int codeStartY = (pictureHeight - codeImage.getHeight()) / 2 + codeOffsetY;// 画条形码到新的面板g2d.drawImage(codeImage, codeStartX, codeStartY, codeImage.getWidth(), codeImage.getHeight(), null);// 画文字到新的面板g2d.setColor(Color.BLACK);// 字体、字型、字号g2d.setFont(new Font("微软雅黑", Font.PLAIN, fontSize));// 文字与条形码之间的间隔int wordAndCodeSpacing1 = 0;if (StringUtils.isNotEmpty(firstBottomStr)) {// 文字长度int strWidth = g2d.getFontMetrics().stringWidth(firstBottomStr);// 文字X轴开始坐标,这里是居中int strStartX = codeStartX + (codeImage.getWidth() - strWidth) / 2;// 文字Y轴开始坐标int strStartY = codeStartY + codeImage.getHeight() + fontSize + wordAndCodeSpacing1;// 画文字g2d.drawString(firstBottomStr, strStartX, strStartY);}// 文字与条形码之间的间隔int wordAndCodeSpacing2 = 30;if (StringUtils.isNotEmpty(secondBottomStr)) {// 文字长度int strWidth = g2d.getFontMetrics().stringWidth(secondBottomStr);// 文字X轴开始坐标,这里是居中int strStartX = codeStartX + (codeImage.getWidth() - strWidth) / 2;// 文字Y轴开始坐标int strStartY = codeStartY + codeImage.getHeight() + fontSize + wordAndCodeSpacing2;// 画文字g2d.drawString(secondBottomStr, strStartX, strStartY);}if (StringUtils.isNotEmpty(topLeftStr)) {// 文字长度int strWidth = g2d.getFontMetrics().stringWidth(topLeftStr);// 文字X轴开始坐标int strStartX = codeStartX + topLeftOffsetX;// 文字Y轴开始坐标int strStartY = codeStartY + topLeftOffsetY - wordAndCodeSpacing1;// 画文字g2d.drawString(topLeftStr, strStartX, strStartY);}if (StringUtils.isNotEmpty(topRightStr)) {// 文字长度int strWidth = g2d.getFontMetrics().stringWidth(topRightStr);// 文字X轴开始坐标,这里是居中int strStartX = codeStartX + codeImage.getWidth() - strWidth + topRightOffsetX;// 文字Y轴开始坐标int strStartY = codeStartY + topRightOffsetY - wordAndCodeSpacing1;// 画文字g2d.drawString(topRightStr, strStartX, strStartY);}g2d.dispose();picImage.flush();return picImage;}/*** 设置 Graphics2D 属性  (抗锯齿)** @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制*/private static void setGraphics2D(Graphics2D g2d) {g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT);Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);g2d.setStroke(s);}/*** 设置背景为白色** @param g2d Graphics2D提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制*/private static void setColorWhite(Graphics2D g2d, int width, int height) {g2d.setColor(Color.WHITE);//填充整个屏幕g2d.fillRect(0, 0, width, height);//设置笔刷g2d.setColor(Color.BLACK);}/*** 将 BufferedImage 转为 base64*/public static String bufferedImage2Base64(BufferedImage image) throws IOException {// 输出流ByteArrayOutputStream stream = new ByteArrayOutputStream();ImageIO.write(image, FORMAT, stream);java.util.Base64.Encoder encoder = java.util.Base64.getEncoder();String imgBase64 = new String(encoder.encode(stream.toByteArray()), CHARSET);imgBase64 = "data:image/" + FORMAT + ";base64," + imgBase64;return imgBase64;}}

这个工具类中,默认生成的条形码图片格式是png,当然可以自己修改格式。

三、thymeleaf画模板

这个就是打印模板了,thymeleaf和freemarker一样都是模板引擎,freemarker模板语法更简单些。如果需要简单的变量替换和循环,FreeMarker可能是更好的选择。如果需要更丰富的模板功能和动态内容处理,Thymeleaf可能更适合。笔者这里选择的是thymeleaf。

<!DOCTYPE html>
<html lang="zh-CN">
<head><title>维修库商品打印标签模板</title><meta charset="UTF-8"></meta><style>        body, html {margin: 0;padding: 0;width: 70mm;height: 70mm;font-family: 'SimSun', sans-serif; /* 防止生成的PDF中文不显示 */}h1 {text-align: center;font-size: 12px;line-height: 1.5;}p {font-size: 12px;margin: 3px 0;}.device-code {display: flex; /* 使用Flexbox布局 */align-items: center; /* 垂直居中对齐 */}.sn-container {display: inline-flex; /* 内联Flexbox容器 */align-items: center; /* 垂直居中对齐 */margin-left: 2px; /* 与“设备码:”之间的间距 */}.sn-image {width: auto; /* 图片宽度自适应 */}.sn-text {margin-top: 5px; /* 文本与图片之间的间距 */text-align: center; /* 文字居中 */}img {vertical-align: middle;display: inline-block;}</style>
</head>
<body>
<div><h1><img th:src="${zlbcImage}" alt="Image" style="height:30px;"></img>智链泊车</h1><p th:text="${createTime != null ? '入库日期:'+ createTime : '入库日期:未知'}"></p><p th:text="${materialName != null ? '名&nbsp;&nbsp;&nbsp;&nbsp;称:'+ materialName : '名称:未知'}"></p><p th:text="${supplierName != null ? '客&nbsp;&nbsp;&nbsp;&nbsp;户:'+ supplierName : '客户:未知'}"></p><p class="device-code">&nbsp;&nbsp;码:<span class="sn-container"><img class="sn-image" th:src="${sequencesNumberImage}" alt="Image"/><div class="sn-text" th:text="${sequencesNumber}">${sequencesNumber}</div></span></p>
</div>
</body>
</html>

这个模板里面的变量赋值时比较简单的,主要是有两个图片的变量zlbcImagesequencesNumberImage,一个是智慧停车前面的原型小图标,一个就是条形码是,在赋值时是需要把图片读成BufferedImage,再把BufferedImage使用base64编码一下。

另外一个重要的点是:font-family: ‘SimSun’, sans-serif;
这个属性必须加上,否则后面把html转成PDF时,中文会不显示。

四、字体准备simsun.ttc

这个字体是因为,我要把html转成一个PDF,中间转换需要一些字体,并且支持中文,网上搜索了下,选择了simsun.ttc这个字体,同时我在html上也指定了这个字体。网上下载这个字体资源库后,放在如下位置,以便程序中加载使用。
在这里插入图片描述

五、测试代码

java">package com.hulei.thymeleafproject;import com.lowagie.text.pdf.BaseFont;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;/*** @author hulei* @date 2024/7/27 9:26*/@RestController
public class TestController {@Resourceprivate TemplateEngine templateEngineBySelf;@PostMapping("/printSNLabel")public void test(@RequestBody List<PrintSNLabelReqDTO> list) {list.forEach(loop -> {Map<String, Object> map = new HashMap<>();map.put("createTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));map.put("materialName", loop.getMaterialName());map.put("supplierName", loop.getSupplierName());//设备码图片二进制字节流BufferedImage sequencesNumberImage = BarCodeUtils.getBarCodeImage(loop.getSequencesNumber(), 100, 50);this.storeImage(sequencesNumberImage, "E:/111.png");try {String base64Image = BarCodeUtils.bufferedImage2Base64(sequencesNumberImage);System.out.println("base64Image: " + base64Image);map.put("sequencesNumberImage", base64Image);} catch (IOException e) {throw new RuntimeException(e);}map.put("sequencesNumber", loop.getSequencesNumber());try {ClassLoader classLoader = Thread.currentThread().getContextClassLoader();String symbolImagePath = "images/zlbcImage.png";InputStream inputStream = classLoader.getResourceAsStream(symbolImagePath);assert inputStream != null;BufferedImage zlbcImageBufferedImage = ImageIO.read(inputStream);this.storeImage(zlbcImageBufferedImage, "E:/222.png");String zlbcImage = BarCodeUtils.bufferedImage2Base64(zlbcImageBufferedImage);System.out.println("zlbcImage: " + zlbcImage);map.put("zlbcImage", zlbcImage);} catch (IOException e) {throw new RuntimeException(e);}try {generateSNPicture(map);} catch (IOException e) {throw new RuntimeException(e);}});}private void generateSNPicture(Map<String,Object> map) throws IOException {// 填充模板数据Context context = new Context();context.setVariable("createTime", map.get("createTime"));context.setVariable("materialName", map.get("materialName"));context.setVariable("supplierName", map.get("supplierName"));context.setVariable("sequencesNumberImage", map.get("sequencesNumberImage"));context.setVariable("sequencesNumber", map.get("sequencesNumber"));context.setVariable("zlbcImage", map.get("zlbcImage"));String htmlContent = templateEngineBySelf.process("printTemplate", context);System.out.println(htmlContent);htmlToPdf(htmlContent);}private void htmlToPdf(String htmlContent){try {//创建PDf文件ITextRenderer renderer = new ITextRenderer();//获取使用的字体数据(由于对中文字体显示可能会不支持,所以需要主动添加字体数据设置。)ITextFontResolver fontResolver = renderer.getFontResolver();fontResolver.addFont("templates/fonts/simsun.ttc",BaseFont.IDENTITY_H, BaseFont.EMBEDDED);//设置文件名称String sDate = new SimpleDateFormat("yyyyMMdd").format(new Date());String sTime = new SimpleDateFormat("HHmmssSSS").format(new Date());// 生成临时文件Path tempPdfPath = Files.createTempFile("temp_pdf_"+sDate+sTime, ".pdf");String pdfFilePath = tempPdfPath.toAbsolutePath().toString();// 将html生成文档renderer.setDocumentFromString(htmlContent);renderer.layout();OutputStream os = new FileOutputStream(pdfFilePath);// 将文档写入到输出流中renderer.createPDF(os);// 关闭流os.close();//把临时生成的文件转移到E盘,这里可以根据个人需求选在把临时文件上传到文件服务器System.out.println("pdfFilePath: "+pdfFilePath);File tempPdfFile = tempPdfPath.toFile();System.out.println("tempPdfFileName: "+tempPdfFile.getName());// 复制文件到E盘try {Path targetPath = Paths.get("E:", tempPdfFile.getName()); // 目标路径Files.copy(tempPdfPath, targetPath);System.out.println("文件已复制到 E 盘");} catch (Exception e) {System.err.println("复制文件时发生错误: " + e.getMessage());}//删除临时生成的本地PDF文件Files.delete(tempPdfPath);} catch (Exception e) {System.out.println("生成pdf文件失败");throw new RuntimeException(e);}}private void storeImage(BufferedImage image, String filePath){try {// 指定输出文件路径和格式File outputFile = new File(filePath);// 使用 ImageIO.write 方法将图片写入磁盘boolean isWritten = ImageIO.write(image, "png", outputFile);if (isWritten) {System.out.println("图片已成功保存到磁盘.");} else {System.out.println("图片保存失败.");}} catch (IOException e) {System.err.println("保存图片时发生错误: " + e.getMessage());}}}

这里为了展示代码,没有分层了,全都放在了controller层。主要分为三块:加载html模板,变量赋值,html转pdf

转成pdf后的效果如下:

在这里插入图片描述

Apifox测试工具,测试数据如下,注意json是数组形式,因为后端controller接收的是List
在这里插入图片描述

整个代码我已上传到gitee:gitee仓库地址


http://www.ppmy.cn/news/1504238.html

相关文章

光伏气象仿真系统有什么优势?

光伏气象仿真系统作为这一领域的核心工具&#xff0c;凭借其独特的优势&#xff0c;正逐步成为行业标配。本文将围绕数据可靠性、功能齐全性、海外布局支持、系统开放性以及合作方式灵活性五个方面&#xff0c;深入探讨光伏气象仿真系统的显著优势。 1.数据可靠&#xff1a;权威…

Golang基础常识性知识面试中常见的六大陷阱及应对技巧

一、nil slice & empty slice 1、nil切片与空切片底层 nil切片&#xff1a;var nilSlice [] string nil slice的长度len和容量cap都是0 nil slicenil nil slice的pointer是nil 空切片&#xff1a;emptySlice0 : make([]int,0) empty slice的长度是0&#xff0c;容量是由…

信息安全工程师题

《中华人民共和国网络安全法》是为保障网络安全&#xff0c;维护网络空间主权和国家安全、社会公共利益&#xff0c;保护公民、法人和其他组织的合法权益&#xff0c;促进经济社会信息化健康发展制定。由全国人民代表大会常务委员会于2016年11月7日发布&#xff0c;自2017年6月…

Spring Boot项目实现调用腾讯云进行人脸识别

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 背景 随着科技的不断发展&#xff0c;人脸识别技术已经成为了一种日益重要的身份验证和安全监控手段。腾讯云人脸识别功能便是其中之一&#xff0c;而Java语言又是现在最为常用且高效的编程语言之一。本篇论…

数据结构之多维数组的存储

一、多维数组的定义 多维数组是由n&#xff08;n≥1&#xff09;个相同数据类型的数据元素组成的有限序列&#xff0c;其中每个元素本身也可以是一个数组。 最常见的多维数组是二维数组&#xff0c;可以看作是一维数组的一维数组。类似地&#xff0c;三维数组可以看作是存储二…

C语言实现 -- 单链表

C语言实现 -- 单链表 1.顺序表经典算法1.1 移除元素1.2 合并两个有序数组 2.顺序表的问题及思考3.链表3.1 链表的概念及结构3.2 单链表的实现 4.链表的分类 讲链表之前&#xff0c;我们先看两个顺序表经典算法。 1.顺序表经典算法 1.1 移除元素 经典算法OJ题1&#xff1a;移除…

RabbitMQ 生产和消息

1. 安装RabbitMQ 编写docker-compose.yml文件 version: 3.8 services:rabbitmq:image: rabbitmq:managementcontainer_name: rabbitmq_containerports:- "5672:5672"- "15672:15672"volumes:- ./rabbitmq_data:/var/lib/rabbitmqenvironment:RABBITMQ_DE…

速度规划之:起点速度和终点速度不为零的非对称梯形速度规划

起点速度和终点速度不为零的非对称梯形速度规划 一、引言二、理论基础1. 梯形速度规划概述2.数学建模- 变量定义- 约束关系- 公式推导 三、计算过程1.只存在减速段2.只存在加速段3.存在加速段和减速段4.存在加速度段、匀速段和减速段 四、仿真实现五、优缺点优点缺点 六、总结 …

万顺汽车租赁推荐系统

1 项目介绍 1.1 摘要 随着汽车租赁市场的不断发展&#xff0c;为了提升用户体验和管理效率&#xff0c;开发了一套集管理员和用户功能于一体的汽车租赁平台系统。该系统旨在提供便捷的用户信息管理、车辆信息管理、租赁订单管理等功能&#xff0c;以满足管理员和用户的不同需…

CLIP论文详解

文章目录 前言一、CLIP理论1.CLIP思想2.模型结构 二、CLIP预训练1.数据集2.训练策略3.模型选择 三、Zero-Shot推理四、CLIP伪代码实现五、CLIP局限性总结 前言 CLIP这篇论文是OpenAI团队在2021年2月底提出的一篇论文&#xff0c;名字叫做《Learning Transferable Visual Models…

5.1-软件工程基础知识-软件工程概述

软件工程诞生原因 了解 早期的软件&#xff1a;主要是指采用个体工作方式实现的程序。第一次软件危机&#xff1a;20世纪60年代中期 典型表现有软件质量低下、项目无法如期完成、项目严重超支等因为软件而导致的重大事故时有发生。 软件工程的诞生&#xff1a;1968年在NATO会…

filebeat + logstash使用笔记

背景 本文中有2台主机&#xff1a; &#xff08;1&#xff09;1.1.1.1是OpenStack的nova节点&#xff0c;安装filebeat &#xff08;2&#xff09;1.1.1.2是logstash节点 在1.1.1.1上通过filebeat读取OpenStack的nova-compute组件日志&#xff08;/var/log/nova/nova-compute.…

每天一个数据分析题(四百六十七)- 因子分析

因子分析中因子旋转的方法有&#xff08;&#xff09; A. 方差最小正交旋转 B. 方差最大正交旋转 C. 斜交旋转 D. 相交旋转 数据分析认证考试介绍&#xff1a;点击进入 题目来源于CDA模拟题库 点击此处获取答案 数据分析专项练习题库 内容涵盖Python&#xff0c;SQL&a…

uniapp打开地图直接获取位置

uniapp官网文档 https://en.uniapp.dcloud.io/api/location/open-location.html <view class"map-content" click.stop"kilometer(item)"><view class"km">{{item.distance||0}}km</view></view>import map from ../../…

【Python特征工程系列】数值型数据缺失值处理方法总结(案例+源码)

这是我的第334篇原创文章。 一、引言 对于从事数据相关工作的小伙伴&#xff0c;面试的时候经常会被问到如何进行缺失值/异常值的处理&#xff0c;本文来梳理一下填补数值型缺失值的7种方法。 二、实现过程 准备数据 df pd.read_csv(data.csv) df.drop("id",axis…

fastDDS-gen编译

要编译 fastDDS-gen&#xff0c;你可以按照以下步骤进行&#xff1a; 克隆仓库&#xff1a; git clone --recursive https://github.com/eProsima/Fast-DDS-Gen.git cd Fast-DDS-Gen构建和安装&#xff1a; fastDDS-gen 使用 Gradle 进行构建。你可以使用以下命令来构建和安装&…

MSF回弹木马ubuntu测试

网站地址为192.168.104.128 web.php内容为&#xff1a; <?php eval($_POST[123]); ?>linux版本信息&#xff1a;20.04.1-Ubuntu nginx信息&#xff1a;nginx-1.21.6 php信息&#xff1a;PHP 7.3.33-19 php-fpm信息&#xff1a;/etc/php/7.3/fpm/php-fpm.conf 一、使用…

AUTOSAR实战教程 - 模式管理BswM与其他各模块的交互

近日驻厂某OEM,幸得大块的个人时间, 把BswM这一块的内容从ETAS/ISOLAR工具配置到代码实现做了一个全方位的CT. 2024,希望孜孜内卷的汽车人升职加薪!博主近期写的一首小诗,也一并送给大家,懂的都懂: 在看不到阳光的冬天/ 我染了风寒/ 白天点灯/ 晚上吃药/ 躺在被窝里才敢咳…

用的到linux-tomcat端口占用排查-Day5

前言&#xff1a; 最近使用tomcat搭建了一套测试环境的应用&#xff0c;整个搭建过程也很简单&#xff0c;就是将部署包上传至服务器☞解压☞启动tomcat服务器&#xff0c;当然服务器也是成功启动了&#xff0c;但是发现前端应用报404&#xff0c;具体如下图所示。 一、现象及思…

【Linux-WMware Tools安装失败“segmentation fault”解决方法】

VMware版本&#xff1a;17 Ubuntu版本: 22.04 安装常规办法&#xff0c;通过vmware安装Tool&#xff0c;安装显示报错&#xff1a;“segmentation fault”&#xff0c;查了下可能是tool和ubuntu版本不兼容导致的。解决办法&#xff1a;通过命令行逐次安装。 1、sudo apt insta…