Springboot3+EasyExcel由浅入深

环境介绍

技术栈

springboot3+easyexcel

软件

版本

IDEA

IntelliJ IDEA 2022.2.1

JDK

17

Spring Boot

3

EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。

他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。

官网https://easyexcel.opensource.alibaba.com/

Sheet工作簿

Row,行,索引从0开始

Column,列,索引从0开始

Cell,单元格

目录

Read

Read1

Read2

异常处理

读sheet

自定义格式转换 日期,数字-Read

自定义转换器-Read

读指定行

Write

Write1

Write2

写入指定列

多级列名

自定义格式转换 日期,数字-Write

自定义转换器-Write

指定列宽行高

批量写入excel方法

自定义模板写入excel

自定义监听器

Web上传下载


Read

Read1

List<Corrdinate> newlist =new ArrayList<>();

String fileName="C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx";

EasyExcel.read(fileName, Corrdinate.class, new ReadListener<Corrdinate>() {

   @Override

   public void invoke(Corrdinate corrdinate, AnalysisContext analysisContext) {

      try {

         if (11<=Double.parseDouble(corrdinate.getX()) && Double.parseDouble(corrdinate.getX())<120

               && 2<=Double.parseDouble(corrdinate.getY()) && Double.parseDouble(corrdinate.getY())<244 ){

            corrdinate.setZ(true);

         }else {

            corrdinate.setZ(false);

         }

         newlist.add(corrdinate);

      }catch (Exception e){

         System.out.println(e);

         corrdinate.setDesc("类型转换失败");

         newlist.add(corrdinate);

      }





   }

   @Override

   public void doAfterAllAnalysed(AnalysisContext analysisContext) {

      System.out.println("读取完成");

   }

}).sheet().doRead();

Read2

String fileName="C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx";

EasyExcel.read(fileName, Corrdinate.class,new PageReadListener<Corrdinate>(corrdinates -> {

   for (Corrdinate corrdinate : corrdinates) {

      try {

         if (1<=Double.parseDouble(corrdinate.getX()) && Double.parseDouble(corrdinate.getX())<110

               && 2<=Double.parseDouble(corrdinate.getY()) && Double.parseDouble(corrdinate.getY())<240 ){

            corrdinate.setZ(true);

         }else {

            corrdinate.setZ(false);

         }

         newlist.add(corrdinate);

      }catch (Exception e){

         System.out.println(e);

         corrdinate.setDesc("类型转换失败");

         newlist.add(corrdinate);

      }

   }

})).sheet().doRead();

异常处理

重写onException方法

@Test
void readException() {
   List<Corrdinate> oldlist =new ArrayList<>();
   List<Corrdinate> newlist =new ArrayList<>();
   String fileName="C:\\Users\\Administrator\\Desktop\\坐标测试.xlsx";
   EasyExcel.read(fileName, Corrdinate.class, new ReadListener<Corrdinate>() {
      @Override
      public void invoke(Corrdinate corrdinate, AnalysisContext analysisContext) {
            if (1<=Double.parseDouble(corrdinate.getX()) && Double.parseDouble(corrdinate.getX())<110
                  && 2<=Double.parseDouble(corrdinate.getY()) && Double.parseDouble(corrdinate.getY())<240 ){
               corrdinate.setZ(true);
            }else {
               corrdinate.setZ(false);
            }
            newlist.add(corrdinate);
      }
      @Override
      public void doAfterAllAnalysed(AnalysisContext analysisContext) {
         System.out.println("读取完成");
      }
      @Override
      public void onException(Exception exception, AnalysisContext context) throws Exception {
         System.out.println(exception);
      }
   }).sheet().doRead();
   for (Corrdinate corrdinate : newlist) {
      System.out.println(corrdinate.toString());
   }
}

try- catch

@Test
void read1() {
   List<Corrdinate> oldlist =new ArrayList<>();
   List<Corrdinate> newlist =new ArrayList<>();
   String fileName="C:\\Users\\Administrator\\Desktop\\测试.xlsx";
   EasyExcel.read(fileName, Corrdinate.class, new ReadListener<Corrdinate>() {
      @Override
      public void invoke(Corrdinate corrdinate, AnalysisContext analysisContext) {
         try {
            if (1<=Double.parseDouble(corrdinate.getX()) && Double.parseDouble(corrdinate.getX())<200
                  && 20<=Double.parseDouble(corrdinate.getY()) && Double.parseDouble(corrdinate.getY())<300 ){
               corrdinate.setZ(true);
            }else {
               corrdinate.setZ(false);
            }
            newlist.add(corrdinate);
         }catch (Exception e){
            System.out.println(e);
            corrdinate.setDesc("类型转换失败");
            newlist.add(corrdinate);
         }
      }
      @Override
      public void doAfterAllAnalysed(AnalysisContext analysisContext) {
         System.out.println("读取完成");
      }

   }).sheet().doRead();

   for (Corrdinate corrdinate : newlist) {
      System.out.println(corrdinate.toString());
   }
}

读sheet

读所有工作簿

@Test
void readManyShoot() {
   String fileName="C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx";
   EasyExcel.read(fileName, Corrdinate.class,new PageReadListener<>(corrdinates -> {
      corrdinates.forEach(System.out::println);
   })).doReadAll();
}

读任意工作簿

@Test
void readAppointSheet() {
   try (ExcelReader excelReader = EasyExcel.read("C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx").build();){
      //创建工作簿对象sheet1
      ReadSheet sheet1 = EasyExcel.readSheet(0).head(Corrdinate.class)
            .registerReadListener(new PageReadListener<>(corrdinates -> {
               corrdinates.forEach(System.out::println);
            }
            )).build();
      //创建工作簿对象sheet2
      ReadSheet sheet2 = EasyExcel.readSheet("Sheet2").head(Corrdinate.class)
            .registerReadListener(new PageReadListener<>(corrdinates -> {
               corrdinates.forEach(System.out::println);
            }
            )).build();
      excelReader.read(sheet1,sheet2);
   }
}

自定义格式转换 日期,数字-Read

@Data
public class man {
    @ExcelProperty("姓名")
    private String name;
    @ExcelProperty("日期")
    @DateTimeFormat("yyyy年mm月dd日")
    private Date date;
    @ExcelProperty("成功率")
    private BigDecimal successrate;
}

自定义转换器-Read

public class StringConverterString implements Converter<String> {
    //支持java类型
    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }
    //支持Excel单元格类型
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    //读的数据符合类型
    @Override
    public String convertToJavaData(ReadConverterContext<?> context) throws Exception {
        //转换
        return "姓名:"+context.getReadCellData().getStringValue();
    }
    //写的数据符合类型
    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) throws Exception {
        return new WriteCellData<>(context.getValue());
    }
}

@Data
public class man {
    @ExcelProperty(converter = StringConverterString.class)
    private String name;
    @ExcelProperty("日期")
    @DateTimeFormat("yyyy年mm月dd日")
    private Date date;
    @ExcelProperty("成功率")
    private BigDecimal successrate;
}

读指定行

EasyExcel默认从第一行开始读取,第0行默认为列头

@Test
void selectRead(){
   String fileName="C:\\Users\\Administrator\\Desktop\\demofile\\坐标测试.xlsx";
   EasyExcel.read(fileName, man.class,new PageReadListener<>(mans -> {
      mans.forEach(System.out::println);
   })).sheet("Sheet3")
         .headRowNumber(2)//第几行,0-n
         .doRead();
}

Write

实体类

@Data

public class Corrdinate {

    private long id;

    @ExcelProperty("x")

    private String x;

    private String y;

    @ExcelProperty("是否匹配")

    private boolean z;

    @ExcelProperty("描述")

    private String desc;

    @ExcelIgnore//忽略字段

    private String de;

}

Write1

//生成数据方法

private List<Corrdinate> getData(int count) {



   List<Corrdinate> list = ListUtils.newArrayList();



   for (int i = 0; i < count; i++) {



      Corrdinate corrdinate = new Corrdinate();

      //生成10-100随机数

      corrdinate.setId(RandomUtil.randomInt(10, 100));

      corrdinate.setX(String.valueOf(RandomUtil.randomInt(10, 100)));

      corrdinate.setY(String.valueOf(RandomUtil.randomInt(10, 100)));

      list.add(corrdinate);

   }

   return list;

}



@Test

void write1(){

EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Corrdinate.class)

      .sheet()//指定工作簿

   

Write2

//生成数据方法

private List<Corrdinate> getData(int count) {



   List<Corrdinate> list = ListUtils.newArrayList();



   for (int i = 0; i < count; i++) {



      Corrdinate corrdinate = new Corrdinate();



      corrdinate.setId(Long.parseLong(String.valueOf(RandomUtil.randomInt(10, 100))));

      //生成10-100随机数

      corrdinate.setX(String.valueOf(RandomUtil.randomInt(10, 100)));

      corrdinate.setY(String.valueOf(RandomUtil.randomInt(10, 100)));

      //随机生成MD5

      corrdinate.setDesc(DigestUtils.md5Hex("hello"));

      list.add(corrdinate);

   }

   return list;

}

@Test

void write2(){

   try (ExcelWriter excelWriter = EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Corrdinate.class).build();){

      WriteSheet sheet2 = EasyExcel.writerSheet("Sheet2").build();
      WriteSheet sheet1 =EasyExcel.writerSheet("Sheet1").build();

      excelWriter.write(getData(10),sheet1);
      excelWriter.write(getData(10),sheet2);
   }

写入指定列

实体类

@Data

public class Corrdinate {

    private long id;

    @ExcelProperty(value = "x",index = 1)//指定列名和顺序

    private String x;

    private String y;

    @ExcelProperty("是否匹配")

    private boolean z;

    @ExcelProperty("描述")

    private String desc;

    @ExcelIgnore//忽略字段

    private String de;

}

生成数据方法

//生成数据方法

private List<Corrdinate> getData(int count) {



   List<Corrdinate> list = ListUtils.newArrayList();



   for (int i = 0; i < count; i++) {



      Corrdinate corrdinate = new Corrdinate();



      corrdinate.setId(Long.parseLong(String.valueOf(RandomUtil.randomInt(10, 100))));

      //生成10-100随机数

      corrdinate.setX(String.valueOf(RandomUtil.randomInt(10, 100)));

      corrdinate.setY(String.valueOf(RandomUtil.randomInt(10, 100)));

      //随机生成MD5

      corrdinate.setDesc(DigestUtils.md5Hex("hello"));

      corrdinate.setDe(DigestUtils.md5Hex("de"));

      list.add(corrdinate);

   }

   return list;

}

写测试

@Test

void writeColumn(){

   Set<String> set = new TreeSet<>();

   set.add("de");



   EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Corrdinate.class)

         .excludeColumnFieldNames(set)

         .sheet("Sheet2")//指定工作簿

         .doWrite(getData(10));//写入10个数据

}

多级列名

实体类

@Data

public class Corrdinate {

    private long id;

    @ExcelProperty(value = "x",index = 1)//指定列名和顺序

    private String x;

    private String y;

    @ExcelProperty({"一级列名","是否匹配"})

    private boolean z;

    @ExcelProperty({"一级列名","描述"})

    private String desc;

    //@ExcelIgnore//忽略字段

    //设置一级列名,二级列名

    @ExcelProperty({"一级列名","二级列名"})

    private String de;

}

写测试

@Test

void writeDemo(){

   EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Corrdinate.class)

         .sheet("Sheet3")//指定工作簿

         .doWrite(getData(10));//写入10个数据

}

自定义格式转换 日期,数字-Write

实体类

@Data

public class man {

    @ExcelProperty(converter = StringConverterString.class)

    private String name;

    @ExcelProperty("日期")

    @DateTimeFormat("yyyy年mm月dd日")

    private Date date;

   @NumberFormat("#.##%")

    private BigDecimal successrate;

}

生成数据并测试写入

//生成数据方法

private List<Man> getData2(int count) {
   List<Man> list = ListUtils.newArrayList();

   for (int i = 0; i < count; i++) {
      Man m = new Man();
      m.setName("张三"+i);
      m.setSuccessrate(BigDecimal.valueOf(RandomUtil.randomDouble(0.0, 1)));
      m.setDate(new Date());
      list.add(m);
   }
   return list;
}


@Test

void writeDemo(){

   EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Man.class)

         .sheet("Sheet3")//指定工作簿

         .doWrite(getData2(10));//写入10个数据

}

}

自定义转换器-Write

自定义转换器

public class StringConverterString implements Converter<String> {

    //支持java类型

    @Override

    public Class<?> supportJavaTypeKey() {

        return String.class;

    }

    //支持Excel单元格类型

    @Override

    public CellDataTypeEnum supportExcelTypeKey() {

        return CellDataTypeEnum.STRING;

    }



    //读的数据符合类型

    @Override

    public String convertToJavaData(ReadConverterContext<?> context) throws Exception {

        //转换

        return "姓名:"+context.getReadCellData().getStringValue();



    }

    //写的数据符合类型

    @Override

    public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) throws Exception {

        return new WriteCellData<>("写入数据"+context.getValue());

    }

}

生成数据并测试写入

private List<Man> getData2(int count) {



   List<Man> list = ListUtils.newArrayList();



   for (int i = 0; i < count; i++) {



      Man m = new Man();

      m.setName("张三"+i);

      m.setSuccessrate(BigDecimal.valueOf(RandomUtil.randomDouble(0.0, 1)));

      m.setDate(new Date());



      list.add(m);

   }

   return list;

}



@Test

void writeDemo(){

   EasyExcel.write("C:\\Users\\Administrator\\Desktop\\demofile\\test01.xlsx", Man.class)

         .sheet("Sheet3")//指定工作簿

         .doWrite(getData2(10));//写入10个数据

}

指定列宽行高

@Data

@HeadRowHeight(30)// 指定列头行高度

@ContentRowHeight(15)// 指定内容行高度

@ColumnWidth(12)//指定列宽

public class Man {

    @ExcelProperty(converter = StringConverterString.class)

    private String name;

    @ExcelProperty("日期")

    @DateTimeFormat("yyyy年mm月dd日")

    private Date date;

   @NumberFormat("#.##%")

    private BigDecimal successrate;

}

批量写入excel方法

编写实体类

@TableName(value ="product")

@Data

@NoArgsConstructor

@AllArgsConstructor

public class Product implements Serializable {

    /**

     * 序号

     */

    @TableId(type = IdType.AUTO)

    @ExcelProperty("序号")

    private Integer number;

    /**

     * 创建时间

     */

    @ExcelProperty("创建时间")

    private Date createtime;

    /**

     * 产品名称

     */

    @ExcelProperty("产品名称")

    private String productname;

    /**

     * 产品编号

     */

    @ExcelProperty("产品编号")

    private String productnumber;

    /**

     * 产品型号

     */

    @ExcelProperty("产品型号")

    private String manufacturer;

    /**

     * 产品位置

     */

    @ExcelProperty("产品位置")

    private String producepath;

    /**

     * 图片位置

     */

    @ExcelProperty("图片位置")

    private String imagepath;

    /**

     * 使用单位

     */

    @ExcelProperty("使用单位")

    private String unit;

    /**

     * 金额

     */

    @ExcelProperty("金额")

    private Integer money;

    /**

     * 入库时间

     */

    @ExcelProperty("入库时间")

    private Date intime;

    /**

     * 出库时间

     */

    @ExcelProperty("出库时间")

    private Date puttime;

    /**

     * 操作人

     */

    @ExcelProperty("操作人")

    private String operator;

    /**

     * 创建人

     */

    @ExcelProperty("创建人")

    private String createduser;

    /**

     * 备注

     */

    @ExcelProperty("备注")

    private String notes;

    /**

     * 产品数量

     */

    @ExcelProperty("产品数量")

    private Integer producedigit;

    /**

     * 产品单位

     */

    @ExcelProperty("产品单位")

    private String productunit;

    @TableField(exist = false)

    private static final long serialVersionUID = 1L;

}

//重复多次写入(写到单个或者多个Sheet)

@Test

public void manyWrite() {

   // 方法1: 如果写到同一个sheet

   String fileName = "C:\\Users\\13631\\Desktop\\simpleWriteTest1702391756908.xlsx";

   // 这里 需要指定写用哪个class去写

   try (ExcelWriter excelWriter = EasyExcel.write(fileName, Product.class).build()) {

      // 这里注意 如果同一个sheet只要创建一次

      WriteSheet writeSheet = EasyExcel.writerSheet("测试").build();

      long star = System.currentTimeMillis();

      // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来

      for (int i = 0; i < 5; i++) {

         // 分页去数据库查询数据 这里可以去数据库查询每一页的数据

         List<Product> data = getData(1000);

         excelWriter.write(data, writeSheet);

      }

      long end = System.currentTimeMillis();

      System.out.println("耗时:" + (end - star)/1000 + "秒");

   }

自定义模板写入excel

填充单行

填充集合

//根据模板填充数据
@Test
public void fillWrite() {
    // 方案2 分多次 填充 会使用文件缓存(省内存)
    String fileName = "C:\\Users\\13631\\Desktop\\模板写数据.xlsx";
    String templateFileName = "C:\\Users\\13631\\Desktop\\模板.xlsx";
    try (ExcelWriter excelWriter = EasyExcel.write(fileName).withTemplate(templateFileName).build()) {
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        excelWriter.fill(getData2(100), writeSheet);
    }
}

填充效果

自定义监听器

1、实体类(如上述实体类)

2、自定义监听器

Invoke和doAfterAllAnalysed是必选的

public class MyListener implements ReadListener<Product> {

    private TestMapper testMapper;
    private ArrayList<Product> list = new ArrayList<>();
    int sum=0;

    public MyListener(TestMapper testMapper) {
        this.testMapper = testMapper;
    }

    //每读一行,则调用该方法
    @Override
    public void invoke(Product product, AnalysisContext analysisContext) {
        sum++;
        list.add(product);
    }
    //每读完整个excel,则调用该方法
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        System.out.println("读取了"+sum+"行数据");
    }
}

@Test
void contextLoads() {
    String fileName = "C:\\Users\\13631\\Desktop\\simpleWriteTest1702391756908.xlsx";
    // 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行
    // 具体需要返回多少行可以在`PageReadListener`的构造函数设置
    ExcelReader reader = EasyExcel.read(fileName, Product.class, new MyListener(new TestMapper())).build();
    ReadSheet sheet = EasyExcel.readSheet().build();
    reader.read(sheet);
}

Web上传下载

web中的读(上传)

后端

//上传

//上传

    @PostMapping("/upload")

    @ResponseBody

    public String upload(MultipartFile file) throws IOException {

        long start = System.currentTimeMillis();

        EasyExcel.read(file.getInputStream(), Product.class, new MyListener(productService)).sheet().doRead();

        long end = System.currentTimeMillis();

        System.out.println("耗时:"+(end-start)/1000+"秒");

        return "success";

    }

前端(vue2+Element)

<el-upload

  class="upload-demo"

  action="http://192.168.1.8:8007/excel/upload"

  :on-preview="handlePreview"

  :on-remove="handleRemove"

  :before-remove="beforeRemove"

  multiple

  :limit="3"

  :on-exceed="handleExceed"

  :file-list="fileList">

  <el-button size="small" type="primary">点击上传</el-button>

</el-upload>

效果

web中的写(下载)

后端

@GetMapping("download")

public void download(HttpServletResponse response) throws IOException {

    // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman

    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

    response.setCharacterEncoding("utf-8");

    // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系

    String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");

    response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

    EasyExcel.write(response.getOutputStream(), Product.class).sheet("模板").doWrite(productService.list());

}

前端

<button @click="download">导出Excel</button>


methods:{

    download(){

      document.location.href="http://192.168.1.8:8007/excel/download";

    }

  },

效果

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

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

相关文章

Mr_HJ / form-generator项目文档学习与记录(续2)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; https://gitee.com/nbacheng/n…

vue3打包后页面空白解决方法

vue3打包后页面空白解决方法 问题解决方法 问题 最近写一个小项目 没有打包的时候一切正常 技术栈用的vue3 vite 我用的是npm创建的项目 npm init vuelatest问题一 &#xff1a;打包后页面空白&#xff0c;什么都没有 问题二&#xff1a;刷新页面后找不到资源 把url的inde…

(超详细)5-YOLOV5改进-添加A2Attention注意力机制

1、在yolov5/models下面新建一个A2Attention.py文件&#xff0c;在里面放入下面的代码 代码如下&#xff1a; import numpy as np import torch from torch import nn from torch.nn import init from torch.nn import functional as Fclass DoubleAttention(nn.Module):def …

自研OS,手机厂商的「私心」与软件厂商的「灾难」

作者 | 辰纹 来源 | 洞见新研社 在卷完了配置参数&#xff0c;影像跑分&#xff0c;屏幕快充、存储影像、续航折叠……手机还能怎么卷&#xff1f; 过去的2023年&#xff0c;手机厂商们不约而同的将目标瞄准了自研系统。 站在民族情感层面&#xff0c;中国手机“去安卓化”…

PHP在线考试平台管理系统源码带文字搭建教程和操作手册

PHP在线考试平台管理系统源码带文字搭建教程和操作手册 技术架构 PHP7.2 Thinkphp6 React UmiJs nginx mysql5.7 cnetos7以上 宝塔面板 系统功能特性与介绍 采用PHP7强类型&#xff08;严格模式&#xff09;。 题库管理 支持多种试题类型和录题方式。 考生管理 快速导入考…

Paddle模型转ONNX

深度学习模型在硬件加速器上的部署常常要用到ONNX&#xff08;Open Neural Network Exchange&#xff0c;开放神经网络交换&#xff09;格式&#xff0c;也可以通过ONNX实现不同AI框架&#xff08;如Pytorch、TensorFlow、Caffe2、PaddlePaddle等&#xff09;之间的模型转换。 …

python:for循环 实现FizzBuzz

python&#xff1a;for循环 实现FizzBuzz 要求&#xff1a;输入一个数字&#xff0c;程序遍历从1到输入的数字之间的所有数字&#xff0c;如果该数能被3整除&#xff0c;打印Fizz&#xff1b;如果该数能被5整除&#xff0c;打印Buzz&#xff1b;如果能同时被3和5整除&#xff…

Docker安装Redis 配置文件映射以及密码设置

安装直接docker pull redis即可&#xff0c;默认redis最新版 设置两个配置文件路径 mkdir -p /root/docker/redis/data mkdir -p /root/docker/redis/conf touch redis.conf // 容器挂载用conf配置文件 bind 0.0.0.0 protected-mode yes port 6379 tcp-backlog 511 timeout…

蓝桥杯单片机组备赛——LED指示灯的基本控制

&#x1f388;教程介绍&#xff1a;博客依据b站小蜜蜂老师的教程进行编写&#xff0c;文中会对老师传授的知识进行总结并加入自己的一些理解。教程链接 文章目录 一、点灯介绍二、相关数字芯片介绍2.1 74HC138介绍2.2 74HC573介绍2.3 74HC02介绍 三、代码设计思路四、代码编写…

【C#】当重复使用一段代码倒计时时,使用普通类和静态方法,实现简单的封装性、可扩展性、可维护性

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…

代码随想录刷题第四十八天| 198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

代码随想录刷题第四十八天 今天是打家劫舍三部曲&#xff0c;最后一题树形dp有点难&#xff0c;其他还好 打家劫舍 (LC 198) 题目思路&#xff1a; 代码实现&#xff1a; class Solution:def rob(self, nums: List[int]) -> int:dp [0 for _ in range(len(nums)1)]dp[1…

Go并发快速入门:Goroutine

Go并发&#xff1a;Goroutine 1.并发基础概念&#xff1a;进程、线程、协程 (1) 进程 可以比作食材加工的一系列动作 进程就是程序在操作系统中的一次执行过程&#xff0c;是由系统进行资源分配和调度的基本单位&#xff0c;进程是一个动态概念&#xff0c;是程序在执行过程…

【生产者消费者模型的 Java 实现】

文章目录 前言传统派维新派 前言 题目&#xff1a;一个初始值为零的变量&#xff0c;多个线程对其交替操作&#xff0c;分别加1减1 实现步骤&#xff1a; 线程操作资源类判断&#xff0c;干活&#xff0c;通知防止虚假唤醒机制&#xff0c;即&#xff1a;多线程的判断需要用…

车规MCU开发之E2E协议

啥是E2E&#xff1f; E2E的原理&#xff1a; 1. 发送端&#xff1a;发送数据包添加E2E保护头 2. 接收端&#xff1a;接收数据包校验E2E保护头 E2E例子 - profile 11为例 E2E_P11ConfigType wk_stP11Cfg { .CounterOffset 8, .CRCOffset 0, .DataID …

2024年免费服务器活动整理汇总

随着科技的发展&#xff0c;服务器在各行各业的应用越来越广泛&#xff0c;而免费服务器活动也成为了许多企业和个人关注的焦点。目前有许多免费服务器活动可供选择&#xff0c;本文将为大家整理汇总免费服务器活动&#xff0c;帮助大家更好地了解和参与。 一、腾讯云免费服务器…

C语言指针相关知识(初阶)

目录 指针是什么 指针变量的大小 指针和指针类型 指针类型的意义 野指针 指针运算 指针-整数 指针-指针 指针的关系运算 指针和数组 二级指针 二级指针定义 指针数组 指针数组的定义 指针是什么 如下图所示&#xff08;右侧编号为内存地址&#xff09;&#xff1…

修改Echarts图表的标题和副标题的内容

直接上代码 var graphicConfig [ { type: "text", left: "center", top: "center", style: { text: "包日", // 初始化为空字符串 textAlign: "center", fill: "#000", fontSize: 14, fontWeight: "bold&qu…

Casper Labs 与 IBM Consulting 合作,AI透明度、审计能力的新方案

​ “全新解决方案&#xff0c;旨在帮助企业更有效地管理训练数据&#xff0c;这些数据由不同的组织通过生成式人工智能系统产生” 企业区块链软件和服务提供商 Casper Labs 与 IBM Consulting 共同宣布&#xff0c;它们将联手推出新的解决方案&#xff0c;以帮助客户在其人工…

day-07 统计出现过一次的公共字符串

思路 用哈希表统计words1和words2中各个字符串的出现次数&#xff0c;次数皆为1的字符串符合题意 解题方法 //用于存储words1中各个字符串的出现次数 HashMap<String,Integer> hashMap1new HashMap<>(); //用于存储words2中各个字符串的出现次数 HashMap<Stri…