Alibaba-Easyexcel 使用总结

简介

简介

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);@Overridepublic void invoke(PersonData data, AnalysisContext context) {cachedDataList.add(data);if (cachedDataList.size() >= BATCH_COUNT) {printData();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic 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());}@Overridepublic void invoke(PersonData data, AnalysisContext context) {cachedDataList.add(data);if (cachedDataList.size() >= BATCH_COUNT) {printData();// 存储完成清理 listcachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);}}@Overridepublic 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 的类型 @Overridepublic Class<?> supportJavaTypeKey() {return String.class;}// 支持 Excel 单元格类型@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}/*** 当读到的数据符合类型,封装的字段也符合类型,按照下面方法转换数据* 这么转换,是由开发者在方法中重写* @param context* @return*/@Overridepublic String convertToJavaData(ReadConverterContext<?> context) {//context.getReadCellData().getStringValue(): 是原本的数据 return "大神:" + context.getReadCellData().getStringValue();}/*** 这里是写的时候会调用*  当读到的数据符合类型,封装的字段也符合类型,按照下面方法转换数据*  这么转换,是由开发者在方法中重写* @return*/@Overridepublic 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-beta1String 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;/*** 忽略这个字段*/// @ExcelIgnoreprivate 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> {@Overridepublic Class<?> supportJavaTypeKey() {return String.class;}@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}/*** 这里读的时候会调用:前面有** @param context* @return*/@Overridepublic String convertToJavaData(ReadConverterContext<?> context) {return "大神:" + context.getReadCellData().getStringValue();}/*** 这里是写的时候会调用*  当读到的数据符合类型,封装的字段也符合类型,按照下面方法转换数据*  这么转换,是由开发者在方法中重写* @return*/@Overridepublic 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.mzph.cn/news/47679.shtml

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

相关文章

RNN+LSTM正弦sin信号预测 完整代码数据视频教程

视频讲解:RNN+LSTM正弦sin信号预测_哔哩哔哩_bilibili 效果演示: 数据展示: 完整代码: import torch import torch.nn as nn import torch.optim as optim import numpy as np import matplotlib.pyplot as plt import pandas as pd from sklearn.preprocessing import…

Nginx代理功能与负载均衡详解

序言 Nginx的代理功能与负载均衡功能是最常被用到的&#xff0c;关于nginx的基本语法常识与配置已在上篇文章中有说明&#xff0c;这篇就开门见山&#xff0c;先描述一些关于代理功能的配置&#xff0c;再说明负载均衡详细。 Nginx代理服务的配置说明 1、上一篇中我们在http…

python的安装

1.进入python官网下载安装包&#xff1a;https://www.python.org/ 2.安装 注意&#xff1a;勾选Add Python 3.8 to PATH选项&#xff0c;并且建议选择Install Now选项&#xff0c;东西多。 解释&#xff1a;这里的path是指系统路径&#xff0c;即将python.exe文件添加到系 统…

常见的网络设备有哪些?分别有什么作用?

个人主页&#xff1a;insist--个人主页​​​​​​ 本文专栏&#xff1a;网络基础——带你走进网络世界 本专栏会持续更新网络基础知识&#xff0c;希望大家多多支持&#xff0c;让我们一起探索这个神奇而广阔的网络世界。 目录 一、网络设备的概述 二、常见的网络设备 1、…

JVS低代码中表单引擎与逻辑引擎是如何联合调用外部API的?

在企业项目中&#xff0c;常常出现需要给外部系统提供一个api &#xff0c;让外部系统触发调用&#xff0c;本系统直接数据入库&#xff0c;那么我们来看看jvs的表单引擎与逻辑引擎联合实现这个功能&#xff0c;先看实现效果&#xff1a; 配置步骤&#xff1a; 一、配置列表页…

网络面试题(172.22.141.231/26,该IP位于哪个网段? 该网段拥有多少可用IP地址?广播地址是多少?)

此题面试中常被问到&#xff0c;一定要会172.22.141.231/26&#xff0c;该IP位于哪个网段&#xff1f; 该网段拥有多少可用IP地址&#xff1f;广播地址是多少&#xff1f; 解题思路&#xff1a; 网络地址&#xff1a;172.22.141.192 10101100.00010110.10001101.11000000 广播…

【后端速成 Vue】第一个 Vue 程序

1、为什么要学习 Vue&#xff1f; 为什么使用 Vue? 回想之前&#xff0c;前后端交互的时候&#xff0c;前端收到后端响应的数据&#xff0c;接着将数据渲染到页面上&#xff0c;之前使用的是 JavaScript 或者 基于 JavaScript 的 Jquery&#xff0c;但是这两个用起来还是不太…

uni-app 打包生成签名Sha1

Android平台打包发布apk应用&#xff0c;需要使用数字证书&#xff08;.keystore文件&#xff09;进行签名&#xff0c;用于表明开发者身份。 可以使用JRE环境中的keytool命令生成。以下是windows平台生成证书的方法&#xff1a; 安装JRE环境&#xff08;推荐使用JRE8环境&am…

STM32 GPIO复习

GPIO General Purpose Input Output&#xff0c;即通用输入输出端口&#xff0c;简称GPIO。 负责采集外部器件的信息或控制外部器件工作&#xff0c;即输入输出。 不同型号&#xff0c;IO口数量可能不一样&#xff0c;可通过选型手册快速查询。 能快速翻转&#xff0c;每次翻…

Crimson:高性能,高扩展的新一代 Ceph OSD

背景 随着物理硬件的不断发展&#xff0c;存储软件所使用的硬件的情况也一直在不断变化。 一方面&#xff0c;内存和 IO 技术一直在快速发展&#xff0c;硬件的性能在极速增加。在最初设计 Ceph 的时候&#xff0c;通常情况下&#xff0c;Ceph 都是被部署到机械硬盘上&#x…

vellum (Discovering Houdini VellumⅡ柔体系统)学习笔记

视频地址&#xff1a; https://www.bilibili.com/video/BV1ve411u7nE?p3&spm_id_frompageDriver&vd_source044ee2998086c02fedb124921a28c963&#xff08;搬运&#xff09; 个人笔记如有错误欢迎指正&#xff1b;希望可以节省你的学习时间 ~享受艺术 干杯&#x1f37b…

通过几段代码,详解Python单线程、多线程、多进程

在使用爬虫爬取数据的时候&#xff0c;当需要爬取的数据量比较大&#xff0c;且急需很快获取到数据的时候&#xff0c;可以考虑将单线程的爬虫写成多线程的爬虫。下面来学习一些它的基础知识和代码编写方法。 一、进程和线程 进程可以理解为是正在运行的程序的实例。进程是拥…

Kubernetes 使用 Rancher 管理

K8S集群管理工具 只能管理单个K8S集群 kubectl命令行管理工具 dashboard&#xff08;K8S官方的UI界面图形化管理工具&#xff09; &#xff08;管理多集群很麻烦&#xff0c;切换不同集群每次需要更改kube-config文件[kubectl配置文件]&#xff0c;如果kubeadm部署每次都需…

bigemap如何批量添加地图?

bigemap如何批量添加地图&#xff1f; 说明&#xff1a;批量添加可以同时添加多个在线地图&#xff0c;一次性添加完成&#xff08;批量添加无法验证地址是否可以访问&#xff09;&#xff08;批量配置文件可以在官网获取&#xff09; 第一步选择地图点进去点(添加号) 第二步&…

Linux面试笔试题(5)

79、下列工具中可以直接连接mysql的工具有【c 】。 A.xhsell B.plsql C.navicat D.以上都不是 Navicat 是一套可创建多个连接的数据库开发工具&#xff0c; 让你从单一应用程序中同时连接 MySQL、Redis、MariaDB、MongoDB、 SQL Server、Oracle、PostgreSQL和 SQLite 。它与…

七夕给TA满分宠爱!浪漫攻略为约会加分

浪漫的七夕将至&#xff0c;无论是异地恋人还是约会情侣&#xff0c;怎么能缺少节日仪式感~精心策划的约会计划&#xff0c;让浪漫“超级加倍”。 美好的二人世界&#xff0c;共度甜蜜时光&#xff0c;当然需要提前做好攻略&#xff0c;风和日丽的好天气能为约会加分不少。在规…

ArcGIS Serve Windows下用户密码变更导致Server服务无法启动问题

问题&#xff1a; 因未知原因Windows下的Server安装账户密码变更&#xff0c;但是又忘记了密码&#xff0c;导致&#xff0c;Server服务启动失败&#xff0c;错误1069&#xff1a; 解决方法&#xff1a; 在账户管理界面&#xff0c;重置对应的arcgis账户的密码&#xff0c;…

初识Redis

简介RedisRedis安装怎么远程连接基础命令常用类型字符串类型字典类型列表类型集合类型有序集合类型 spring boot集成Redis代码操作Redis 实现一个session储存到redis持久化缓存雪崩缓存穿透缓存击穿缓存预热 项目升级之Redis储存Session 简介Redis Redis是一种内存数据存储系统…

华人画家戴渭作品 3000 万拍出,牛津艺术学院发出任教邀请

爱丁堡,2023年7月 - 画家戴渭以他独特的画风、深邃的意境和慈悲智慧的属性,将艺术与宗教融合于作品之中。初看他的作品,可能会被其高超的艺术水准所震撼,然而仔细品味,方能领略到他深邃的艺术造诣与宗教智慧的深度融合。 作为国内最年轻的华人80后画家之一,戴渭近期被英国牛津…