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

JAVA:探索 PDF 文字提取的技术指南

1、简述

随着信息化的发展,PDF 文档成为了信息传播的重要媒介。在许多应用场景下,如数据迁移、内容分析和信息检索,我们需要从 PDF 文件中提取文字内容。JAVA提供了多种库来处理 PDF 文件,其中 PDFBox 和 iText 是最常用的两个。

在这里插入图片描述

在这篇博客中,我们将深入探讨如何使用多种方式来提取 PDF 文本,分析各自的优缺点,并讨论在不同场景下的最佳实践。

2、准备工作

在开始之前,你需要以下准备工作:

  • 百度开发者账号:前往百度AI开放平台注册账号,并创建一个应用以获取 API Key 和 Secret Key。
  • Java 开发环境:确保你的开发环境已经配置好,包括 JDK 和一个集成开发环境(IDE),如 IntelliJ IDEA 或 Eclipse。
  • 引入依赖:百度官方提供了 Java SDK,或者你可以直接使用 HttpClient 进行 API 调用。

引入Maven依赖:

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.7</version>
</dependency>
<dependency><groupId>org.apache.directory.studio</groupId><artifactId>org.apache.commons.codec</artifactId><version>1.8</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version>
</dependency>
<!-- spring-boot-actuator -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>3.0.2</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.3</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version>
</dependency>
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.5.0</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>font-asian</artifactId><version>7.1.16</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>kernel</artifactId><version>7.1.16</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>io</artifactId><version>7.1.16</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>layout</artifactId><version>7.1.16</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>forms</artifactId><version>7.1.16</version>
</dependency>
<dependency><groupId>com.itextpdf</groupId><artifactId>pdfa</artifactId><version>7.1.16</version>
</dependency>
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.8.0</version>
</dependency>
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><version>4.4</version>
</dependency>
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.13</version>
</dependency>

3、利用 PDFBox 解析

可以使用 PDFBox 库来解析 PDF 文件并提取文本内容。PDFBox 可以帮助你逐行读取 PDF 的文本,然后你可以编写逻辑来查找指定的文字。

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;import java.io.File;
import java.io.IOException;public class PDFReader {public static void main(String[] args) {String filePath = "path/to/your/pdf-file.pdf";String keyword = "指定文字";  // 要查找的指定文字try (PDDocument document = PDDocument.load(new File(filePath))) {PDFTextStripper pdfStripper = new PDFTextStripper();String text = pdfStripper.getText(document);// 将文本按行分割String[] lines = text.split("\n");for (int i = 0; i < lines.length; i++) {if (lines[i].contains(keyword)) {System.out.println("在第 " + page + " 页找到关键字: " + keyword);}}} catch (IOException e) {e.printStackTrace();}}
}

4、利用 Tesseract 来解析 PDFBox

将 PDF 转换为图像并使用 Tesseract OCR 进行文本识别是一种有效的方法来处理 PDF 文档中的复杂布局或不规则表格。以下是如何在 Java 中实现这一过程的详细步骤:

  • 将 PDF 页面转换为图像:使用 PDFBox 将每个 PDF 页面转换为图像。
  • 使用 Tesseract OCR 识别图像中的文本:通过 Tesseract OCR 读取每个图像,并提取文本。
  • 查找关键字并提取信息:在 OCR 识别的文本中查找关键字(如“图号”),并提取相邻单元格的值。
 @PostMapping("/pdf2Excel")public ResponseEntity<String> pdf2Excel(@RequestParam("keyword") String keyword, @RequestParam("file")MultipartFile file) throws IOException {if (file.isEmpty()) {return new ResponseEntity<>("File is empty", HttpStatus.BAD_REQUEST);}String basePath = System.getProperty("java.io.tmpdir");String imagesPath = basePath + "\\images\\";File directory = new File(imagesPath);if(!directory.exists()){directory.mkdirs();}File convFile = new File(basePath+ "/" + file.getOriginalFilename());file.transferTo(convFile);String excelPath = "C:\\Users\\WIN10\\Desktop\\fsdownload\\excel\\MapData.xlsx";File excelFile = new File(excelPath);if(!excelFile.exists()){Files.createFile(excelFile.toPath());}Map<String, Object> objectMap = new HashMap<>();try (PDDocument document = Loader.loadPDF(convFile)) {PDFRenderer pdfRenderer = new PDFRenderer(document);int numberOfPages = document.getNumberOfPages();ITesseract instance = new Tesseract();instance.setDatapath("D:\\soft\\Tesseract-OCR\\tessdata"); // 设置Tesseract的tessdata路径instance.setLanguage("chi_sim"); // 设置识别语言for (int pageIndex = 0; pageIndex < numberOfPages; pageIndex++) {BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(pageIndex, 144);int currentPageNum = pageIndex + 1;File imageFile = new File(imagesPath + "page_" + currentPageNum + ".jpg");ImageIO.write(bufferedImage, "jpg", imageFile);// 调用OCR服务识别文字String result =  instance.doOCR(imageFile);processOCRResult(result, objectMap, currentPageNum);System.out.println("Page " + (currentPageNum) + " converted to image.");}System.out.println("获取所有的图号-结束");System.out.println("数据转换Excel-开始");// 创建 Excel 工作簿Workbook workbook = new XSSFWorkbook();Sheet sheet = workbook.createSheet("Map Data");// 创建表头Row headerRow = sheet.createRow(0);headerRow.createCell(0).setCellValue("Key");headerRow.createCell(1).setCellValue("Value");// 填充数据int rowNum = 1;for (Map.Entry<String, Object> entry : objectMap.entrySet()) {Row row = sheet.createRow(rowNum++);row.createCell(0).setCellValue(entry.getKey());row.createCell(1).setCellValue((String) entry.getValue());}// 自动调整列宽sheet.autoSizeColumn(0);sheet.autoSizeColumn(1);FileOutputStream fileOut = new FileOutputStream(excelFile);workbook.write(fileOut);workbook.close();return ResponseEntity.ok().body("数据转换Excel成功");} catch (Exception e) {return new ResponseEntity<>("File upload error: " + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);}}

4、利用百度文字识别来解析 PDFBox

在现代开发中,文字识别(OCR,Optical Character Recognition)技术已经被广泛应用于图像处理、文档管理等领域。百度提供的文字识别 API 功能强大、易于使用,能够帮助开发者快速实现图像中的文字提取。本文将介绍如何在 Java 中利用百度文字识别 API 进行图片文字提取。

4.1 获取 Access Token

在调用文字识别 API 之前,需要先获取 Access Token。这一步通常在应用初始化时执行,并且 Access Token 具有一定的有效期。

public  Map<String,Object> token() throws Exception {//获取当前配置表数据参数Map<String,Object> map  = new HashMap<>();CloseableHttpClient httpClient = HttpClients.createDefault();HttpPost httpPost = new HttpPost("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials");httpPost.addHeader("Content-Type", "application/json");httpPost.addHeader("Accept", "application/json");//post请求参数配置List<NameValuePair> formparams = new ArrayList<NameValuePair>();formparams.add(new BasicNameValuePair("client_id", API_KEY));formparams.add(new BasicNameValuePair("client_secret", SECRET_KEY));UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");   //设置编码格式为utf-8httpPost.setEntity(uefEntity);  //设置POST请求参数//使用httpclient的execute方法发送接口请求CloseableHttpResponse response =  httpClient.execute(httpPost);HttpEntity  httpEntity = response.getEntity();String responseString = EntityUtils.toString(httpEntity);JSONObject obj = JSON.parseObject(responseString);if(response.getStatusLine().getStatusCode() == 200){map.put("access_token", obj.getString("access_token"));map.put("refresh_token",obj.getString("refresh_token"));map.put("expires_in",obj.getIntValue("expires_in"));}else {map.put("error", obj.getString("error"));map.put("error_description", obj.getString("error_description"));}map.put("stateCode", response.getStatusLine().getStatusCode());return map;
}
4.2 调用百度文字识别 API

获取到 Access Token 后,我们可以使用它来调用百度的文字识别 API。我们将通过一个 POST 请求发送图片数据,并接收识别结果。

public Map<String,Object> accurate(String token , String image) throws Exception{Map<String,Object> map  = new HashMap<>();CloseableHttpClient httpClient = HttpClients.createDefault();HttpPost httpPost = new HttpPost("https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token=" + token+"&language_type=CHN_ENG&detect_direction=false&paragraph=false&probability=false");httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");httpPost.addHeader("Accept", "application/json");//post请求参数配置List<NameValuePair> formparams = new ArrayList<NameValuePair>();formparams.add(new BasicNameValuePair("image", image));UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(formparams, "UTF-8");   //设置编码格式为utf-8httpPost.setEntity(uefEntity);  //设置POST请求参数//使用httpclient的execute方法发送接口请求CloseableHttpResponse response =  httpClient.execute(httpPost);HttpEntity  httpEntity = response.getEntity();String responseString = EntityUtils.toString(httpEntity);JSONObject obj = JSON.parseObject(responseString);String errorCode = obj.getString("error_code");if(Objects.nonNull(errorCode)){map.put("stateCode", 500);map.put("error_code", obj.getString("error_code"));map.put("error_msg", obj.getString("error_msg"));}else {map.put("stateCode", 200);map.put("words_result", obj.getJSONArray("words_result"));map.put("words_result_num",obj.getString("words_result_num"));map.put("log_id",obj.getString("log_id"));}return map;
}
4.3 将识别的文字转成 Excel

百度 OCR API 返回的结果是 JSON 格式的。我们可以使用 Gson 或其他 JSON 解析库来处理这些结果,并提取出识别到的文字并转成Excel输出。

@PostMapping("/pdf2Excel")
public ResponseEntity<byte[]> pdf2Excel(@RequestParam("keyword") String keyword, @RequestParam("file") MultipartFile file) throws Exception {if (file.isEmpty()) {return new ResponseEntity<>("File is empty".getBytes(), HttpStatus.BAD_REQUEST);}String basePath = System.getProperty("java.io.tmpdir");String imagesPath = basePath + "\\images\\";File directory = new File(imagesPath);if(!directory.exists()){directory.mkdirs();}File convFile = new File(basePath+ "/" + file.getOriginalFilename());file.transferTo(convFile);Map<String, Object> tokenMap = ocrAPIFactory.token();int stateCode = (int)tokenMap.get("stateCode");if(stateCode != 200){return  new ResponseEntity<>("ERROR".getBytes(), HttpStatus.OK);}Map<Integer, String> objectMap = new HashMap<>();String accessToken= String.valueOf(tokenMap.get("access_token"));System.out.println("获取所有的图号-开始");try (PDDocument document = Loader.loadPDF(convFile)) {PDFRenderer pdfRenderer = new PDFRenderer(document);int numberOfPages = document.getNumberOfPages();for (int pageIndex = 0; pageIndex < numberOfPages; pageIndex++) {BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(pageIndex, 144);int currentPageNum = pageIndex + 1;String imageFilePath = imagesPath + "page_" + currentPageNum + ".jpg";File imageFile = new File(imageFilePath);ImageIO.write(bufferedImage, "jpg", imageFile);String imgStr =  ocrAPIFactory.getFileContentAsBase64(imageFilePath, false);Map<String, Object> fileMap = ocrAPIFactory.accurate(accessToken, imgStr);stateCode = (int)fileMap.get("stateCode");if(stateCode != 200){System.out.println ("获取百度OCR 百度文件转换失败:" + fileMap.get("error_msg"));return  new ResponseEntity<>("ERROR".getBytes(), HttpStatus.OK);}JSONArray wordsResults = (JSONArray)fileMap.get("words_result");if(Objects.nonNull(wordsResults)){processOCRResult(wordsResults, currentPageNum, objectMap);}System.out.println("Page " + (currentPageNum) + " converted to image.");}System.out.println("获取所有的图号-结束");System.out.println("数据转换Excel-开始");//页数排序Map<Integer, String> sortedMap = objectMap.entrySet().stream() // 将 Map 转换为 Stream.sorted(Map.Entry.comparingByKey()) // 按值排序.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue,(oldValue, newValue) -> oldValue, // 如果有重复键时的合并策略() -> new LinkedHashMap<>()  // 保持顺序的 Map 实现));// 创建 Excel 工作簿Workbook workbook = new XSSFWorkbook();Sheet sheet = workbook.createSheet("Map Data");// 创建表头Row headerRow = sheet.createRow(0);headerRow.createCell(0).setCellValue("页码");headerRow.createCell(1).setCellValue("图号");// 填充数据int rowNum = 1;for (Map.Entry<Integer, String> entry : sortedMap.entrySet()) {Row row = sheet.createRow(rowNum++);row.createCell(0).setCellValue(Objects.nonNull(entry.getKey()) ? entry.getKey().toString() :"0");row.createCell(1).setCellValue(Objects.nonNull(entry.getValue()) ? entry.getValue().toString() :"" );}// 自动调整列宽sheet.autoSizeColumn(0);sheet.autoSizeColumn(1);// 将工作簿内容写入字节数组输出流ByteArrayOutputStream outputStream = new ByteArrayOutputStream();try {workbook.write(outputStream);workbook.close();} catch (IOException e) {e.printStackTrace();return ResponseEntity.status(500).build();}// 创建 Http 响应HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);headers.setContentDispositionFormData("attachment", "MapData.xlsx");System.out.println("数据转换Excel-结束");//删除文件夹try {// 递归删除文件夹及其内容Files.walkFileTree(new File(imagesPath).toPath(), new SimpleFileVisitor<Path>() {@Overridepublic FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {Files.delete(file);return FileVisitResult.CONTINUE;}@Overridepublic FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {Files.delete(dir);return FileVisitResult.CONTINUE;}});System.out.println("Directory deleted successfully.");} catch (IOException e) {e.printStackTrace();}return ResponseEntity.ok().headers(headers).body(outputStream.toByteArray());} catch (Exception e) {System.out.println("数据转换Excel异常:" + e);return new ResponseEntity<>("File upload error: ".getBytes(), HttpStatus.INTERNAL_SERVER_ERROR);}
}

5、结论

在 Java 中,PDF 文字提取可以通过 PDFBox 轻松实现。PDFBox 适合简单的文档处理,复杂的文档结构通过OCR来解析。在选择使用哪个库时,建议根据项目需求、文档复杂度和性能要求进行评估。

这篇博客提供了从 PDF 中提取文字的基础方法,并介绍了如何处理复杂的文档结构。希望这对你的项目有所帮助!如果有任何问题或建议,欢迎留言讨论。

相关文章:

JAVA:探索 PDF 文字提取的技术指南

1、简述 随着信息化的发展&#xff0c;PDF 文档成为了信息传播的重要媒介。在许多应用场景下&#xff0c;如数据迁移、内容分析和信息检索&#xff0c;我们需要从 PDF 文件中提取文字内容。JAVA提供了多种库来处理 PDF 文件&#xff0c;其中 PDFBox 和 iText 是最常用的两个。…...

当你项目服务器磁盘报警

当你们公司运维收到这样的邮件&#xff0c;大概率日志文件过大引起的 在Linux下如何不停止服务,清空nohup.out文件呢&#xff1f; nohup.out会一直一直自己增长下去&#xff0c;如果你的服务器硬盘不给力的话&#xff0c;很容易把应用也挂掉&#xff08;硬盘没空间 &#xff0…...

SpringBoot中Maven的定义及国内源配置教程,实现自动获取Jar包

推荐一个国内镜像API网站&#xff0c;无需信用卡及科学上网即可调用gpt&#xff0c;claude3&#xff0c;gemini等国外模型&#xff0c;感兴趣的可以看下&#x1f449;&#xff1a;https://api.atalk-ai.com/ SpringBoot中Maven的定义及国内源配置教程&#xff0c;实现自动获取J…...

LSTM 和 LSTMCell

1. LSTM 和 LSTMCell 的简介 LSTM (Long Short-Term Memory): 一种特殊的 RNN&#xff08;循环神经网络&#xff09;&#xff0c;用于解决普通 RNN 中 梯度消失 或 梯度爆炸 的问题。能够捕获 长期依赖关系&#xff0c;适合处理序列数据&#xff08;如自然语言、时间序列等&…...

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现&#xff08;Kalman Filter&#xff09; 更新以gitee为准&#xff1a; 文章目录 数据预测概念和适用方式线性系统的适用性 数据预测算法和卡尔曼滤波公式推导状态空间方程和观测器先验估计后验估计…...

神经网络问题之一:梯度消失(Vanishing Gradient)

梯度消失&#xff08;Vanishing Gradient&#xff09;问题是深度神经网络训练中的一个关键问题&#xff0c;它主要发生在反向传播过程中&#xff0c;导致靠近输入层的权重更新变得非常缓慢甚至几乎停滞&#xff0c;严重影响网络的训练效果和性能。 图1 在深度神经网络中容易出现…...

【微软:多模态基础模型】(4)统一视觉模型

欢迎关注[【youcans的AGI学习笔记】](https://blog.csdn.net/youcans/category_12244543.html&#xff09;原创作品 【微软&#xff1a;多模态基础模型】&#xff08;1&#xff09;从专家到通用助手 【微软&#xff1a;多模态基础模型】&#xff08;2&#xff09;视觉理解 【微…...

npm | Yarn | pnpm Node.js包管理器比较与安装

一、包管理器比较 参考原文链接&#xff1a; 2024 Node.js Package Manager 指南&#xff1a;npm、Yarn、pnpm 比较 — 2024 Node.js Package Manager Guide: npm, Yarn, pnpm Compared (nodesource.com) 以下是对 Node.js 的三个包管理工具 npm、Yarn 和 pnpm 的优缺点总结&am…...

建造者模式

什么是建造者模式&#xff1f; 建造者模式&#xff08;Builder Pattern&#xff09;是一种设计模式&#xff0c;用来一步步创建复杂的对象&#xff0c;而不用直接去调用复杂的构造函数或手动设置大量属性。 你可以&#xff1a; • 按步骤“搭建”对象。 • 自由选择要设置的部…...

Spring Boot核心概念:应用配置

Spring Boot提供了强大的配置系统&#xff0c;允许开发者通过配置文件轻松管理应用的配置。支持的主要配置文件格式有两种&#xff1a;application.properties和application.yml。 application.properties与application.yml application.properties和application.yml是Spring…...

linux环境安装cuda toolkit

1 全新安装 如果环境中没安装过cuda版本&#xff0c; 这种情况下比较简单。 直接在https://developer.nvidia.com/cuda-toolkit-archive选择对应版本下载安装即可。 如下为安装cuda toolkit 11.8. 2 环境中已经存在其他版本 这种情况下比较复杂一些。 首先要确认最高支持的版…...

WebSocket实战,后台修改订单状态,前台实现数据变更,提供前端和后端多种语言

案例场景&#xff1a; 在实际的后台中需要变更某个订单的状态&#xff0c;在官网中不刷新页面&#xff0c;可以自动更新状态 在前端页面实现订单状态的实时更新&#xff08;不刷新页面&#xff09;&#xff0c;可以通过 WebSocket 的方式与后台保持通信&#xff0c;监听订单状态…...

实时通信协议概述:WebRTC、RTP/RTCP、RTMP、HLS 和 FLV 的比较与应用

文章目录 一、协议总览二、WebRTC2.1 时序图2.2 代码示例 三、RTP/RTCP3.1 时序图3.2 代码示例 四、RTMP4.1 时序图4.2 代码示例 五、HLS5.1 时序图5.2 代码示例 六、总结 一、协议总览 协议/格式细节对比适用场景用法WebRTC使用 UDP 传输协议&#xff0c;支持 P2P 通信&#…...

Vue路由

目录 1. 安装 vue-router 2. 创建 Vue 项目结构 3. 配置路由 4. 在 main.js 中使用路由 5. 在 App.vue 中添加 6. 创建组件 7. 运行你的应用 在 Vue.js 2 中&#xff0c;路由管理通常通过 vue-router 插件来实现。vue-router 是一个官方的路由管理器&#xff0c;允许你…...

uniapp开发微信小程序笔记3-全局配置、导航栏配置、tabBar配置

前言&#xff1a; 本文记录的是微信小程序的全局配置、导航栏配置、tabBar配置 一、全局配置&#xff1a; 可以直接查官方文档&#xff1a;pages.json 页面路由 | uni-app官网&#xff0c;有非常详细的文档说明 都是在 pages.json里面做配置的&#xff0c;我们可以看到已经有…...

Hash table类算法【leetcode】

哈希表中关键码就是数组的索引下标&#xff0c;然后通过下标直接访问数组中的元素 那么哈希表能解决什么问题呢&#xff0c;一般哈希表都是用来快速判断一个元素是否出现集合里。 例如要查询一个名字是否在这所学校里。 要枚举的话时间复杂度是O(n)&#xff0c;但如果使用哈希…...

多算法模型(BI-LSTM GRU Mamba ekan xgboost)实现功率预测

概述 本项目旨在通过结合多算法模型网络实现功率预测。包括数据处理、特征工程、模型训练、模型推理和结果输出&#xff0c;最终结果以 JSON 格式返回。 代码地址&#xff1a;代码...

html 图片转svg 并使用svg路径来裁剪html元素

1.png转svg 工具地址: Vectorizer – 免费图像矢量化 打开svg图片,复制其中的path中的d标签的路径 查看生成的svg路径是否正确 在线SVG路径预览工具 - UU在线工具 2.在html中使用svg路径 <svg xmlns"http://www.w3.org/2000/svg" width"318px" height…...

贴代码框架PasteForm特性介绍之select,selects,lselect和reload

简介 PasteForm是贴代码推出的 “新一代CRUD” &#xff0c;基于ABPvNext&#xff0c;目的是通过对Dto的特性的标注&#xff0c;从而实现管理端的统一UI&#xff0c;借助于配套的PasteBuilder代码生成器&#xff0c;你可以快速的为自己的项目构建后台管理端&#xff01;目前管…...

【Redis】实现异步秒杀功能

一、将判断条件提前缓存到redis中 将判断条件缓存到redis中&#xff0c;如果判断成功直接操作redis中的数据&#xff0c;然后将数据写入redis&#xff0c;如果成功返回一个值。然后根据这个值判断是否成功&#xff0c;如果成功把用户id&#xff0c;优惠卷id&#xff0c;订单id存…...

React的API✅

createContext createContext要和useContext配合使用&#xff0c;可以理解为 “React自带的redux或mobx” &#xff0c;事实上redux就是用context来实现的。但是一番操作下来我还是感觉&#xff0c;简单的context对视图的更新的细粒度把控比不上mobx&#xff0c;除非配合memo等…...

2024亚太杯数学建模C题【Development Analyses and Strategies for Pet Industry 】思路详解

C&#xff1a;宠物行业及相关产业的发展分析与战略 随着人们消费观念的发展&#xff0c;宠物行业作为一个新兴产业&#xff0c;正在全球范围内逐渐积聚势头&#xff0c;这得益于快速的经济发展和人均收入的提高。1992年&#xff0c;中国小动物保护协会成立&#xff0c;随后1993…...

使用Notepad++工具去除重复行

使用Notepad工具去除重复行 参考链接&#xff1a;https://blog.csdn.net/londa/article/details/108981396 一 、使用正则表达式 1、对文本进行排序&#xff0c;让重复行排在一起 2、使用正则表达式替换&#xff08;注意&#xff09;^(.*?)$\s?^(?.*^\1$) 在替换时选择正…...

Three.js + AI:AI 算法生成 3D 萤火虫飞舞效果~

AI 驱动 3D 动画 大家好&#xff0c;我是石小石&#xff01;随着 Web 技术的发展&#xff0c;Three.js 成为构建 3D 图形和动画的主流工具。与此同时&#xff0c;人工智能&#xff08;AI&#xff09;在图像处理、动作生成等领域表现出强大能力。将 AI 与 Three.js 结合&#x…...

VScode clangd插件安装

前提 在VScode中写C代码时&#xff0c;总会用到 C/C 这个插件&#xff0c;也就自然而然地使用了这个插件带来的代码跳转和代码提示功能。但是当代码变地很多时&#xff0c;就会变得非常慢。所以经过调查后弃用C/C 插件的这个功能&#xff0c;使用 clangd 这个插件来提示C代码和…...

Swift从0开始学习 对象和类 day3

类&#xff08;Class&#xff09; 是一种类型或模板&#xff0c;描述了对象的特征和行为。对象&#xff08;Object&#xff09; 是类的实例&#xff0c;实际的实体&#xff0c;拥有自己的数据。 新入门的教学都喜欢用“人”来举例为类&#xff0c;在这里我也用“人”吧 //&…...

Linux——从命令行配置网络

1.使用nmcli添加静态网络连接 nmcli con add con-name static-addr \ ifname eth0 type ethernet ipv4.method manual ipv4.dns 172.25.250.220 \ ipv4.addresses 172.25.250.10/24 ipv4.gateway 172.25.250.254 命令概述 这是一条使用 nmcli&#xff08;NetworkManager 命令…...

RabbitMQ实现异步下单与退单

前言&#xff1a; 在电商项目中的支付模块也是一个很重要的模块&#xff0c;其中下订操作以及退订操作就是主要的操作。其次的下单是同步下单&#xff0c;也就是第三方支付、数据库扣减、积分增加、等等其他业务操作&#xff0c;等待全部执行完毕后向用户返回成功响应请求。对…...

[Python] 编程入门:理解变量类型

文章目录 [toc] 整数常见操作 浮点数字符串字符串中混用引号问题字符串长度计算字符串拼接 布尔类型动态类型特性类型转换结语 收录专栏&#xff1a;[Python] 在编程中&#xff0c;变量是用于存储数据的容器&#xff0c;而不同的变量类型则用来存储不同种类的数据。Python 与 C…...

C++ —— 剑斩旧我 破茧成蝶—C++11

江河入海&#xff0c;知识涌动&#xff0c;这是我参与江海计划的第2篇。 目录 1. C11的发展历史 2. 列表初始化 2.1 C98传统的{} 2.2 C11中的{} 2.3 C11中的std::initializer_list 3. 右值引用和移动语义 3.1 左值和右值 3.2 左值引用和右值引用 3.3 引用延长生命周期…...

Perl 简介

Perl 简介 Perl 是一种高级、通用、解释型、动态编程语言。由 Larry Wall 于 1987 年首次发布&#xff0c;它结合了 C、sed、awk 和 shell 脚本语言的特性。Perl 最初被设计用于文本处理&#xff0c;如报告生成和文件转换&#xff0c;但随着时间的推移&#xff0c;它已经发展成…...

Transformer中的Self-Attention机制如何自然地适应于目标检测任务

Transformer中的Self-Attention机制如何自然地适应于目标检测任务&#xff1a; 特征图的降维与重塑 首先&#xff0c;Backbone&#xff08;如ResNet、VGG等&#xff09;会输出一个特征图&#xff0c;这个特征图通常具有较高的通道数、高度和宽度&#xff08;例如CHW&#xff…...

【Linux篇】初学Linux,如何快速搭建Linux开发环境

文章目录 前言1. Linux背景介绍1.1 UNIX的发展历史1.2 Linux的发展历史 2. 企业应用现状3. 开源3.1 探索Linux源代码3.2 开源 VS 闭源 4. Linux的版本4.1 技术线4.2 商业产品线 5. os概念&#xff0c;定位6. 搭建Linux环境6.1 Linux环境的搭建方式6.2 购买云服务器 7. 使用XShe…...

竞赛思享会 | 2024年第十届数维杯国际数学建模挑战赛D题【代码+演示】

Hello&#xff0c;这里是Easy数模&#xff01;以下idea仅供参考&#xff0c;无偿分享&#xff01; 题目背景 本题旨在通过对中国特定城市的房产、人口、经济、服务设施等数据进行分析&#xff0c;评估其在应对人口老龄化、负增长趋势和极端气候事件中的韧性与可持续发展能力。…...

vim 使用技巧

使用技巧 正常模式&#xff08;Normal Mode&#xff09;插入模式&#xff08;Insert Mode&#xff09;命令模式&#xff08;Command Mode&#xff09; vim常用三种模式包括正常模式&#xff0c;插入模式&#xff0c;命令模式。 正常模式&#xff08;Normal Mode&#xff09; 进…...

CSS-flex布局

flex常用语法 display: flex 父级元素相关 flex-direction 主轴方向【水平方向&#xff08;默认&#xff09;、垂直方向】justify-content 主轴上的对齐方式【flex-end结束对齐、space-between两端对齐、center】align-items 交叉轴的对齐方式【center、flex-end】flex-wrap…...

小R的随机播放顺序

问题描述 小R有一个特殊的随机播放规则。他首先播放歌单中的第一首歌&#xff0c;播放后将其从歌单中移除。如果歌单中还有歌曲&#xff0c;则会将当前第一首歌移到最后一首。这个过程会一直重复&#xff0c;直到歌单中没有任何歌曲。 例如&#xff0c;给定歌单 [5, 3, 2, 1,…...

docker常见命令

1.启动容器 docker run 运行容器 docker run -d 守护线程运行容器 docker run -p 80:80 指定端口运行容器&#xff0c;左侧为服务器端口&#xff0c;右侧为容器端口 docker run --rm 停止容器后销毁 docker --name 指定容器名称 2.停止容器 docker stop (id/name) …...

C语言-指针作为函数返回值及二级指针

1、指针作为函数返回值 c语言允许函数的返回值是一个指针&#xff08;地址&#xff09;我们将这样的函数称为指针函数&#xff0c;下面的例子定义一了一个函数strlong&#xff08;&#xff09;&#xff0c;用来返回两个字符串中较长的一个&#xff1a; 1. #include <stdio…...

kotlin

参考资料&#xff1a; 参考资料 1、kotlin编译原理是先编译为class文件&#xff0c;再在java 虚拟机上执行2、变量 var 1 变量 val 2 常量 kotlin存在类型推导机制 var c:Int 1kotlin不存在基本类型&#xff0c;将全部使用对象类型3、函数 fun test(){}fun add(a:Int,b Int…...

【STM32】USART串口数据包

数据包的作用是将一个个单独的数据打包起来&#xff0c;方便进行多字节的数据通信 数据包格式 HEX数据包 文本数据包 数据包接收 HEX数据包接收&#xff08;固定包长&#xff09; 文本数据包接收&#xff08;可变包长&#xff09; 串口收发HEX数据包 接线图 Serial模块 se…...

开源TTS语音克隆神器GPT-SoVITS_V2版本地整合包部署与远程使用生成音频

文章目录 前言1.GPT-SoVITS V2下载2.本地运行GPT-SoVITS V23.简单使用演示4.安装内网穿透工具4.1 创建远程连接公网地址 5. 固定远程访问公网地址 前言 本文主要介绍如何在Windows系统电脑使用整合包一键部署开源TTS语音克隆神器GPT-SoVITS&#xff0c;并结合cpolar内网穿透工…...

echarts 图表resize() 报错Cannot read properties of undefined (reading ‘type‘)

原因是我使用了this.trainChart来接收数据&#xff0c;应该使用let或者var定义trainChart&#xff0c;就不会出现错误了。 错误代码如下&#xff1a; 原本 定义的echarts export default {data() {return {: null}} }现在 var trainChart null export default { }...

寻的制导律:从理论到应用的全景展示(下)

寻的制导律&#xff1a;从理论到应用的全景展示&#xff08;下&#xff09; 第六章 制导系统设计与实现 在制导系统的设计与实现过程中&#xff0c;系统需求分析、硬件与软件架构设计以及实现与测试方法是关键的三个环节。通过系统化的方法论&#xff0c;可以确保制导系统在复…...

ChatGPT 与其他 AI 技术在短视频营销中的技术应用与协同策略

摘要&#xff1a; 本文深入探讨了 ChatGPT 及其他 AI 技术在短视频营销中的应用。从技术层面剖析了这些技术如何助力短视频内容创作、个性化推荐、用户互动以及营销效果评估等多方面&#xff0c;通过具体方法分析、数据引用与大模型工具介绍&#xff0c;旨在为短视频营销领域提…...

使用PSpice进行第一个电路的仿真

1、单击【开始】菜单&#xff0c;选择【OrCAD Capture CIS Lite】。 2、单击【File】>【New】>【Project】。 3、①填入Name下面的文本框&#xff08;提示&#xff1a;项目名称不要出现汉字&#xff09;&#xff1b; ②选择【Analog or Mixed A/D】&#xff1b; ③单击【…...

SparkSQL 对 SQL 查询的优化静态优化和动态优化两大部分介绍

SparkSQL 对 SQL 查询的优化主要分为 静态优化 和 动态优化 两大部分&#xff0c;其中静态优化主要在查询编译时进行&#xff0c;而动态优化则是在查询执行过程中进行。SparkSQL 的优化包括了多种技术&#xff0c;例如 RBO&#xff08;基于规则的优化&#xff09;、CBO&#xf…...

Android 网络请求(二)OKHttp网络通信

学习笔记 OkHttp 是一个非常强大且流行的 HTTP 客户端库&#xff0c;广泛用于 Android 开发中进行网络请求。与 HttpURLConnection 相比&#xff0c;OkHttp 提供了更简单、更高效的 API&#xff0c;特别是在处理复杂的 HTTP 请求时。 如何使用 OkHttp 进行网络请求 以下是使…...

游戏引擎学习第15天

视频参考:https://www.bilibili.com/video/BV1mbUBY7E24 关于游戏中文件输入输出&#xff08;IO&#xff09;操作的讨论。主要分为两类&#xff1a; 只读资产的加载 这部分主要涉及游戏中用于展示和运行的只读资源&#xff0c;例如音乐、音效、美术资源&#xff08;如 3D 模型和…...

【机器学习】聚类算法原理详解

聚类算法 性能度量&#xff1a; 外部指标 jaccard系数&#xff08;简称JC&#xff09;FM指数&#xff08;简称FMI&#xff09;Rand指数&#xff08;简称RI&#xff09; 内部指标 DB指数&#xff08;简称DBI&#xff09;Dunn指数&#xff08;简称DI&#xff09; 距离计算&am…...