Spring - 6 ( 9000 字 Spring 入门级教程 )

一: SpringBoot 配置文件

1.1 配置文件作用

配置文件通常是一个文本文件,其中包含了程序或系统的各种设置、选项和参数。比如C:\Users, C:\Windows 文件夹, 以及各种 .config, .xml 文件

配置文件主要是为了解决硬编码(代码写死)带来的问题, 把可能会发生改变的信息, 放在⼀个集中的地方, 当我们启动某个程序时, 应用程序从配置文件中读取数据, 并加载运行,它们允许开发人员将应用程序的配置信息从源代码中分离出来,从而提高代码的可维护性和灵活性。

1.2 SpringBoot 配置文件

SpringBoot 支持配置文件, 同时也并定义了配置文件的格式,很多项目或者框架的配置信息就放在配置文件中, 比如:

  • 项目的启动端口
  • 数据库的连接信息(包含用户名和密码的设置)
  • 第三方系统的调用密钥等信息
  • ⽤于发现和定位问题的普通日志和异常日志等.

1.3 配置文件快速入手

SpringBoot 内置了 Tomcat 服务器, 默认端口号是 8080, 但是用户电脑上 8080 端口号有可能就被其他应用程序占用了,此时我们就需要通过配置文件修改项目的启动端口号

SpringBoot 在创建项目时, 就已经帮我们创建了配置文件:
在这里插入图片描述

  1. 修改 application.properties 文件
server.port=9090
  1. 重新运行程序, 观察日志

在这里插入图片描述

显示 Tomcat 启动端口号为 9090

  1. 访问程序: http://127.0.0.1:9090/login.html

在这里插入图片描述

此时: http://127.0.0.1:808/login.html 就不能再访问了

1.4 配置文件的格式

Spring Boot 配置文件有以下三种格式:

  • application.properties
  • application.yml(yaml 的简写,用法和 yaml 一模一样)
  • application.yaml

如图所示:

在这里插入图片描述

当应用程序启动时, Spring Boot 会自动从 classpath 路径找到并加载 application.properties 和 application.yaml 或者 application.yml ⽂件,我们可以通过 spring.config.name 指定文件路径和名称

注意:

  1. 理论上讲 .properties 和 .yml 可以并存在于⼀个项目中,当 .properties 和 .yml 并存时,两个配置都会加载. 如果配置文件内容有冲突, 以 .properties 为主

  2. 虽然理论上来讲 .properties 可以和 .yml 共存,但实际的业务当中,我们通常会采取⼀种统⼀的配置文件格式,这样可以更好的维护(降低故障率).

二: properties 配置文件说明

properties 配置文件是最早期的配置文件格式,也是创建 SpringBoot 项目默认的配置文件

2.1 properties 基本语法

properties 是以键值的形式配置的,key 和 value 之间是以"="连接的,如:

# 配置项⽬端⼝号
server.port=8080

#配置数据库连接信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb?characterEncoding=utf8&
spring.datasource.username=root
spring.datasource.password=root

注意:配置文件中使用 “#” 来添加注释信息。

2.2 读取配置文件

在项目中,如果想要主动的读取配置文件中的内容,可以使用 @Value 注解。@Value 注解使用 " ${} " 的格式读取

  1. properties 配置如下:
mykey.key1 = bite
  1. 读取程序代码:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.RestController;

@RestController
public class PropertiesController {

    @Value("${mykey.key1}")
    private String key1;

    @RequestMapping("/key")
    public String key() {
        return "读取到值:" + key1;
    }

@Value(“${mykey.key1}”)注解的作用是告诉 Spring 框架在运行时去获取名为 mykey.key1 的属性值,并将其注入到 key1 变量中。

最终执行效果:
在这里插入图片描述

2.3 properties 缺点分析

properties 配置是以 key-value 的形式配置的,如下图所示:

在这里插入图片描述

从上述配置 key 看出,properties 配置文件中会有很多的冗余的信息,比如这些:

在这里插入图片描述

想要解决这个问题,就要使用 yml 配置文件的格式化了.

三:yml 配置文件说明

3.1 yml 基本语法

yml 是树形结构的配置文件,它的基础语法是"key: value",key 和 value 之间使用英文冒号加空格的方式组成,空格不可省略

在这里插入图片描述

因为第⼀项的配置为正确的,所以 key 也是高亮显示的

3.2 使用 yml 连接数据库

spring:
  datasource:
    url: jdbc:mysql://127.0.0.0:3306/dbname?characterEncoding=utf8&useSSL=false
    username: root
    password: root

yml 和 properties 连接数据库的配置对比:

  1. properties

在这里插入图片描述

  1. yml

在这里插入图片描述

四:yml 进阶使用

4.1 yml 配置不同数据类型及 null

# 字符串
string.value: Hello

# 布尔值,true或false
boolean.value: true
boolean.value1: false

# 整数
int.value: 10

# 浮点数
float.value: 3.14159

# Null,~代表null
null.value: ~

#  空字符串直接后⾯什么都不加就可以了, 但这种⽅式不直观, 更多的表⽰是使⽤引号括起来
empty.value: ''

4.2 yml 配置读取

yml 读取配置的方式和 properties 相同,使用 @Value 注解即可,实现代码如下:

  1. yml 配置:
string:
	hello: bite
  1. 读取程序代码:
@RestController
public class ReadYml {
    @Value("${string.hello}")
    private String hello;
    
    @RequestMapping("/ymlKey")
    public String key(){
        return "读取到值:"+hello;
    }
}

访问: http://127.0.0.1:8080/ymlKey

在这里插入图片描述

4.3 value 值加单双引号问题

字符串默认不用加上单引号或者双引号,如果加英文的单双引号可以表示特殊的含义。

举个例子:

  1. yml 配置
string:
  str1: Hello \n Spring Boot.
  str2: 'Hello \n Spring Boot.'
  str3: "Hello \n Spring Boot."
  1. 读取程序代码
@RestController
public class ReadYml {
    @Value("${string.str1}")
    private String str1;
    
    @Value("${string.str2}")
    private String str2;
    
    @Value("${string.str3}")
    private String str3;
    
    @RequestMapping("/yml")
    public String readYml(){
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
        return "yml";
    }
}

以上程序的执行结果如下图所示:

在这里插入图片描述

从上述结果可以看出:

  • 字符串默认不用加上单引号或者双引号。
  • 单引号会转义特殊字符,使其失去特殊功能, 始终是⼀个普通的字符串.
  • 双引号不会转义字符串里面的特殊字符, 特殊字符会表示本身的含义.

注意:此处的转义理解起来会有些拗口, \n 本意表示的是换行

  • 使用单引号会转义, 就是说, \n 不再表示换行了, 二是表示⼀个普通的字符串
  • 使用双引号不会转义, 表示 \n 表示的是它本身的含义, 就是换行

4.4 配置对象

我们还可以在 yml 中配置对象

  1. yml 配置
student:
  id: 1
  name: Java
  age: 18

或者是使用行内写法(与上面写法的作用是一样的):

student: {id: 1,name: Java,age: 18}

这个时候就不能用 @Value 来读取配置中的对象了,此时要使用另⼀个注解 @ConfigurationProperties 来读取

  1. 读取程序代码
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@ConfigurationProperties(prefix = "student")
@Component
@Data
public class Student {
    private int id;
    private String name;
    private int age;
}

prefix = “student” 意味着这个注解将会查找 “student” 的配置项,并将它们映射到被注解的类的属性上。

配置文件中的属性是 student.id、student.name 和 student.age。使用了 @ConfigurationProperties(prefix = “student”) 注解之后,Spring Boot 会根据名字自动将这些属性值注入到 Student 类的对应属性 id、name 和 age 中。

  1. 访问 http://127.0.0.1:8080/readStudent

在这里插入图片描述

4.5 配置集合

配置文件也可以配置 list 集合,如下所示:

  1. yml 配置
dbtypes:
  name:
    - mysql
    - sqlserver
    - db2

集合的读取和对象⼀样,也是使用 @ConfigurationProperties 来读取的

  1. 读取程序代码
@Component
@ConfigurationProperties("dbtypes")
@Data
public class ListConfig {
    private List<String> name;
}

4.6 配置 Map

配置文件也可以配置 map,如下所示:

  1. yml 配置
maptypes:
  map:
    k1: kk1
    k2: kk2
    k3: kk3

或者是使用行内写法

maptypes: {map: {k1: kk1,k2: kk2, k3: kk3}}

Map 的读取和对象⼀样,也是使用 @ConfigurationProperties 来读取的

  1. 读取程序代码
@Component
@ConfigurationProperties("maptypes")
@Data
public class MapConfig {
	private HashMap<String,String> map;
}

4.7 yml 优缺点

优点:

  1. 可读性高,写法简单, 易于理解
  2. 支持更多的数据类型, 可以简单表达对象, 数组, List,Map 等数据形态.
  3. 支持更多的编程语言, 不止是 Java 中可以使用, 在 Golang, Python, Ruby, JavaScript 中也可以使用

缺点:

  1. 不适合写复杂的配置文件
  2. 对格式有较强的要求(⼀个空格可能会引起⼀场血案)

举个例子:

  1. properties 格式如下
keycloak.realm = demo
keycloak.resource = fm-cache-cloud
keycloak.credentials.secret = d4589683-Oce7-4982-bcd3
keycloak.security[0].authRoles[0]= user
keycloak.security[0].collections[0].name = ssologinurl
keycloak.security[0].collections[0].patterns[0] = /login/*
  1. yml 文件格式:
keycloak:
  realm: demo
  resource: fm-cache-cloud
  credentials:
    secret: d4589683-Oce7-4982-bcd3
  security:
    - authRoles:
        - user
	collections:
	  - name: ssologinurl
	    patterns:
	      - /login/*

五: 综合性练习

下面我们来做一个验证码案例

在这里插入图片描述

验证码的实现方式很多, 网上也有比较多的插件或者工具包可以使用, 咱们选择使用 Google 的开源项目 Kaptcha 来实现.

5.1 Kaptcha 插件介绍

Kaptcha 是 Google 的⼀个⾼度可配置的实用验证码生成工具,网上有很多人甚至公司基于 Google 的 kaptcha 进行了⼆次开发. 我们直接选择⼀个适配 SpringBoot 的开源项目

  • 项目链接:https://github.com/oopsguy/kaptcha-spring-boot

由于作者的文档写的不是很全, 下⾯简单介绍下插件的使用

5.2 原理

验证码可以客户端生成, 也可以服务器生成.,对于普通的字符验证码, 后端通常分两部分.

  1. 生成验证码内容, 根据验证码内容和干扰项等, 生成图片, 返回给客户端
  2. 把验证码内容存储起来, 校验时取出来进行对比.

kaptcha 插件选择把验证码存储在 Session 里

5.3 引入依赖

<dependency>
	<groupId>com.oopsguy.kaptcha</groupId>
	<artifactId>kaptcha-spring-boot-starter</artifactId>
	<version>1.0.0-beta-2</version>
</dependency>

5.4 生成验证码

该插件提供了两种方式生成验证码:

  1. 通过代码来生成
  2. 通过配置文件来生成验证码

我们采用配置文件的形式来生成验证码

Kaptcha 详细配置:

配置项配置说明默认值
kaptcha.border图片边框,合法值:yes , noyes
kaptcha.border.color边框颜色,合法值: r,g,b 或者 white,black,blue.black
kaptcha.image.width图片宽200
kaptcha.image.height图片高50
kaptcha.producer.impl图片实现类com.google.code.kaptcha.impl.DefaultKaptcha
kaptcha.textproducer.impl文本实现类com.google.code.kaptcha.text.impl.DefaultTextCreator
kaptcha.textproducer.char.string文本集合,验证码值从此集合中获取abcde2345678gfynmnpwx
kaptcha.textproducer.char.length验证码长度5
kaptcha.textproducer.font.names字体Arial, Courier
kaptcha.textproducer.font.size字体大小40px
kaptcha.textproducer.font.color字体颜色,合法值: r,g,b 或者 white,black,blue.black
kaptcha.textproducer.char.space文字间隔2
kaptcha.noise.impl干扰实现类com.google.code.kaptcha.impl.DefaultNoise
kaptcha.noise.color干扰颜色,合法值: r,g,b 或者 white,black,blue.black
kaptcha.obscurificator.impl图片样式 水纹,鱼眼,阴影水纹
kaptcha.background.impl背景实现类com.google.code.kaptcha.impl.DefaultBackground
kaptcha.background.clear.from背景颜色渐变,开始颜色light grey
kaptcha.background.clear.to背景颜色渐变,结束颜色white
kaptcha.word.impl文字渲染器com.google.code.kaptcha.text.impl.DefaultWordRenderer
kaptcha.session.keysession keyKAPTCHA_SESSION_KEY
kaptcha.session.datesession dateKAPTCHA_SESSION_DATE

我们可以使用 kaptcha.items 配置多个验证码生成器,kaptcha.items 是⼀个 Map, key 为验证码生成器名称, value 为验证码生成器的配置

kaptcha:
  items:
    # home captcha
    home:
      path: /homeaptcha
      session:
        key: HOME_KAPTCHA_KEY
        date: HOME_KAPTCHA_SESSION_DATE
    # admin captcha
    admin:
      path: /admin/captcha
      session:
        key: ADMIN_KAPTCHA_SESSION_KEY
        date: ADMIN_KAPTCHA_SESSION_DATE

配置说明:

在这里插入图片描述

配置后, 可以直接访问 http://XXXX:port/home/captcha 即可生成验证码

5.5 需求

界面如下图所示:

  1. 页面生成验证码
  2. 输入验证码, 点击提交, 验证用户输入验证码是否正确, 正确则进行页面跳转

在这里插入图片描述

5.6 准备工作

创建项目, 引入 Spring MVC 的依赖包, 把前端页面放在项目中

在这里插入图片描述

5.7 约定前后端交互接口

需求分析:后端需要提供两个服务:

  • 生成验证码, 并返回验证码
  • 校验验证码是否正确: 校验验证码是否正确.

接口定义:

  1. 生成验证码

请求:

GET /admin/captcha

响应: 图片内容

在这里插入图片描述

浏览器给服务器发送⼀个 GET /admin/captcha 这样的请求, 服务器就会返回⼀个图片, 浏览器会将图片显示在页面上

  1. 校验验证码是否正确

请求: /admin/check

POST /admin/check
captcha=xn8d 

captcha:用户输入的验证码

响应:根据用户输⼊的验证码, 校验验证码是否正确. true: 验证成功. false: 验证失败.

true

5.8 实现服务器端代码

  1. 引⼊依赖
<dependency>
    <groupId>com.oopsguy.kaptcha</groupId>
    <artifactId>kaptcha-spring-boot-starter</artifactId>
    <version>1.0.0-beta-2</version>
</dependency>
  1. 通过配置创建验证码生成器
kaptcha:
  border:
    enabled: true
  image:
    height: 50
    width: 160
  text-producer:
    character:
      length: 4
    font:
      color: blue
  items:
    home:
      path: /admin/captcha
      session:
        key: KAPTCHA_SESSION_KEY
        date: KAPTCHA_SESSION_DATE
  1. 启动项目, 访问 http://127.0.0.1:8080/admin/captcha , 显示验证码

在这里插入图片描述

  1. 验证码校验
import com.google.code.kaptcha.Constants;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
import java.util.Date;

@RestController
public class KaptchaController {
    private final static long VALID_MILLIS_TIME = 60 * 1000;

    @RequestMapping("/check")
    public boolean checkHomeCaptcha(String captcha, HttpSession session) {
        if (!StringUtils.hasLength(captcha)) {
            return false;
        }

        String savedCaptcha = (String) session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
        Date sessionDate = (Date) session.getAttribute(Constants.KAPTCHA_SESSION_DATE);

        if (captcha.equalsIgnoreCase(savedCaptcha)) {
            if (sessionDate == null || System.currentTimeMillis() - sessionDate.getTime() < VALID_MILLIS_TIME) {
                return true;
            }
            return false;
        }
        return false;
    }
}

5.9 调整前端页面代码

  1. 修改 index.html,补充 ajax 代码, 点击提交按钮, 发送请求去服务端进行校验
$("#checkCaptcha").click(function () {
    $.ajax({
        url: "/check",
        type: "post",
        data: { captcha: $("#inputCaptcha").val() },
        success: function (result) {
            if (result) {
                location.href = "success.html";
            } else {
                alert("验证码错误");
                $("#inputCaptcha").val("");
            }
        }
    });
});

5.10 运行测试

  1. 通过 http://127.0.0.1:8080/index.html 访问服务

在这里插入图片描述

  1. 输入验证码, 验证成功

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

排序算法--希尔排序

前提&#xff1a; 排序算法——直接插入排序-CSDN博客 希尔排序(Shell Sort)是插入排序的一种。是直接插入排序算法的Plus版。该方法又称缩小增量排序&#xff0c;是D.L.Shell于1959年提出。要想学好希尔排序&#xff0c;直接插入排序一定要学好&#xff0c;没学过的&#xff0…

chrome extension插件替换网络请求中的useragent

感觉Chrome商店中的插件不能很好的实现自己想要的效果,那么就来自己动手吧。 本文以百度为例: 一般来说网页请求如下: 当前使用的useragent是User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safar…

【Flask 系统教程 4】Jinjia2模版和语法

Jinjia2 模板 模板的介绍 Jinja2 是一种现代的、设计优雅的模板引擎&#xff0c;它是 Python 的一部分&#xff0c;由 Armin Ronacher 开发。Jinja2 允许你在 HTML 文档中嵌入 Python 代码&#xff0c;以及使用变量、控制结构和过滤器来动态生成内容。它的语法简洁清晰&#…

java发送请求2次开发-get请求json

因为你请求参数不为空&#xff0c;接口都会把这个参数带上 所以借鉴HttpPost类 继承这个类&#xff0c; 这个类是可以带消息的 httpgetwithentity&#xff0c;httpget请求带上消息 复写 构造方法复制过来进行使用 二次开发类让其get请求时可以发送json

IOS上线操作

1、拥有苹果开发者账号 2、配置证书&#xff0c;进入苹果开发者官网&#xff08;https://developer.apple.com/&#xff09; 3、点击账户&#xff08;account&#xff09;&#xff0c;然后创建一个唯一的标识符 4、点击"Identifiers"&#xff0c;然后点击"&qu…

SpringBoot的ProblemDetails

1.RFC 7807 之前的项目如果出现异常&#xff0c;默认跳转到error页面。或者是抛出500 异常。 但是对于前后端分离的项目&#xff0c;Java程序员不负责页面跳转&#xff0c;只需要 把错误信息交给前端程序员处理即可。而RFC 7807规范就是将异常 信息转为JSON格式的数据。这个…

android init进程启动流程

Android系统完整的启动流程 android 系统架构图 init进程的启动流程 init进程启动服务的顺序 bool Service::Start() {// Starting a service removes it from the disabled or reset state and// immediately takes it out of the restarting state if it was in there.flags_…

每天五分钟深度学习框架pytorch:如何创建多维Tensor张量元素?

本文重点 上节课程我们学习了如何创建Tensor标量,我们使用torch.tensor。本节课程我们学习如何创建Tensor向量,我们即可以使用torch.Tensor又可以使用torch.tensor,下面我们看一下二者的共同点和不同点。 Tensor张量 tensor张量是一个多维数组,零维就是一个点(就是上一…

llama-factory/peft微调千问1.5-7b-chat

目标 使用COIG-CQIA数据集和通用sft数据集对qwen1.5-7b-chat进行sft微调,使用公开dpo数据集进行dpo对齐。学习千问的长度外推方法。 一、训练配置 使用Lora方式, 将lora改为full即可使用全量微调。 具体的参数在 该框架将各个参数、训练配置都封装好了,直接使用脚本,将数…

毫米波雷达多人呼吸心跳检测MATLAB仿真

本文基于TI的IWR1642毫米波雷达 2T4R MIMO阵列&#xff0c;通过实际采集数据算法仿真&#xff0c;实现多人呼吸心跳检测。 文章末尾给出了本文的仿真代码。 主要内容包含&#xff1a; &#xff08;1&#xff09;雷达参数设定 &#xff08;2&#xff09;ADC数据导入 &#xff08…

Windows Server 安全策略配置

前言 Windows Server是由微软开发的一种操作系统&#xff0c;主要用于在企业或机构的服务器上运行。它提供了一系列的功能和工具&#xff0c;旨在提高服务器的性能、可靠性、安全性和管理性。 特点 强大的性能&#xff1a;Windows Server具有高度优化的内核和资源管理&#x…

【MySQL | 第十篇】重新认识MySQL索引匹配过程

文章目录 10.重新认识MySQL索引匹配过程10.1匹配规则10.2举例&#xff1a;联合索引遇到范围查询&#xff08;>、<、between、like&#xff09;10.2.1例子一&#xff1a;>10.2.2例子二&#xff1a;>10.2.3例子三&#xff1a;between10.2.4例子四&#xff1a;like 10…

SQL数据库

一.什么是数据库 数据库&#xff1a;存储数据的仓库&#xff0c;数据是有组织的进行存储。&#xff08;database 简称DB&#xff09; 数据库管理系统&#xff1a;管理数据库的大型软禁&#xff08;DataBase Management System 简称DBMS&#xff09; SQL&#xff1a;操作关系…

Deep Learning Part Seven基于RNN生成文本--24.5.2

不存在什么完美的文章&#xff0c;就好像没有完美的绝望。 ——村上春树《且听风吟》 本章所学的内容 0.引子 本章主要利用LSTM实现几个有趣的应用&#xff1a; 先剧透一下&#xff1a;是AI聊天软件&#xff08;现在做的ChatGPT&#xff08;聊天神器&#xff0c;水论文高手…

Windows Server安装DHCP和DNS

前言 本期将教大家如何在Windows server上部署DHCP服务和DNS服务&#xff0c;用于模拟给内网主机分配IP地址。虽然用于演示的系统比较老&#xff0c;如果在新版本如Windows server2016、19、22上部署&#xff0c;操作基本一致。在此之前先给大家科普一波理论&#xff0c;需略过…

【docker 】push 镜像到私服

查看镜像 docker images把这个hello-world 推送到私服 docker push hello-world:latest 报错了。不能推送。需要标记镜像 标记Docker镜像 docker tag hello-world:latest 192.168.2.1:5000/hello-world:latest 将Docker镜像推送到私服 docker push 192.168.2.1:5000/hello…

Django数据库创建存储及管理

一、什么是ORM Django的ORM(Object-Relational Mapping)是Django框架中一个非常重要的组件。ORM可以让开发者以面向对象的方式操作数据库,而不需要直接编写SQL语句。 具体来说,Django ORM提供了以下功能: 模型定义:开发者可以在Django应用中定义Python类来表示数据库表,这些…

基于寄存器的STM32操作流程

寄存器点灯 寄存器操作STM32的好处是不需要依靠外部文件&#xff0c;自由度更高&#xff0c;更为底层&#xff0c;但也更加繁杂。 通过寄存器点灯&#xff0c;需要按照电路结构与手册配置寄存器&#xff1a; 电路结构如下&#xff1a;可知需配置的GPIO为GPIOB5与GPIOE5。 在…

Docker构建LNMP部署WordPress

前言 使用容器化技术如 Docker 可以极大地简化应用程序的部署和管理过程&#xff0c;本文将介绍如何利用 Docker 构建 LNMP 环境&#xff0c;并通过部署 WordPress 来展示这一过程。 目录 一、环境准备 1. 项目需求 2. 安装包下载 3. 服务器环境 4. 规划工作目录 5. 创…

excel怎么删除条件格式规则但保留格式?

这个问题的意思就是要将设置的条件格式&#xff0c;转换成单元格格式。除了使用VBA代码将格式转换外&#xff0c;还可以用excel自己的功能来完成这个任务。 一、将条件格式“留下来” 1.设置条件格式 选中数据&#xff0c;点击开始选项卡&#xff0c;设置条件格式&#xff0…
最新文章