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

【保姆级】Java后端查询数据库结果导出xlsx文件+打印xlsx表格

目录

    • 前言
    • 一、需求一:数据库查询的数据导出成Excel表格
      • 1.1 Vue前端实现导出按钮+点击事件
      • 1.2 后端根据数据库查询结果生成xlsx文件
    • 二、需求二:对生成的xlsx文件调用打印机打印
      • 2.1 Vue前端实现按钮+事件
      • 2.2 后端实现打印

前言

最近在弄一个需求,需求如下:
需求一:Vue前端点击导出按钮,就可以将从数据库查出的数据导出成xlsx,即Excel表格形式
需求二点击打印按钮,要将生成的xlsx文件启动进程,调用打印接口,实现打印,这是为了生成客户订单表,可以让机器直接打印

PS:想吐槽网上很多都复制粘贴的技术文章,找半天一点卵用都没用,这里记录一下自己解决方案,若转发请注明出处,原创不易,有问题可评论区留言

需求一效果预览
在这里插入图片描述
需求二预览
在这里插入图片描述

一、需求一:数据库查询的数据导出成Excel表格

1.1 Vue前端实现导出按钮+点击事件

<el-button type="success" round icon="el-icon-download" @click="exportByEasyPoi">导出</el-button>

对应按钮点击触发的exportByEasyPoi方法,这里我用的是EasyPoi操作Excel,也挺多公司用的
注:前端是Vue2

<script>
import userApi from '@/api/userManage'
export default {methods: {exportByEasyPoi() {userApi.exportByEasyPoi().then(response => {this.$message.success('导出成功')})}}
}
</script>

这里我调用了src/api/userManage.js,这是自己创建的js脚本,调用后端接口的

import request from '@/utils/request'export default {exportByEasyPoi() {return request({url: `/user/exportep`,method: 'get',timeout: '10000'})}
}

需求一前端就这么多了,接下来就是后端

1.2 后端根据数据库查询结果生成xlsx文件

首先导入EasyPoi相关依赖

<!--easypoi-->
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.3.0</version>
</dependency>
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-base</artifactId><version>4.3.0</version>
</dependency>
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-web</artifactId><version>4.3.0</version>
</dependency>
<dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-annotation</artifactId><version>4.3.0</version>
</dependency>
<!-- lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version>
</dependency>

下面先给出后端核心逻辑代码,后面会具体讲解,这里就不加篇幅,直接把逻辑代码写在Controller层,原本应该写在Service层,即xxxServiceImpl实现类中,这里为了方便,直接这么写下。

@Autowired
private IUserService userService;@GetMapping("/exportep")public Result<?> exportByEasyPoi(HttpServletResponse response) throws IOException {// mybatisplus实现的list(),拿到用户信息列表List<User> users = userService.list();List<ExcelUserVo> excelUserVos = BeanCopyUtils.copyBeanList(users, ExcelUserVo.class);// easypoi导出ExportParams params = new ExportParams();params.setTitle("测试");// 表格左下角的sheet名称params.setSheetName("用户信息");Workbook workbook = ExcelExportUtil.exportExcel(params, ExcelUserVo.class, excelUserVos);// 判断文件路径是否存在,并将信息写入文件try{// 文件夹是否存在,若没有对应文件夹直接根据路径生成文件会报错File folder = new File(Constants.XLSX_DIR);if (!folder.exists() && !folder.isDirectory()) {folder.mkdirs();}// 文件是否存在File file = new File(Constants.XLSX_DIR + "\\" + Constants.XLSX_NAME);if (!file.exists()){file.createNewFile();}// 输出流写入FileOutputStream outputStream = new FileOutputStream(Constants.XLSX_DIR + "\\" + Constants.XLSX_NAME);workbook.write(outputStream);// 关闭写,不然用户点击生成的文件会显示只读outputStream.close();workbook.close();}catch (IOException e){e.printStackTrace();}return Result.success("导出成功");}

ExcelUserVo.java是自己需要显示在表格中的列,就是我们查询用户表,大部分时候不需要展示所有的属性到前端,挑需要显示的,所以封装成xxxVo,比如密码、创建时间、备注可以不显示在前端,不用打印就不要。

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;@Data
@NoArgsConstructor
@AllArgsConstructor
@ExcelTarget("sys_user")
public class ExcelUserVo implements Serializable {@Excel(name = "用户id", width = 10)
//    @ExcelIgnore // 表示忽略, 不在表格生成private Integer id;@Excel(name = "用户名", width = 20)private String username;@Excel(name = "邮箱", width = 30)private String email;@Excel(name = "电话", width = 30)private String phone;@Excel(name = "状态(1:正常,0:禁用)", width = 10)private Integer status;
}

BeanCopyUtils.java是常用工具类,可以实现对象的拷贝,将两个对象中相同属性字段拷贝

import java.util.List;
import java.util.stream.Collectors;public class BeanCopyUtils {private BeanCopyUtils() {}/** 单个对象*/public static <V> V copyBean(Object source, Class<V> clazz) {/** 创建目标对象 实现属性拷贝*/V result = null;try {result = clazz.newInstance();/** 拷贝*/BeanUtils.copyProperties(source, result);} catch (Exception e) {e.printStackTrace();}return result;}/** 集合*/public static <O, V> List<V> copyBeanList(List<O> list, Class<V> clazz) {/** 创建目标对象 实现属性拷贝*/return list.stream().map(o -> copyBean(o, clazz)).collect(Collectors.toList());}
}

自定义常量Constants.java,这里主要是定义输出路径

public class Constants {// excel表public static final String XLSX_DIR = "D:\\study\\excel";public static final String XLSX_NAME = "easypoi.xlsx";}

数据库sys_user表结构

DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(50) NOT NULL,`password` varchar(100) DEFAULT NULL,`email` varchar(50) DEFAULT NULL,`phone` varchar(20) DEFAULT NULL,`status` int(1) DEFAULT NULL,`avatar` varchar(200) DEFAULT NULL,`deleted` int(1) DEFAULT '0',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

二、需求二:对生成的xlsx文件调用打印机打印

2.1 Vue前端实现按钮+事件

<el-button type="warning" round icon="el-icon-printer" @click="printExcel">打印</el-button>
methods: {printExcel() {userApi.printTable().then(response => {this.$message.success('请求打印成功')})}
}

userManage.js中再写一个调用后端接口的

export default {printTable() {return request({url: `/user/print`,method: 'get',timeout: '100000'})}
}

2.2 后端实现打印

这里也干脆实现逻辑不写在Service层了,省点字,实际开发中还是要遵循规范哈

@GetMapping("/print")
public Result<?> printInfo(){try {String filepath = Constants.XLSX_DIR + "\\" + Constants.XLSX_NAME;PrintUtil.print(filepath);} catch (Exception e) {e.printStackTrace();}return Result.success();
}

核心打印工具PrintUtil.java,这个java文件稍微有点长

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;import javax.imageio.ImageIO;
import javax.print.*;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.OrientationRequested;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;public class PrintUtil {/*** 竖屏模式*/public static OrientationRequested PORTRAIT = OrientationRequested.PORTRAIT;/*** 横屏模式*/public static OrientationRequested LANDSCAPE = OrientationRequested.LANDSCAPE;/*** 获取全部打印设备信息* @return 返回全部能用的打印服务的List*/public static List<PrintService> getDeviceList() {// 构建打印请求属性集HashPrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();// 设置打印格式,因为未确定类型,所以选择autosenseDocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;// 查找所有的可用的打印服务PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras);List<PrintService> list = Arrays.asList(printService);return list;}/*** 根据文件类型不同调用不同代码去打印* @param filePath 文件路径*/public static void print(String filePath) throws Exception {PrintService printService = PrintServiceLookup.lookupDefaultPrintService();String defaultDeviceName = printService.getName();print(filePath, defaultDeviceName);}/*** 额外传入一个 AfterPrint,会在打印完成后调用 afterPrint.run()* @param filePath* @param afterPrint* @throws Exception*/public static void print(String filePath, AfterPrint afterPrint) throws Exception {print(filePath);afterPrint.run();}/*** 根据文件类型不同调用不同代码去打印* @param filePath 文件路径* @param deviceName 设备名称,传入哪个设备的名称,就让哪个设备去打印*/public static void print(String filePath, String deviceName) throws Exception{List<PrintService> list = getDeviceList();PrintService printService = null;for (PrintService p : list) {if(p.getName().equals(deviceName)) {printService = p;break;}}if(printService == null) {throw new Exception("Device not found");}String type = filePath.replaceAll(".*\\.","");if("jpg".equalsIgnoreCase(type)) {normalPrint(new File(filePath), DocFlavor.INPUT_STREAM.JPEG, printService);return;}if("jpeg".equalsIgnoreCase(type)) {normalPrint(new File(filePath), DocFlavor.INPUT_STREAM.JPEG, printService);return;}if("gif".equalsIgnoreCase(type)) {normalPrint(new File(filePath), DocFlavor.INPUT_STREAM.GIF, printService);return;}if("pdf".equalsIgnoreCase(type)) {printPDF(new File(filePath), DocFlavor.INPUT_STREAM.PNG, printService);return;}if("png".equalsIgnoreCase(type)) {normalPrint(new File(filePath), DocFlavor.INPUT_STREAM.PNG, printService);return;}if("doc".equalsIgnoreCase(type)) {printWord(filePath, deviceName);return;}if("docx".equalsIgnoreCase(type)) {printWord(filePath, deviceName);return;}if("xls".equalsIgnoreCase(type)) {printExcel(filePath, deviceName);return;}if("xlsx".equalsIgnoreCase(type)) {printExcel(filePath, deviceName);return;}if("ppt".equalsIgnoreCase(type)) {printPPT(filePath, deviceName);return;}if("pptx".equalsIgnoreCase(type)) {printPPT(filePath, deviceName);return;}}/*** 会在打印完成后调用 afterPrint.run()* @param filePath* @param deviceName* @param afterPrint* @throws Exception*/public static void print(String filePath, String deviceName, AfterPrint afterPrint) throws Exception{print(filePath, deviceName);afterPrint.run();}/*** javase的打印机打印文件,支持jpg,png,gif,pdf等等* @param file 要打印的文件* @param flavor 打印格式*/private static void normalPrint(File file, DocFlavor flavor) {// 定位默认的打印服务PrintService service = PrintServiceLookup.lookupDefaultPrintService();             // 显示打印对话框normalPrint(file, flavor, service);}private static void normalPrint(File file, DocFlavor flavor, PrintService service) {normalPrint(file, flavor, PORTRAIT, service);}/*** javase的打印机打印文件,支持jpg,png,gif等等* @param file 要打印的文件* @param service 打印机选择* @param requested 设定横屏还是竖屏* @param flavor 打印格式*/private static void normalPrint(File file, DocFlavor flavor, OrientationRequested requested, PrintService service) {// 构建打印请求属性集HashPrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();pras.add(requested);if (service != null) {try {DocPrintJob job = service.createPrintJob(); // 创建打印作业FileInputStream fis = new FileInputStream(file); // 构造待打印的文件流DocAttributeSet das = new HashDocAttributeSet();Doc doc = new SimpleDoc(fis, flavor, das);job.print(doc, pras);} catch (Exception e) {e.printStackTrace();}}}/*** 打印pdf的方法,因为java内置的打印pdf的方法有病,所以首先需要把pdf转换成png,然后打印png* @param file 要打印的文件* @param flavor 要打印的文件* @param service 打印设备*/private static void printPDF(File file, DocFlavor flavor, PrintService service) {try {PDDocument doc = PDDocument.load(file);PDFRenderer renderer = new PDFRenderer(doc);int pageCount = doc.getNumberOfPages();for(int i=0;i<pageCount;i++){File f = new File(file.getParent() + File.separator + "temp_" + i + ".png");BufferedImage image = renderer.renderImageWithDPI(i, 96);ImageIO.write(image, "PNG", f);normalPrint(f, flavor, LANDSCAPE, service);f.delete();}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** 打印机打印Word* @param filepath 打印文件路径* @param deviceName 传入哪个设备名称,用哪个设备打印*/private static void printWord(String filepath, String deviceName) {if(filepath.isEmpty()){return;}ComThread.InitSTA();//使用Jacob创建 ActiveX部件对象:ActiveXComponent word=new ActiveXComponent("Word.Application");//打开Word文档Dispatch doc=null;Dispatch.put(word, "Visible", new Variant(false));word.setProperty("ActivePrinter", new Variant(deviceName));Dispatch docs=word.getProperty("Documents").toDispatch();doc=Dispatch.call(docs, "Open", filepath).toDispatch();try {Dispatch.call(doc, "PrintOut");//打印} catch (Exception e) {e.printStackTrace();}finally{try {if(doc!=null){//关闭文档Dispatch.call(doc, "Close",new Variant(0));}} catch (Exception e2) {e2.printStackTrace();}word.invoke("Quit", new Variant[] {});//关闭进程//释放资源ComThread.Release();}}/*** 打印Excel* @param filePath 打印文件路径,形如 E:\\temp\\tempfile\\1494607000581.xls* @param deviceName 传入哪个设备名称,用哪个设备打印*/private static void printExcel(String filePath, String deviceName){if(filePath.isEmpty()){return;}ComThread.InitSTA();ActiveXComponent xl=new ActiveXComponent("Excel.Application");try {Dispatch.put(xl, "Visible", new Variant(true));Dispatch workbooks = xl.getProperty("Workbooks").toDispatch();Dispatch excel=Dispatch.call(workbooks, "Open", filePath).toDispatch();Dispatch.callN(excel,"PrintOut",new Object[]{Variant.VT_MISSING, Variant.VT_MISSING, new Integer(1),new Boolean(false), deviceName, new Boolean(true),Variant.VT_MISSING, ""});Dispatch.call(excel, "Close", new Variant(false));} catch (Exception e) {e.printStackTrace();} finally{xl.invoke("Quit",new Variant[0]);ComThread.Release();}}/*** 打印PPT* @param filePath* @param deviceName*/private static void printPPT(String filePath, String deviceName) {File file = new File(filePath);File pdfFile = new File(file.getParentFile().getAbsolutePath() + file.getName() + ".pdf");ActiveXComponent app = null;Dispatch ppt = null;try {ComThread.InitSTA();app = new ActiveXComponent("PowerPoint.Application");Dispatch ppts = app.getProperty("Presentations").toDispatch();ppt = Dispatch.call(ppts, "Open", filePath, true, true, false).toDispatch();Dispatch.call(ppt, "SaveAs", pdfFile.getAbsolutePath(), 32);} catch (Exception e) {e.printStackTrace();throw e;} finally {if (ppt != null) {Dispatch.call(ppt, "Close");}if (app != null) {app.invoke("Quit");}ComThread.Release();}try {print(pdfFile.getAbsolutePath(), deviceName);pdfFile.delete();} catch (Exception e) {e.printStackTrace();}}/*** 接口,在打印结束后调用*/public interface AfterPrint {void run();}
}

PrintUtil.java中依赖两个打印需要的非常重要包,jacob和pdfbox,下面给出免费链接,阿里云盘不限速的
链接:Java打印相关依赖包

下载后,需要导入一下,也十分简单,如图
在这里插入图片描述
然后运行后端,点击按钮就会有对应效果了,如果你没有打印机,会弹出生成PDF,有打印机连着,会使用默认打印机,或者通过PrintUtil中方法自定义打印机名称,选择打印机打印

以上就是全部内容,过程有啥问题可以评论区和大家一起交流!

相关文章:

【保姆级】Java后端查询数据库结果导出xlsx文件+打印xlsx表格

目录前言一、需求一&#xff1a;数据库查询的数据导出成Excel表格1.1 Vue前端实现导出按钮点击事件1.2 后端根据数据库查询结果生成xlsx文件二、需求二&#xff1a;对生成的xlsx文件调用打印机打印2.1 Vue前端实现按钮事件2.2 后端实现打印前言 最近在弄一个需求&#xff0c;需…...

Java数据库部分(MySQL+JDBC)(二、JDBC超详细学习笔记)

文章目录1 JDBC&#xff08;Java Database Connectivity&#xff09;1.1 什么是 JDBC&#xff1f;1.2 JDBC 核心思想2 JDBC开发步骤【重点】2.0 环境准备2.1 注册数据库驱动2.2 获取数据库的连接2.3 获取数据库操作对象Statement2.4 通过Statement对象执行SQL语句2.5 处理返回结…...

vue3生命周期

一、Vue3中的生命周期 1、setup() : 开始创建组件之前&#xff0c;在 beforeCreate 和 created 之前执行&#xff0c;创建的是 data 和 method 2、onBeforeMount() : 组件挂载到节点上之前执行的函数&#xff1b; 3、onMounted() : 组件挂载完成后执行的函数&#xff1b; 4、…...

Python学习笔记10:开箱即用

开箱即用 模块 python系统路径 import sys, pprint pprint.pprint(sys.path) [,D:\\Program Files\\Python\\Lib\\idlelib,D:\\Program Files\\Python\\python310.zip,D:\\Program Files\\Python\\DLLs,D:\\Program Files\\Python\\lib,D:\\Program Files\\Python,D:\\Progr…...

详解JAVA反射

目录 1.概述 2.获取Class对象 3.API 3.1.实例化对象 3.2.方法 3.3.属性 1.概述 反射&#xff0c;JAVA提供的一种在运行时获取类的信息并动态操作类的能力。JAVA反射允许我们在运行时获取类的属性、方法、构造函数等信息&#xff0c;并能够动态地操作它们。 2.获取Class…...

在nestjs中进行typeorm cli迁移(migration)的配置

在nestjs中进行typeorm cli迁移(migration)的配置 在学习nestjs过程中发现typeorm的迁移配置十分麻烦,似乎许多方法都是旧版本的配置&#xff0c;无法直接使用. 花了挺长时间总算解决了这个配置问题. db.config.ts 先创建db.config.ts, 该文件export了两个对象&#xff0c;其…...

前端工程构建问题汇总

1.less less-loader安装失败问题 npm install less-loader --save --legacy-peer-deps 加上–legacy-peer-deps就可以了 在NPM v7中&#xff0c;现在默认安装peerDependencies&#xff0c;这会导致版本冲突&#xff0c;从而中断安装过程。 –legacy-peer-deps标志是在v7中引…...

某马程序员NodeJS速学笔记

文章目录前言一、什么是Node.js?二、fs文件系统模块三、Http模块四、模块化五、开发属于自己的包模块加载机制六、Express1.初识ExpressGET/POSTnodemon2.路由模块化3.中间件中间件分类自定义中间件4. 跨域问题七、Mysql模块安装与配置基本使用Web开发模式Session认证JWT八、m…...

SpringMVC DispatcherServlet源码(6) 完结 静态资源原理

阅读源码&#xff0c;分析静态资源处理器相关组件&#xff1a; 使用SimpleUrlHandlerMapping管理url -> 处理器映射关系spring mvc使用WebMvcConfigurationSupport注入SimpleUrlHandlerMapping组件DelegatingWebMvcConfiguration可以使用WebMvcConfigurer的配置静态资源url…...

2023年全国最新会计专业技术资格精选真题及答案9

百分百题库提供会计专业技术资格考试试题、会计考试预测题、会计专业技术资格考试真题、会计证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 四、材料题 1.某企业为增值税一般纳税人&#xff0c;2019年12月初“应付职工薪酬…...

Web3中文|把Web3装进口袋,Solana手机Saga有何魔力?

2月23日&#xff0c;Solana Web3手机Saga发布新的消息&#xff0c;将推出NFT铸造应用程序Minty Fresh。在Minty Fresh&#xff0c;用户仅需轻点并完成拍摄&#xff0c;就可以直接在手机中进行NFT铸造&#xff0c;并在几秒钟内将其转换为链上NFT&#xff0c;NFT还可以发布在 Ins…...

【配电网优化】基于串行和并行ADMM算法的配电网优化研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

数据结构初阶 -- 顺序表

数据结构初阶 链表的讲解 目录 一. 线性表 1.1 定义 1.2 特点 二. 顺序表 2.1 定义 2.2 代码 2.3 功能需求 2.4 静态顺序表的特点以及缺点 2.5 动态的顺序表 2.6 动态顺序表接口的实现 三. 代码 头文件 主文件 一. 线性表 1.1 定义 线性表&#xff08;linear li…...

uniapp:3分钟搞定在线推送uni.createPushMessage,uni.onPushMessage

安卓端 在线推送功能演示&#xff1a; 1、dcloud后台申请开通uniPush dcloud后台 &#xff08;1&#xff09;&#xff1a;找到我的应用 &#xff08;2&#xff09;&#xff1a;点进去后&#xff0c;各平台信息&#xff0c;点击新增 &#xff08;3&#xff09;&#xff1a;填…...

C/C++开发,无可避免的多线程(篇一).跨平台并行编程姗姗来迟

一、编译环境准备 在正式进入c/c多线程编程系列之前&#xff0c;先来搭建支持多线程编译的编译环境。 1.1 MinGW&#xff08;win&#xff09; 进入Downloads - MinGW-w64下载页面&#xff0c;选择MinGW-w64-builds跳转下载&#xff0c; 再次进行跳转&#xff1a; 然后进入下载页…...

如何把照片的底色修改为想要的颜色

如何给照片更换底色&#xff1f;其实有可以一键给照片更换底色的 APP &#xff0c;但是几乎都要收费。如果想要免费的给照片更换底色的话&#xff0c;分享两种简单便捷的方法给你。掌握了这项技能&#xff0c;以后就不用店花钱处理啦&#xff01;1、免费&#xff01;线上快速 给…...

【高效办公】批量生成固定模板的文件夹名称

老师让你按照他的要求生成每位学生的文件夹,你是学委,让你马上完成该任务,但你又不想是手动一个一个码字,因此聪明的你就看到了本篇文章啦!!! 虽说一个人懒惰,并不是好的事情。 但这个似乎合情合理啊~ 然后,就动手想办法,一开始就真的打算码字了。。 思路 在实际开…...

redis的集群方式

1.主从复制 主从复制原理&#xff1a; 从服务器连接主服务器&#xff0c;发送SYNC命令&#xff1b; 主服务器接收到SYNC命名后&#xff0c;开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令&#xff1b; 主服务器BGSAVE执行完后&#xff0c;向所有从服务…...

温控负荷的需求响应潜力评估及其协同优化管理研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

模电学习9. MOS管使用入门

模电学习9. MOS管使用入门一、mos管理简介1. 简介2. mos管理的特点3. MOS管的工作状态&#xff08;1&#xff09;放大功能&#xff08;2&#xff09;截止区&#xff08;3&#xff09;饱和区3. Mos管的分类&#xff08;1&#xff09;按照工作模式分类&#xff1a;&#xff08;2&…...

录播姬:如何轻松录制mikufans直播并解决常见问题?

录播姬&#xff1a;如何轻松录制mikufans直播并解决常见问题&#xff1f; 【免费下载链接】BililiveRecorder 录播姬 | mikufans 生放送录制 项目地址: https://gitcode.com/gh_mirrors/bi/BililiveRecorder 录播姬是一款专为mikufans直播平台设计的开源录制工具&#x…...

BilibiliDown完整使用教程:三步搞定B站视频批量下载

BilibiliDown完整使用教程&#xff1a;三步搞定B站视频批量下载 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mirrors/bi/…...

GSE魔兽世界宏编辑器:高级序列化技术与智能战斗自动化解决方案

GSE魔兽世界宏编辑器&#xff1a;高级序列化技术与智能战斗自动化解决方案 【免费下载链接】GSE-Advanced-Macro-Compiler GSE is an alternative advanced macro editor and engine for World of Warcraft. 项目地址: https://gitcode.com/gh_mirrors/gs/GSE-Advanced-Macr…...

NAS极速搭建PostgreSQL:打造个人专属数据仓库

1. 为什么选择NASPostgreSQL组合&#xff1f; 最近几年&#xff0c;越来越多的技术爱好者开始在家用NAS上部署数据库服务。我自己从2018年开始尝试这种方案&#xff0c;先后测试过MySQL、MongoDB和PostgreSQL&#xff0c;最终发现PostgreSQL在NAS上的表现最为出色。相比云数据库…...

无守护进程容器镜像构建:Tiny Builder 原理、实践与CI/CD集成指南

1. 项目概述&#xff1a;一个极简的容器镜像构建器最近在折腾容器化部署和CI/CD流水线时&#xff0c;我一直在寻找一个足够轻量、纯粹的镜像构建工具。Docker本身当然没问题&#xff0c;但有时候&#xff0c;尤其是在一些资源受限的环境&#xff08;比如GitHub Actions的免费Ru…...

OpenClaw从入门到应用——工具(Tools):Lobster

通过OpenClaw实现副业收入&#xff1a;《OpenClaw赚钱实录&#xff1a;从“养龙虾“到可持续变现的实践指南》 Lobster 是一个工作流 Shell&#xff0c;它让 OpenClaw 将多步工具序列作为单一的、确定性的操作来运行&#xff0c;并带有明确的审批检查点。 引子 你的助手可以…...

如何构建一个基于YOLOv8的智慧化工地管理系统,用于工地要素分割与检测

如何构建一个基于YOLOv8的智慧化工地管理系统&#xff0c;用于工地要素分割与检测。该系统将涵盖10大要素&#xff08;工人佩戴安全帽、不佩戴安全帽、预制构件、混凝土运输车、渣土车、搅拌车、挖掘机、压路车、推土车、装载车&#xff09; 文章目录以下文字仅供参考&#xff…...

基于RT-Thread与HMI-BOARD的直线推杆智能测试系统设计与实现

1. 项目概述与核心价值在工业自动化领域&#xff0c;直线推杆作为一种常见的执行机构&#xff0c;广泛应用于医疗床、升降桌、工业阀门、农业机械等设备中。一个推杆从设计图纸到批量生产&#xff0c;中间有一个至关重要的环节&#xff1a;寿命与可靠性测试。传统的测试方案&am…...

5分钟完整指南:Sabaki围棋软件打造专业级对弈环境

5分钟完整指南&#xff1a;Sabaki围棋软件打造专业级对弈环境 【免费下载链接】Sabaki An elegant Go board and SGF editor for a more civilized age. 项目地址: https://gitcode.com/gh_mirrors/sa/Sabaki Sabaki是一款优雅的围棋棋盘和SGF编辑器&#xff0c;专为追求…...

别浪费了STM32F103C8T6的PA13和PA14!SWD下载后,教你一键解锁这两个GPIO

解锁STM32F103C8T6的PA13/PA14引脚&#xff1a;从SWD调试到GPIO复用的实战指南 刚拿到STM32F103C8T6核心板时&#xff0c;很多开发者会对着有限的引脚发愁——尤其是那些标着"SWDIO"和"SWCLK"的PA13/PA14引脚。难道这两个引脚只能永远被调试接口占用&#…...