002 JavaClent操作RabbitMQ

Java Client操作RabbitMQ

文章目录

  • Java Client操作RabbitMQ
    • 1.pom依赖
    • 2.连接工具类
    • 3.简单模式
    • 4.工作队列模式(work)
      • 公平调度
      • 示例
    • 5.发布/订阅模式(fanout)
      • 交换机
      • 绑定
      • 示例代码
    • 6.路由模式(direct)
    • 7.Topic匹配模式

1.pom依赖

<!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
<dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>5.20.0</version>
</dependency>

2.连接工具类

/*** rabbitmq连接工具类* @author moshangshang*/
@Slf4j
public class RabbitMQUtil {private static final String HOST_ADDRESS="192.168.1.102";private static final Integer PORT=5672;private static final String VIRTUAL_HOST="my_vhost";private static final String USER_NAME="root";private static final String PASSWORD="root";public static Connection getConnection() throws Exception {com.rabbitmq.client.ConnectionFactory factory=new com.rabbitmq.client.ConnectionFactory();factory.setHost(HOST_ADDRESS);factory.setPort(PORT);factory.setVirtualHost(VIRTUAL_HOST);factory.setUsername(USER_NAME);factory.setPassword(PASSWORD);return factory.newConnection();}public static void main(String[] args) {Connection connection = null;try {connection = getConnection();} catch (Exception e) {log.error("get rabbitmq connection exception....",e);}finally {try {if(connection!=null){connection.close();}} catch (IOException e) {log.error("close rabbitmq connection exception....",e);}}}}

3.简单模式

生产者投递消费到队列进行消费

在这里插入图片描述

消息发送

public class Send {private final static String QUEUE_NAME = "hello";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {//声明队列/**  如果队列不存在,则会创建*  Rabbitmq不允许创建两个相同的队列名称,否则会报错。**  @params1: queue 队列的名称*  @params2: durable 队列是否持久化*  @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭*  @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。*  @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。* */channel.queueDeclare(QUEUE_NAME, false, false, false, null);String message = "Hello World!";channel.basicPublish("", QUEUE_NAME, null, message.getBytes());System.out.println(" [x] Sent '" + message + "'");}}
}

消息接收

因为希望在消费者异步监听消息到达时,当前程序能够继续执行,而不是退出。

因为提供了一个DeliverCallback回调,该回调将缓冲消息,直到准备使用它们。

public class Recv {private final static String QUEUE_NAME = "hello";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();Channel channel = connection.createChannel();channel.queueDeclare(QUEUE_NAME, false, false, false, null);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" [x] Received '" + message + "'");};channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> { });}
}

4.工作队列模式(work)

生产者直接投递消息到队列,存在多个消费者情况

  • 创建一个工作队列,用于在多个工作人员之间分配耗时的任务。
  • 工作队列(又名:任务队列)背后的主要思想是避免立即执行资源密集型任务,并必须等待其完成。相反,我们把任务安排在以后完成。我们将任务封装为消息并将其发送到队列。在后台运行的工作进程将弹出任务并最终执行作业。当你运行多个worker时,任务将在它们之间共享。
  • 这个概念在web应用程序中特别有用,因为在短的HTTP请求窗口内无法处理复杂的任务。
  • 默认情况下,消费者会进行轮询调度
  • RabbitMQ支持消息确认。消费者发送回一个确认,告诉RabbitMQ已经收到、处理了一条特定的消息,RabbitMQ可以自由删除它。
  • 如果一个消费者在没有发送ack的情况下死亡(其通道关闭、连接关闭或TCP连接丢失),RabbitMQ将理解消息未完全处理,并将其重新排队。如果同时有其他消费者在线,它将迅速将其重新传递给另一个消费者。这样,即使worker偶尔挂掉,也可以确保没有信息丢失。
  • 消费者交付确认时强制执行超时(默认为30分钟)。这有助于检测一直没有确认的消费者。
  • 默认情况下,手动消息确认已打开。在前面的示例中,我们通过autoAck=true标志明确地关闭了它们。一旦我们完成了一项任务,是时候将此标志设置为false并从worker发送适当的确认了。

在这里插入图片描述

公平调度

由于默认轮询调度,有些任务执行时间长,有些短,所以会导致部分worker压力大

使用预取计数=1设置的basicQos方法。这条消息告诉RabbitMQ一次不要给一个worker发送多条消息。在处理并确认前一条消息之前,不要向worker发送新消息。相反,它会将其发送给下一个不忙的worker。

int prefetchCount = 1;
channel.basicQos(prefetchCount);

示例

public class WorkProvider {private static final String TASK_QUEUE_NAME = "work_queue";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);for (int i = 0; i < 8; i++) {String message = String.valueOf(i);channel.basicPublish("", TASK_QUEUE_NAME,MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes(StandardCharsets.UTF_8));System.out.println(" 消息发送 :'" + i + "'");}}}
}
public class WorkerConsumer1 {private static final String TASK_QUEUE_NAME = "work_queue";public static void main(String[] argv) throws Exception {final Connection connection = RabbitMQUtil.getConnection();final Channel channel = connection.createChannel();channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);System.out.println(" 消息监听中。。。。。。");//控制ack流速,表示每次进行ack确认前只会处理一条消息//channel.basicQos(1);DeliverCallback deliverCallback = (consumerTag, delivery) -> {//获取消息String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println("worker1 消息消费:'" + message + "'");try {doWork(message);} finally {System.out.println(" 执行结束。。");//消息确认,根据消息序号(false只确认当前一个消息收到,true确认所有比当前序号小的消息(成功消费,消息从队列中删除 ))channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);}};//设置自动应答channel.basicConsume(TASK_QUEUE_NAME, false, deliverCallback, consumerTag -> { });}}

消费者1的方法处理

  private static void doWork(String task) {try {Thread.sleep(1000);} catch (InterruptedException ignored) {Thread.currentThread().interrupt();}}

消费者2的方法处理

  private static void doWork(String task) {return;}

启动两个worker消费者,执行结果如下(轮询):

在这里插入图片描述
在这里插入图片描述

若设置公平调度

channel.basicQos(1);

测试结果:

在这里插入图片描述
在这里插入图片描述

5.发布/订阅模式(fanout)

  • 不同于工作队列,同一消息在所有消费者共享,但只能有一个消费者消费,而发布订阅则会将同一消息发送给多个消费者,则将消息广播给所有订阅者

  • 在之前的模式中,都是直接将消息发送给队列,然后从队列消费,事实上之前使用了一个默认的交换机,即“”空字符串的

  • RabbitMQ消息传递模型的核心思想是生产者从不直接向队列发送任何消息。实际上,很多时候,生产者甚至根本不知道消息是否会被传递到任何队列。

  • 相反,生产者只能向exchange发送消息。exchange是一件非常简单的事情。它一方面接收来自生产者的消息,另一方面将它们推送到队列。exchange必须确切地知道如何处理它收到的消息。

在这里插入图片描述

将消息生产投递到exchange,由交换机去投递消息到队列

交换机

有几种exchange类型可供选择:directtopicheadersfanout。我们将专注于最后一个fanout

//创建交换机名称为logs
channel.exchangeDeclare("logs", "fanout");/*** exchange:交换机的名称* type:交换机的类型* durable 队列是否持久化* autoDelete:是否自动删除,(当该交换机上绑定的最后一个队列解除绑定后,该交换机自动删除)* internal:是否是内置的,true表示内置交换器。(则无法直接发消息给内置交换机,只能通过其他交换机路由到该交换机)* argument:其他一些参数*/channel.exchangeDeclare(EXCHANGE_NAME,"fanout",false,false,false,null);

第一个参数是exchange的名称。空字符串表示默认或未命名的交换:消息将被路由到routingKey指定名称的队列(如果存在)。

channel.basicPublish( "logs", "", null, message.getBytes());

绑定

我们已经创建了一个fanout交换机和一个队列。现在我们需要告诉exchange向我们的队列发送消息。交换和队列之间的关系称为绑定。

交换机会向绑定的队列通过路由key将消息路由到指定的队列中,fanout分发不需要路由key

在这里插入图片描述

//其中,第一个参数为绑定的队列,第二个参数为绑定的交换机,第三个参数为路由key
channel.queueBind(queueName, "logs", "");
#列出所有得绑定
rabbitmqctl list_bindings

示例代码

public class FanoutProvider {//声明交换机public static final String EXCHANGE_NAME="fanoutTest";//声明队列public static final String QUEUE_NAME1="queue_name1";public static final String QUEUE_NAME2="queue_name2";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {//声明交换机channel.exchangeDeclare(EXCHANGE_NAME,"fanout",false,false,false,null);//声明队列channel.queueDeclare(QUEUE_NAME1,false,false,false,null);channel.queueDeclare(QUEUE_NAME2,false,false,false,null);//进行队列绑定channel.queueBind(QUEUE_NAME1,EXCHANGE_NAME,"");channel.queueBind(QUEUE_NAME2,EXCHANGE_NAME,"");String message = "fanout模式消息推送。。。。。";//消息推送//参数说明:交换机,路由key/队列,消息属性,消息体channel.basicPublish(EXCHANGE_NAME, "", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes(StandardCharsets.UTF_8));System.out.println(" 消息发送 :'" +message + "'");}}}
public class FanoutConsumer1 {public static final String EXCHANGE_NAME="fanoutTest";public static final String QUEUE_NAME1="queue_name1";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();//创建信道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, "fanout");//绑定队列channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME, "");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" fanout 消费者1:'" + message + "'");};channel.basicConsume(QUEUE_NAME1, true, deliverCallback, consumerTag -> {});}}
public class FanoutConsumer2 {public static final String EXCHANGE_NAME="fanoutTest";public static final String QUEUE_NAME2="queue_name2";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();//创建信道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, "fanout");//绑定队列channel.queueBind(QUEUE_NAME2, EXCHANGE_NAME, "");DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" fanout 消费者2:'" + message + "'");};channel.basicConsume(QUEUE_NAME2, true, deliverCallback, consumerTag -> { });}}

6.路由模式(direct)

由交换机通过路由key绑定key进行消息推送,也可以将同一个路由key绑定到多个队列或所有队列,此时相当于fanout

如果推送消息的路由key不存在,则该消息会丢弃

public class DirectProvider {public static final String EXCHANGE_NAME="direct-exchange";public static final String QUEUE_NAME1="direct-queue";public static final String ROUTING_KEY="change:direct";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {//声明交换机channel.exchangeDeclare(EXCHANGE_NAME,"direct",false,false,false,null);//声明队列channel.queueDeclare(QUEUE_NAME1,false,false,false,null);String message = "direct模式消息推送。。。。。";//参数说明:交换机,路由key/队列,消息属性,消息体channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes(StandardCharsets.UTF_8));System.out.println(" 消息发送 :'" +message + "'");}}}
public class DirectConsumer {public static final String EXCHANGE_NAME="direct-exchange";public static final String QUEUE_NAME1="direct-queue";public static final String BINDING_KEY="change:direct";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();//创建信道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, "direct");//绑定队列channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME, BINDING_KEY);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" direct 消费者1:'" + message + "'");};channel.basicConsume(QUEUE_NAME1, true, deliverCallback, consumerTag -> { });}}

7.Topic匹配模式

  • 发送到主题交换的消息不能有任意的路由key,它必须是一个由点分隔的单词列表。单词可以是任何东西,但通常它们指定了与消息相关的一些特征。一些有效的路由key示例:stock.usd.nyse、nyse.vmw、quick.orange.rabbit。路由密钥中可以有任意多的单词,最多255个字节。
  • 绑定key也必须采用相同的形式。topic交换机背后的逻辑类似于direct交换机,使用特定路由key发送的消息将被传递到所有使用绑定key绑定的所有队列。但是,绑定密钥有两个重要的特殊情况:
  • *(星号)只能代替一个单词
  • #(hash)可以替代零个或多个单词
public class TopicProvider {public static final String EXCHANGE_NAME="topic-exchange";public static final String QUEUE_NAME1="topic-queue";public static final String ROUTING_KEY="com.orange.test";public static final String ROUTING_KEY2="com.orange.test.aaa";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();try (Channel channel = connection.createChannel()) {//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC,false,false,false,null);//声明队列channel.queueDeclare(QUEUE_NAME1,false,false,false,null);String message1 = "topic test模式消息推送。。。。。";String message2 = "topic test.aaa模式消息推送。。。。。";//参数说明:交换机,路由key/队列,消息属性,消息体channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY, MessageProperties.PERSISTENT_TEXT_PLAIN, message1.getBytes(StandardCharsets.UTF_8));channel.basicPublish(EXCHANGE_NAME, ROUTING_KEY2, MessageProperties.PERSISTENT_TEXT_PLAIN, message2.getBytes(StandardCharsets.UTF_8));System.out.println(" 消息发送 :'" +message1 + "'");System.out.println(" 消息发送 :'" +message2 + "'");}}}
public class TopicConsumer {public static final String EXCHANGE_NAME="topic-exchange";public static final String QUEUE_NAME1="topic-queue";public static final String BINDING_KEY="*.orange.#";public static void main(String[] argv) throws Exception {Connection connection = RabbitMQUtil.getConnection();//创建信道Channel channel = connection.createChannel();//声明交换机channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);//绑定队列channel.queueBind(QUEUE_NAME1, EXCHANGE_NAME, BINDING_KEY);DeliverCallback deliverCallback = (consumerTag, delivery) -> {String message = new String(delivery.getBody(), StandardCharsets.UTF_8);System.out.println(" topic 消费者1:'" + message + "'");};channel.basicConsume(QUEUE_NAME1, true, deliverCallback, consumerTag -> { });}}

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

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

相关文章

基于yolov8的无人机检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的无人机检测系统是一项前沿技术&#xff0c;结合了YOLOv8深度学习模型的强大目标检测能力与无人机的灵活性。YOLOv8作为YOLO系列的最新版本&#xff0c;在检测精度和速度上均有显著提升&#xff0c;特别适用于复杂和高动态的场景。 该系统通过捕获实…

quartz 搭配SQL Server时出现deadlock的解决方案

背景&#xff1a; 最近在折腾换OA系统&#xff0c;遇到了一个很诡异的事情。在测试阶段&#xff0c;OA系统经常莫名地宕机&#xff0c;停止响应。查下来&#xff0c;发现是数据库出现大量死锁&#xff0c;耗尽了连接池。出现问题的语句是一样的&#xff0c;问题锁定在QRTZ_TRI…

学习使用在windows系统上安装vue前端框架以及环境配置图文教程

学习使用在windows系统上安装vue前端框架以及环境配置图文教程 1、安装nodejs2、安装vue3、安装Vue-cli脚手架4、安装高版本5、创建vue项目6、启动项目7、配置开发环境8、发布项目 1、安装nodejs 点我查看教程 2、安装vue winR&#xff0c;打开cmd cnpm install vue -g表示安…

COMDEL电源维修CLX2500康戴尔射频电源维修

美国COMDEL射频电源维修常见型号包括&#xff1a;CLX2750&#xff1b;CLX2500&#xff1b;CLX-600H&#xff1b;CX600AS&#xff1b;CX-5000S&#xff1b;CX-3500S&#xff1b;CX-2500S&#xff1b;CV500&#xff1b;CDX2000等。 Comdel成立于1966年&#xff0c;总部设在马萨诸…

pdf转jpg工具分享,4款搞定90%的PDF转格式

PDF转换真的是要学会的技能&#xff0c;我最近遇到了一个难题&#xff1a;我需要将一些PDF文件转换成JPG格式&#xff0c;以便在不同的设备上查看和编辑。我尝试了几个不同的工具&#xff0c;今天&#xff0c;我就来和大家分享一下我的使用体验&#xff0c;希望能帮到和我一样在…

企业社会信任数据,信任指数(2004-2022年)

企业社会信任是指公众对企业及其行为的信任程度&#xff0c;这种信任度是基于企业的商业行为、产品质量、服务态度、信息披露透明度和社会责任履行等多方面因素的综合评估。 2004年&#xff0d;2022年 企业社会信任数据&#xff08;大数据&#xff09;https://download.csdn.n…

Netty笔记06-组件ByteBuf

文章目录 概述ByteBuf 的特点ByteBuf的组成ByteBuf 的生命周期 ByteBuf 相关api1. ByteBuf 的创建2. 直接内存 vs 堆内存3. 池化 vs 非池化4. ByteBuf写入代码示例 5. ByteBuffer扩容6. ByteBuf 读取7. retain() & release()TailContext 释放未处理消息逻辑HeadContext 8. …

电脑与电脑之间怎么快速传输文件?

若两台电脑在同一局域网&#xff0c;可以使用Windows远程桌面传输文件&#xff0c;或者使用远程看看这款免费的远程桌面软件&#xff0c;它支持在不同的网络之间传输文件&#xff0c;而且速度快、安全性高。 步骤1. 在两台电脑上下载、安装并运行远程看看。 步骤2. 注册一个远…

CGAL 从DSM到DTM filtering

CGAL 从DSM到DTM filtering 上一节通过连通区域计算并将连通信息保存到三角面片中&#xff0c;获取了多个连通区域&#xff0c;本节将设置阈值将建筑物区域移除&#xff0c;生成一个最初的DTM。 建筑物区域去除 设置阈值为min_size&#xff0c;遍历三角面片&#xff0c;对连…

macOS系统Homebrew工具安装及使用

1.打开Homebrew — The Missing Package Manager for macOS (or Linux) 2.复制安装命令到终端执行 复制 执行 3. 开始自动安装过程 4.安装成功 5.使用brew安装wget工具

基于SSM的在线家教管理系统(含源码+sql+视频导入教程+文档+PPT)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的在线家教管理系统拥有三个角色 管理员&#xff1a;用户管理、教师管理、简历管理、申请管理、课程管理、招聘教师管理、应聘管理、评价管理等 教师&#xff1a;课程管理、应聘…

掌握ZooKeeper的业务使用场景,ZooKeeper如何实现分布式锁

1. ZooKeeper分布式锁 1.1 排他锁实现分布式锁 面试官&#xff1a;知道Zookeeper有什么应用场景吗? 目前地球村里大型公司部署的分布式技术&#xff0c;绝大部分都是由Zookeeper提供底层的技术支持&#xff0c;所以Zookeeper多么重要就不用我多说了吧。 我们可以利用Zookeep…

STM32使用 :串口的接收与发送

一、串口 在 STM32 中&#xff0c;串口&#xff08;UART&#xff0c;通用异步收发传输器&#xff09;是用于串行通信的外设。它在嵌入式系统中的作用非常广泛&#xff0c;主要包括几个方面 数据通信 串口用于微控制器与其他设备之间的数据传输。这些设备可以是其他微控制器、…

mysql的zip解压缩版安装

文章目录 一、MySQL下载二、mysql解压缩版安装1、解压缩2、设置环境变量3、mysql初始化4、安装mysql服务5、启动mysql服务6、连接mysql7、修改初始密码8、安装完成 一、MySQL下载 下载网址&#xff1a;MySQL下载 本文以mysql8.4.2版本为例下载解压缩版。 二、mysql解压缩版安…

MS SQL Server 实战 排查多列之间的值是否重复

目录 需求 范例运行环境 数据样本设计 功能实现 上传EXCEL文件到数据库 SQL语句 小结 需求 在日常的应用中&#xff0c;排查列重复记录是经常遇到的一个问题&#xff0c;但某些需求下&#xff0c;需要我们排查一组列之间是否有重复值的情况。比如我们有一组题库数据&…

STM32的寄存器深度解析

目录 一、STM32 寄存器概述 二、寄存器的定义与作用 三、寄存器分类 1.内核寄存器 2.外设寄存器 四、重要寄存器详解 1.GPIO 相关寄存器 2.定时器相关寄存器 3.中断相关寄存器 4.RCC 相关寄存器 五、寄存器操作方法 1.直接操作寄存器 2.使用库函数操作寄存器 六…

数字高程模型DEM详细应用分析

DEM在各个领域都有广泛应用&#xff0c;它不仅仅是一张“高程地图”&#xff0c;更是地理分析、模拟和预测的重要工具。 一、地形分析 在地形分析中&#xff0c;DEM是不可或缺的工具. 1 坡度分析&#xff08;Slope Analysis&#xff09; 定义&#xff1a;坡度是指地形表面的…

go语言的基本语法

学了go语言但是一直没整理。。。那怎么证明我学了&#xff1f;如果学了之后忘了怎么复习&#xff1f;遂诞生这几篇&#xff0c;当作Linux中间的小插曲 整理一下go语言的基本语法&#xff1a; package mainimport ("bufio""fmt""os" ) 在使用对…

模拟退火算法(SA算法)求解实例---旅行商问题 (TSP)

目录 一、采用SA求解 TSP二、 旅行商问题2.1 实际例子&#xff1a;求解 6 个城市的 TSP2.2 **求解该问题的代码**2.3 代码运行过程截屏2.4 代码运行结果截屏&#xff08;后续和其他算法进行对比&#xff09; 三、 如何修改代码&#xff1f;3.1 减少城市坐标&#xff0c;如下&am…

文件格式转换:EXCEL和CSV文件格式互相转换

目录 1.EXCEl和CSV文件格式互相转换1.1首先安装所需的Python包1.2excel转换为csv代码如下&#xff1a;1.3csv转换为excel代码如下&#xff1a; 由于excel文件在数学建模数据处理当中的局限性&#xff0c;我们通常把excel文件转换为csv文件来处理&#xff0c;下面是相关的代码&a…