SpringBoot实现Excel导入导出

SpringBoot实现Excel导入导出

在我们平时工作中经常会遇到要操作Excel的功能,比如导出个用户信息或者订单信息的Excel报表。你肯定听说过

POI这个东西,可以实现。但是POI实现的API确实很麻烦,它需要写那种逐行解析的代码(类似Xml解析)。今天

给大家推荐一款非常好用的Excel导入导出工具EasyPoi,希望对大家有所帮助!

1、EasyPoi简介

用惯了SpringBoot的朋友估计会想到,有没有什么办法可以直接定义好需要导出的数据对象,然后添加几个注

解,直接自动实现Excel导入导出功能?

EasyPoi正是这么一款工具,如果你不太熟悉POI,想简单地实现Excel操作,用它就对了!

EasyPoi的目标不是替代POI,而是让一个不懂导入导出的人也能快速使用POI完成Excel的各种操作,而不是看很

多API才可以完成这样的工作。

项目官网:https://gitee.com/lemur/easypoi

2、集成

在SpringBoot中集成EasyPoi非常简单,只需添加easypoi-spring-boot-starter依赖即可,真正的开箱即

用!

2.1 pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.6</version><relativePath/></parent><groupId>com.easypoi</groupId><artifactId>spring-boot-easypoi</artifactId><version>0.0.1-SNAPSHOT</version><name>spring-boot-easypoi</name><description>pringBoot实现Excel导入导出</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.4.0</version></dependency><!--springfox swagger官方Starter--><dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artifactId><version>3.0.0</version></dependency><!--lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!--SpringBoot通用依赖模块--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2.2 结果集封装

package com.easypoi.common.api;/*** 封装API的错误码*/
public interface IErrorCode {long getCode();String getMessage();
}
package com.easypoi.common.api;/*** 枚举了一些常用API操作码*/
public enum ResultCode implements IErrorCode {SUCCESS(200, "操作成功"),FAILED(500, "操作失败"),VALIDATE_FAILED(404, "参数检验失败"),UNAUTHORIZED(401, "暂未登录或token已经过期"),FORBIDDEN(403, "没有相关权限");private long code;private String message;private ResultCode(long code, String message) {this.code = code;this.message = message;}public long getCode() {return code;}public String getMessage() {return message;}
}
package com.easypoi.common.api;/*** 通用返回对象*/
public class CommonResult<T> {private long code;private String message;private T data;protected CommonResult() {}protected CommonResult(long code, String message, T data) {this.code = code;this.message = message;this.data = data;}/*** 成功返回结果** @param data 获取的数据*/public static <T> CommonResult<T> success(T data) {return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);}/*** 成功返回结果** @param data    获取的数据* @param message 提示信息*/public static <T> CommonResult<T> success(T data, String message) {return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);}/*** 失败返回结果** @param errorCode 错误码*/public static <T> CommonResult<T> failed(IErrorCode errorCode) {return new CommonResult<T>(errorCode.getCode(), errorCode.getMessage(), null);}/*** 失败返回结果** @param message 提示信息*/public static <T> CommonResult<T> failed(String message) {return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);}/*** 失败返回结果*/public static <T> CommonResult<T> failed() {return failed(ResultCode.FAILED);}/*** 参数验证失败返回结果*/public static <T> CommonResult<T> validateFailed() {return failed(ResultCode.VALIDATE_FAILED);}/*** 参数验证失败返回结果** @param message 提示信息*/public static <T> CommonResult<T> validateFailed(String message) {return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);}/*** 未登录返回结果*/public static <T> CommonResult<T> unauthorized(T data) {return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);}/*** 未授权返回结果*/public static <T> CommonResult<T> forbidden(T data) {return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);}public long getCode() {return code;}public void setCode(long code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public T getData() {return data;}public void setData(T data) {this.data = data;}
}

2.3 Swagger配置

package com.easypoi.config;import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** Swagger2API文档的配置*/
@Configuration
@EnableSwagger2
public class Swagger2Config {@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()//为当前包下controller生成API文档.apis(RequestHandlerSelectors.basePackage("com.easypoi.controller"))//为有@Api注解的Controller生成API文档.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))//为有@ApiOperation注解的方法生成API文档.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)).paths(PathSelectors.any()).build();}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("SwaggerUI演示").description("mall-tiny").contact(new Contact("macro", null, null)).version("1.0").build();}
}

2.4 启动类

package com.easypoi;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringBootEasypoiApplication {public static void main(String[] args) {SpringApplication.run(SpringBootEasypoiApplication.class, args);}}

2.5 配置文件

server:port: 8088springfox:documentation:enabled: true

2.6 实体类

package com.easypoi.domain;import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;import java.util.Date;/*** 购物会员*/
@Data
@EqualsAndHashCode(callSuper = false)
public class Member {@Excel(name = "ID", width = 10)private Long id;@Excel(name = "用户名", width = 20, needMerge = true)private String username;private String password;@Excel(name = "昵称", width = 20, needMerge = true)private String nickname;@Excel(name = "出生日期", width = 20, format = "yyyy-MM-dd")private Date birthday;@Excel(name = "手机号", width = 20, needMerge = true, desensitizationRule = "3_4")private String phone;private String icon;@Excel(name = "性别", width = 10, replace = {"男_0", "女_1"})private Integer gender;
}
package com.easypoi.domain;import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
import cn.afterturn.easypoi.excel.annotation.ExcelEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;import java.util.Date;
import java.util.List;/*** 订单*/
@Data
@EqualsAndHashCode(callSuper = false)
public class Order {@Excel(name = "ID", width = 10, needMerge = true)private Long id;@Excel(name = "订单号", width = 20, needMerge = true)private String orderSn;@Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss", needMerge = true)private Date createTime;@Excel(name = "收货地址", width = 20, needMerge = true)private String receiverAddress;@ExcelEntity(name = "会员信息")private Member member;@ExcelCollection(name = "商品列表")private List<Product> productList;
}
package com.easypoi.domain;import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;import java.math.BigDecimal;/*** 商品*/
@Data
@EqualsAndHashCode(callSuper = false)
public class Product {@Excel(name = "ID", width = 10)private Long id;@Excel(name = "商品SN", width = 20)private String productSn;@Excel(name = "商品名称", width = 20)private String name;@Excel(name = "商品副标题", width = 30)private String subTitle;@Excel(name = "品牌名称", width = 20)private String brandName;@Excel(name = "商品价格", width = 10)private BigDecimal price;@Excel(name = "购买数量", width = 10, suffix = "件")private Integer count;
}

2.7 工具类

package com.easypoi.util;import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;import java.nio.charset.Charset;
import java.util.List;/*** 从本地获取JSON数据的工具类*/
public class LocalJsonUtil {/*** 从指定路径获取JSON并转换为List** @param path        json文件路径* @param elementType List元素类型*/public static <T> List<T> getListFromJson(String path, Class<T> elementType) {ClassPathResource resource = new ClassPathResource(path);String jsonStr = IoUtil.read(resource.getStream(), Charset.forName("UTF-8"));JSONArray jsonArray = new JSONArray(jsonStr);return JSONUtil.toList(jsonArray, elementType);}
}

LocalJsonUtil工具类,可以直接从resources目录下获取JSON数据并转化为对象。

2.8 字段处理器

package com.easypoi.handler;import cn.afterturn.easypoi.handler.impl.ExcelDataHandlerDefaultImpl;
import cn.hutool.core.util.StrUtil;
import com.easypoi.domain.Member;/*** 自定义字段处理*/
public class MemberExcelDataHandler extends ExcelDataHandlerDefaultImpl<Member> {@Overridepublic Object exportHandler(Member obj, String name, Object value) {if("昵称".equals(name)){String emptyValue = "暂未设置";if(value==null){return super.exportHandler(obj,name,emptyValue);}if(value instanceof String&&StrUtil.isBlank((String) value)){return super.exportHandler(obj,name,emptyValue);}}return super.exportHandler(obj, name, value);}@Overridepublic Object importHandler(Member obj, String name, Object value) {return super.importHandler(obj, name, value);}
}

2.9 处理器

package com.easypoi.controller;import cn.afterturn.easypoi.entity.vo.NormalExcelConstants;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.view.PoiBaseView;
import com.easypoi.common.api.CommonResult;
import com.easypoi.domain.Member;
import com.easypoi.domain.Order;
import com.easypoi.domain.Product;
import com.easypoi.handler.MemberExcelDataHandler;
import com.easypoi.util.LocalJsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;/*** EasyPoi导入导出测试Controller*/
@Controller
@Api(tags = "EasyPoiController", description = "EasyPoi导入导出测试")
@RequestMapping("/easyPoi")
public class EasyPoiController {@ApiOperation(value = "导出会员列表Excel")@RequestMapping(value = "/exportMemberList", method = RequestMethod.GET)public void exportMemberList(ModelMap map,HttpServletRequest request,HttpServletResponse response) {List<Member> memberList = LocalJsonUtil.getListFromJson("json/members.json", Member.class);ExportParams params = new ExportParams("会员列表", "会员列表", ExcelType.XSSF);//对导出结果进行自定义处理MemberExcelDataHandler handler = new MemberExcelDataHandler();handler.setNeedHandlerFields(new String[]{"昵称"});params.setDataHandler(handler);map.put(NormalExcelConstants.DATA_LIST, memberList);map.put(NormalExcelConstants.CLASS, Member.class);map.put(NormalExcelConstants.PARAMS, params);map.put(NormalExcelConstants.FILE_NAME, "memberList");PoiBaseView.render(map, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);}@ApiOperation("从Excel导入会员列表")@RequestMapping(value = "/importMemberList", method = RequestMethod.POST)@ResponseBodypublic CommonResult importMemberList(@RequestPart("file") MultipartFile file) {ImportParams params = new ImportParams();params.setTitleRows(1);params.setHeadRows(1);try {List<Member> list = ExcelImportUtil.importExcel(file.getInputStream(),Member.class, params);return CommonResult.success(list);} catch (Exception e) {e.printStackTrace();return CommonResult.failed("导入失败!");}}@ApiOperation(value = "导出订单列表Excel")@RequestMapping(value = "/exportOrderList", method = RequestMethod.GET)public void exportOrderList(ModelMap map,HttpServletRequest request,HttpServletResponse response) {List<Order> orderList = getOrderList();ExportParams params = new ExportParams("订单列表", "订单列表", ExcelType.XSSF);//导出时排除一些字段params.setExclusions(new String[]{"ID", "出生日期", "性别"});map.put(NormalExcelConstants.DATA_LIST, orderList);map.put(NormalExcelConstants.CLASS, Order.class);map.put(NormalExcelConstants.PARAMS, params);map.put(NormalExcelConstants.FILE_NAME, "orderList");PoiBaseView.render(map, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);}private List<Order> getOrderList() {List<Order> orderList = LocalJsonUtil.getListFromJson("json/orders.json", Order.class);List<Product> productList = LocalJsonUtil.getListFromJson("json/products.json", Product.class);List<Member> memberList = LocalJsonUtil.getListFromJson("json/members.json", Member.class);for (int i = 0; i < orderList.size(); i++) {Order order = orderList.get(i);order.setMember(memberList.get(i));order.setProductList(productList);}return orderList;}
}

2.10 测试

接下来介绍下EasyPoi的使用,以会员信息和订单信息的导入导出为例,分别实现下简单的单表导出和具有关联信

息的复杂导出。

2.10.1 简单导出

我们以会员信息列表导出为例,使用EasyPoi来实现下导出功能,看看是不是够简单!

  • 首先创建一个会员对象Member,封装会员信息;

  • 在此我们就可以看到EasyPoi的核心注解@Excel,通过在对象上添加@Excel注解,可以将对象信息直接导出

    到Excel中去,下面对注解中的属性做个介绍;

    • name:Excel中的列名;

    • width:指定列的宽度;

    • needMerge:是否需要纵向合并单元格;

    • format:当属性为时间类型时,设置时间的导出导出格式;

    • desensitizationRule:数据脱敏处理,3_4表示只显示字符串的前3位和后4位,其他为*号;

    • replace:对属性进行替换;

    • suffix:对数据添加后缀。

  • 接下来我们在Controller中添加一个接口,用于导出会员列表到Excel,导出的member.json的内容:

[{"id": 1,"username": "admin","password": null,"nickname": "Admin","birthday": "1994-12-31","phone": "18790000000","icon": null,"gender": 0},{"id": 2,"username": "macro","password": null,"nickname": "Macro","birthday": "1995-01-31","phone": "18791000000","icon": null,"gender": 0},{"id": 3,"username": "andy","password": null,"nickname": "Andy","birthday": "1995-02-28","phone": "18792000000","icon": null,"gender": 1},{"id": 4,"username": "ruby","password": null,"nickname": "Ruby","birthday": "1995-03-31","phone": "18793000000","icon": null,"gender": 1},{"id": 5,"username": "tom","password": null,"nickname": "","birthday": "1995-03-31","phone": "18793000000","icon": null,"gender": 1}
]

运行项目,直接通过Swagger访问接口,注意在Swagger中访问接口无法直接下载,需要点击返回结果中的下载按

钮才行,访问地址:http://localhost:8088/swagger-ui/

在这里插入图片描述

在这里插入图片描述

下载完成后,查看下文件,一个标准的Excel文件已经被导出了。

memberList.xlsx文件内容:

在这里插入图片描述

2.10.2 简单导入

导入功能实现起来也非常简单,下面以会员信息列表的导入为例。

  • 在Controller中添加会员信息导入的接口,这里需要注意的是使用@RequestPart注解修饰文件上传参数,否

    则在Swagger中就没法显示上传按钮了;

  • 然后在Swagger中测试接口,选择之前导出的Excel文件即可,导入成功后会返回解析到的数据。

在这里插入图片描述

得到的结果:

{"code": 200,"message": "操作成功","data": [{"id": 1,"username": "admin","password": null,"nickname": "Admin","birthday": "1994-12-30T16:00:00.000+00:00","phone": "187****0000","icon": null,"gender": 0},{"id": 2,"username": "macro","password": null,"nickname": "Macro","birthday": "1995-01-30T16:00:00.000+00:00","phone": "187****0000","icon": null,"gender": 0},{"id": 3,"username": "andy","password": null,"nickname": "Andy","birthday": "1995-02-27T16:00:00.000+00:00","phone": "187****0000","icon": null,"gender": 1},{"id": 4,"username": "ruby","password": null,"nickname": "Ruby","birthday": "1995-03-30T16:00:00.000+00:00","phone": "187****0000","icon": null,"gender": 1},{"id": 5,"username": "tom","password": null,"nickname": "暂未设置","birthday": "1995-03-30T16:00:00.000+00:00","phone": "187****0000","icon": null,"gender": 1}]
}
2.10.3 复杂导出

当然EasyPoi也可以实现更加复杂的Excel操作,比如导出一个嵌套了会员信息和商品信息的订单列表,下面我们来

实现下!

  • 首先添加商品对象Product,用于封装商品信息;

  • 然后添加订单对象Order,订单和会员是一对一关系,使用@ExcelEntity注解表示,订单和商品是一对多关

    系,使用@ExcelCollection注解表示,Order就是我们需要导出的嵌套订单数据;

  • 接下来在Controller中添加导出订单列表的接口,由于有些会员信息我们不需要导出,可以调用

    ExportParams中的setExclusions方法排除掉;

  • 在Swagger中访问接口测试,导出订单列表对应Excel;

products.json的内容:

[{"id": 1,"productSn": "7437788","name": "小米8","subTitle": "全面屏游戏智能手机 6GB+64GB 黑色 全网通4G 双卡双待","brandName": "小米","price": 2699,"count": 1},{"id": 2,"productSn": "7437789","name": "红米5A","subTitle": "全网通版 3GB+32GB 香槟金 移动联通电信4G手机 双卡双待","brandName": "小米","price": 649,"count": 1},{"id": 3,"productSn": "7437799","name": "Apple iPhone 8 Plus","subTitle": "64GB 红色特别版 移动联通电信4G手机","brandName": "苹果","price": 5499,"count": 1}
]

orders.json的内容:

[{"id": 1,"orderSn": "201809150101000001","createTime": "2021-10-10 17:02:28","receiverAddress": "广东省深圳市"},{"id": 1,"orderSn": "201809150101000002","createTime": "2021-10-11 17:02:28","receiverAddress": "江苏省南京市"},{"id": 1,"orderSn": "201809150101000003","createTime": "2021-10-12 17:02:28","receiverAddress": "江苏省苏州市"}
]

在这里插入图片描述

  • 下载完成后,查看下文件,EasyPoi导出复杂的Excel也是很简单的!

在这里插入图片描述

2.10.4 自定义处理

如果你想对导出字段进行一些自定义处理,EasyPoi也是支持的,比如在会员信息中,如果用户没有设置昵称,我

们添加下暂未设置信息。

  • 我们需要添加一个处理器继承默认的ExcelDataHandlerDefaultImpl类,然后在exportHandler方法中实

    现自定义处理逻辑;

  • 然后修改Controller中的接口,调用MemberExcelDataHandler处理器的setNeedHandlerFields设置需要

    自定义处理的字段,并调用ExportParamssetDataHandler设置自定义处理器;

  • 再次调用导出接口,我们可以发现昵称已经添加默认设置了。

上面的代码已经是自定义处理过的。

//对导出结果进行自定义处理
MemberExcelDataHandler handler = new MemberExcelDataHandler();
handler.setNeedHandlerFields(new String[]{"昵称"});
params.setDataHandler(handler);

3、总结

体验了一波EasyPoi,它使用注解来操作Excel的方式确实非常好用。如果你想生成更为复杂的Excel的话,可以考

虑下它的模板功能。

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

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

相关文章

初始MySQL(五)(自我复制数据,合并查询,外连接,MySQL约束:主键,not null,unique,foreign key)

目录 表复制 自我复制数据(蠕虫复制) 合并查询 union all(不会去重) union(会自动去重) MySQL表的外连接 左连接 右连接 MySQL的约束 主键 not null unique(唯一) foreign key(外键) 表复制 自我复制数据(蠕虫复制) #为了对某个sql语句进行效率测试,我们需要海量…

redis之org.springframework.data.redis.RedisSystemException: Error in execution

背景 在运行某系统时&#xff0c;在测试类向redis中存入某值&#xff0c;然后取出。 一、遇到的问题 报错&#xff1a; org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: …

查看dll是32位还是64位

根据资料&#xff0c;用记事本打开dll文件&#xff1b;找到字符串 PE&#xff0c;其后不远如果出现L&#xff0c;是32位&#xff1b;字符串PE后出现 d? 是64位&#xff1b; 打开一个看一下&#xff1b;这个是32位&#xff1b; 这是从网上看的&#xff1b; 然后用dumpbin.exe工…

docker安装AWVS 23.9.231005181

本文声明仅AWVS用作学习使用 将镜像文件secfa_awvs.tar复制到目标机器上。 我的百度网盘文件路径&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1Pe4qlVp9XKbZ3dLrouaP2w 提取码&#xff1a;67mc –来自百度网盘超级会员V6的分享 在目标机器上&#xff0c;使用以下命…

No195.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

Postgres的级数生成函数generate_series应用

Postgres的级数生成函数generate_series应用 引用&#xff1a;http://postgres.cn/docs/12/functions-srf.html 函数文档 函数 参数类型 返回类型 描述 generate_series(start, stop) int、bigint或者numeric setof int、setof bigint或者setof numeric&#xff08;与参数类型相…

为什么Android 手机这么慢?如何提高 Android 手机的运行速度

速印机&#xff08;理想、荣大等&#xff09;、复印机&#xff08;夏普、东芝、理光、佳能、震旦等全系列&#xff09;、打印机、扫描仪、传真机、多媒体教学一体机、交互式电子白板、报警器材、监控、竞业达监考设备及其它监考设备、听力考试设备、特种安防设备维护及维修。吴…

时间序列预测:深度学习、机器学习、融合模型、创新模型实战案例(附代码+数据集+原理介绍)

本文介绍->给大家推荐一下我的时间序列预测实战专栏&#xff0c;本专栏平均质量分98分&#xff0c;而且本专栏目前免费阅读。其中涉及机器学习、深度学习、融合模型、个人创新模型、数据分析等一系列有关时间序列的内容&#xff0c;其中的实战案例不仅有简单的模型类似于机器…

EXIT(1)

EXTI介绍 EXTI是片上外设 NVIC是cpu内的外设 回忆起之前的GPIO和AFIO 我们是如何检测按键按下的 我们是一直用while循环读取IDR寄存器的对应位置的值 一直检测判断按键是否被按下 那么是否有第二种方式检测按键是否被按下了呢&#xff1f; 通过EXTI 当EXTI检测到按键的电平发生…

飞书开发学习笔记(五)-Python快速开发网页应用

飞书开发学习笔记(五)-Python快速开发网页应用 一.下载示例代码 首先进入飞书开放平台: https://open.feishu.cn/app 凭证与基础信息 页面&#xff0c;在 应用凭证 中获取 App ID 和 App Secret 值。 教程和示例代码位置:https://open.feishu.cn/document/home/integrating-…

Vue+OpenLayers 创建地图并显示鼠标所在经纬度

1、效果 2、创建地图 本文用的是高德地图 页面 <div class"map" id"map"></div><div id"mouse-position" class"position_coordinate"></div>初始化地图 var gaodeLayer new TileLayer({title: "高德地…

Spring Boot 中自动装配机制的原理

&#xff08;摘自mic老师面试题&#xff09; 最近一个粉丝说&#xff0c;他面试了 4 个公司&#xff0c;有三个公司问他&#xff1a;“Spring Boot 中自动装配 机制的原理” 他回答了&#xff0c;感觉没回答错误&#xff0c;但是怎么就没给 offer 呢&#xff1f; 对于这个问题…