当前位置: 首页 > news >正文

基于EasyExcel的数据导入导出

前言:
代码复制粘贴即可用,主要包含的功能有Excel模板下载、基于Excel数据导入、Excel数据导出。

根据实际情况修改一些细节即可,最后有结果展示,可以先看下结果,是否是您想要的。

台上一分钟,台下60秒,不喜勿喷。

觉得有用,麻烦点个赞和关注。

新建SpringBoot项目,引入下面的依赖
注:这个依赖已经整合了 poi 和poi-ooxm,无需单独引入。

 <!-- EasyExcel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.7</version></dependency>

数据导入导出执行原理和思路:
用户端逻辑:

  1. 数据导入

     用户先下载模板,根据模板填入数据,然后点击上传;
    
  2. 数据导出

     用户在界面选择需要导出的数据(导出条件),点击导出。
    

后台开发逻辑:

  1. 模板下载

     利用easyExcel生成文件,然后将文件放进响应流中,同时设置响应头为文件下载,浏览器收到响应之后,回去解析流中的内容,然后进行下载。
    
  2. 文件上传

     用在填写好Excel内容之后,会以文件上传的形式,将文件上传到服务端,此时,我们只需要利用EasyExcel将文件流中的数据读出来即可。
    
  3. 数据导出

     后台在接收到用户的数据导出请求之后,会根据请求中的筛选条件,查询对应数据,再将对应的数据填充进对应的导出模板中,以流的形式响应给浏览器。其实和模板下载的差不错,只是模板下载没有数据,数据导出有数据而已。
    

代码实现
说明:以下代码,是我根据具体业务编写之后整理出来的,会有不足的地方,欢迎指教!

下拉框策略
如果没有此需求,可以不要此类。

import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;import java.util.Map;
import java.util.TreeMap;/*** 这个类的作用主要是给列增加下拉框* 主要是为了方便用户填写数据*/
public class CustomSheetWriteHandler implements SheetWriteHandler {/*** 存放下拉内容的集合* key为列的下标, value为下拉内容数组*/private final Map<Integer, String[]> map = new TreeMap<>();/*** 工作簿下标,从0开始*/private int index = 0;/*** 给多少行添加下拉框,这里默认给2000行*/private final int batchSize = 2000;@Overridepublic void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {}/*** 宝藏在此:如果下拉框内容总的长度超过255,会导致Cell有下拉框,但是下拉内容显示不了,* 这时我们可以新建一个sheet,将其隐藏,然后将里面的内容引用到我们的下拉框列就可以。* 值得细品* @param writeWorkbookHolder* @param writeSheetHolder*/@Overridepublic void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {// excel下标从0开始,这里第二列的下拉选择内容map.put(1, new String[]{"下拉内容一", "下拉内容二"});// excel下标从0开始,这里第三列的下拉选择内容map.put(3, new String[]{"北京市", "上海市", "重庆市", "天津市"});DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();map.forEach((k, v) -> {// 创建sheet,突破下拉框255的限制// 获取一个workbookWorkbook workbook = writeWorkbookHolder.getWorkbook();// 定义sheet的名称String sheetName = "sheet" + k;// 1.创建一个隐藏的sheet 名称为 proviceSheetSheet proviceSheet = workbook.createSheet(sheetName);// 从第二个工作簿开始隐藏this.index++;// 设置隐藏workbook.setSheetHidden(this.index, true);// 2.循环赋值(为了防止下拉框的行数与隐藏域的行数相对应,将隐藏域加到结束行之后)for (int i = 0, length = v.length; i < length; i++) {// i:表示你开始的行数 0表示你开始的列数proviceSheet.createRow(i).createCell(0).setCellValue(v[i]);}Name category1Name = workbook.createName();category1Name.setNameName(sheetName);// 4 $A$1:$A$N代表 以A列1行开始获取N行下拉数据category1Name.setRefersToFormula(sheetName + "!$A$1:$A$" + (v.length));// 5 将刚才设置的sheet引用到你的下拉列表中,1表示从行的序号1开始(开始行,通常行的序号为0的行是表头),50表示行的序号50(结束行),表示从行的序号1到50,k表示开始列序号和结束列序号CellRangeAddressList addressList = new CellRangeAddressList(1, batchSize, k, k);DataValidationConstraint constraint8 = helper.createFormulaListConstraint(sheetName);DataValidation dataValidation3 = helper.createValidation(constraint8, addressList);// 阻止输入非下拉选项的值dataValidation3.setErrorStyle(DataValidation.ErrorStyle.STOP);dataValidation3.setShowErrorBox(true);dataValidation3.setSuppressDropDownArrow(true);dataValidation3.createErrorBox("提示", "此值与单元格定义格式不一致");// validation.createPromptBox("填写说明:","填写内容只能为下拉数据集中的单位,其他单位将会导致无法入仓");writeSheetHolder.getSheet().addValidationData(dataValidation3);});}
}

批注策略
给表头添加批注,没有此需求可以不要

import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;/*** 自定义拦截器.新增注释,第一行头加批注* 这个类的作用主要是给表头添加批注*/
@Slf4j
public class CommentWriteHandler implements RowWriteHandler {@Overridepublic void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer rowIndex, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {}@Overridepublic void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {Sheet sheet = writeSheetHolder.getSheet();Drawing<?> drawingPatriarch = sheet.createDrawingPatriarch();// 在第一行 第二列创建一个批注Comment comment1 =drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short)0, 0, (short)1, 1));// 输入批注信息comment1.setString(new XSSFRichTextString("批注1"));// 将批注添加到单元格对象中sheet.getRow(0).getCell(0).setCellComment(comment1);Comment comment2 =drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short)1, 0, (short)2, 1));// 输入批注信息comment2.setString(new XSSFRichTextString("批注2"));// 将批注添加到单元格对象中sheet.getRow(0).getCell(1).setCellComment(comment2);Comment comment3 =drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short)2, 0, (short)3, 1));// 输入批注信息comment3.setString(new XSSFRichTextString("批注3"));// 将批注添加到单元格对象中sheet.getRow(0).getCell(2).setCellComment(comment3);}
}

数据读取监听
导入数据时,程序解析和读取数据用,必须要!!!

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** Excel数据解析监听器, 数据解析方法异步执行* @param <T>   Excel中数据的类型*/
@Getter
@Setter
@NoArgsConstructor
public class ExcelListener<T> extends AnalysisEventListener<T> {// 加入一个判断标签,判断数据是否已经读取完private volatile boolean retryLock = false;// 解析完成后的数据集合, 监听对象初始化之后,立即初始化集合对象private final List<T> dataList = new ArrayList<>();// 每次最多导入条数private final int batchSize = 2000;/*** 获取解析后的数据集合, 如果数据还没有被解析完成,会对读取该集合的线程进行阻塞,直到数据读取完成之后,进行解锁。* 如果一次导入数据超过batchSize条,则以抛异常的形式阻止导入数据* @return  解析后的数据集合*/public List<T> getDataList() {while (true){if (retryLock){if (dataList.size() > batchSize){// 手动清空数据内存数据,减少内存消耗dataList.clear();throw new RuntimeException("一次最多导入"+ batchSize +"条数据");} else {return dataList;}}}}/*** Excel每解析一行数据,就会调用一次该方法* @param data*            one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param context*            analysis context*/@Overridepublic void invoke(T data, AnalysisContext context) {dataList.add(data);}/*** 读取表头内容* @param headMap   表头部数据* @param context   数据解析上下文*/@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {//System.out.println("表头:" + headMap);}/*** 流中的数据解析完成之后,就会调用此方法* @param context*/@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 数据解析完成,解锁retryLock = true;}/*** 解析过程如果发生异常,会调用此方法* @param exception* @param context*/@Overridepublic void onException(Exception exception, AnalysisContext context){throw new RuntimeException("Excel数据异常,请检查或联系管理员!");}
}

Excel工具类
封装统一的Excel操作入口

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;@Slf4j
public class ExcelUtil {/*** 导出数据为excel文件** @param filename       文件名称* @param dataResult     集合内的bean对象类型要与clazz参数一致* @param clazz          集合内的bean对象类型要与clazz参数一致* @param response       HttpServlet响应对象*/public static void export(String filename, List<?> dataResult, Class<?> clazz, HttpServletResponse response) {response.setStatus(200);OutputStream outputStream = null;ExcelWriter excelWriter = null;try {if (StringUtils.isBlank(filename)) {throw new RuntimeException("'filename' 不能为空");}String fileName = filename.concat(".xlsx");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));outputStream = response.getOutputStream();// 根据不同的策略生成不同的ExcelWriter对象if (dataResult == null){excelWriter = getTemplateExcelWriter(outputStream);} else {excelWriter = getExportExcelWriter(outputStream);}WriteTable writeTable = EasyExcel.writerTable(0).head(clazz).needHead(true).build();WriteSheet writeSheet = EasyExcel.writerSheet(fileName).build();// 写出数据excelWriter.write(dataResult, writeSheet, writeTable);} catch (Exception e) {log.error("导出excel数据异常:", e);throw new RuntimeException(e);} finally {if (excelWriter != null) {excelWriter.finish();}if (outputStream != null) {try {outputStream.flush();outputStream.close();} catch (IOException e) {log.error("导出数据关闭流异常", e);}}}}/*** 根据不同策略生成不同的ExcelWriter对象, 可根据实际情况修改* @param outputStream  数据输出流* @return  模板下载ExcelWriter对象*/private static ExcelWriter getTemplateExcelWriter(OutputStream outputStream){return EasyExcel.write(outputStream).registerWriteHandler(new CommentWriteHandler())        //增加批注策略.registerWriteHandler(new CustomSheetWriteHandler())    //增加下拉框策略.registerWriteHandler(getStyleStrategy())               //字体居中策略.build();}/*** 根据不同策略生成不同的ExcelWriter对象, 可根据实际情况修改* @param outputStream  数据输出流* @return  数据导出ExcelWriter对象*/private static ExcelWriter getExportExcelWriter(OutputStream outputStream){return EasyExcel.write(outputStream).registerWriteHandler(getStyleStrategy())   //字体居中策略.build();}/***  设置表格内容居中显示策略* @return*/private static HorizontalCellStyleStrategy getStyleStrategy(){WriteCellStyle headWriteCellStyle = new WriteCellStyle();//设置背景颜色headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());//设置头字体WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short)13);headWriteFont.setBold(true);headWriteCellStyle.setWriteFont(headWriteFont);//设置头居中headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 内容策略WriteCellStyle writeCellStyle = new WriteCellStyle();// 设置内容水平居中writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);return new HorizontalCellStyleStrategy(headWriteCellStyle, writeCellStyle);}/*** 根据Excel模板,批量导入数据* @param file  导入的Excel* @param clazz 解析的类型* @return  解析完成的数据*/public static List<?> importExcel(MultipartFile file, Class<?> clazz){if (file == null || file.isEmpty()){throw new RuntimeException("没有文件或者文件内容为空!");}List<Object> dataList = null;BufferedInputStream ipt = null;try {InputStream is = file.getInputStream();// 用缓冲流对数据流进行包装ipt = new BufferedInputStream(is);// 数据解析监听器ExcelListener<Object> listener = new ExcelListener<>();// 读取数据EasyExcel.read(ipt, clazz,listener).sheet().doRead();// 获取去读完成之后的数据dataList = listener.getDataList();} catch (Exception e){log.error(String.valueOf(e));throw new RuntimeException("数据导入失败!" + e);}return dataList;}}

创建导入数据模板类
可以理解为这个类是我们和客户之间的约定,程序根据这个模板类生成对应的Excel文件,客户根据Excel文件将数据填充进来。然后用户将填充好的Excel文件上传到我们的程序中,我们还得根据这个模板类来解析读取用户填充的数据。

根据实际业务调整,上面的工具类会根据提供的模板生成对应的Excel文件。

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;
import lombok.experimental.Accessors;import javax.validation.constraints.NotEmpty;
import java.io.Serializable;/*** 数据导入的Excel模板实体*/
@Data
public class ImportExcelVo implements Serializable {private static final long serialVersionUID = 1L;@ColumnWidth(20)@ExcelProperty(value = "公司名称", index = 0)private String name;@ColumnWidth(20)@ExcelProperty(value = "公司联系电话", index = 1)private String phone;@ColumnWidth(28)@ExcelProperty(value = "公司统一社会信用代码", index = 2)private String creditCode;@ColumnWidth(15)@ExcelProperty(value = "区域", index = 3)private String province;@ColumnWidth(15)@ExcelProperty(value = "公司法人", index = 4)private String legalPerson;@ExcelProperty(value = "备注", index = 5)private String remark;
}

创建数据导出模板
根据此模板,向用户展示用户可以看到的字段。

根据实际业务调整,上面的工具类会根据提供的模板生成对应的Excel文件。

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import lombok.Data;
import lombok.experimental.Accessors;import java.io.Serializable;/*** 资质信息导出实体*/
@Data   // Lombok注解,用于生成getter setter
@Accessors(chain = true) //Lombok注解,链式赋值使用
public class ExportExcelVo implements Serializable {private static final long serialVersionUID = 1L;@ColumnWidth(25)@ExcelProperty(value = "企业名称", index = 0)private String name;@ColumnWidth(25)@ExcelProperty(value = "社会统一信用代码", index = 1)private String creditCode;@ColumnWidth(15)@ExcelProperty(value = "曾用名", index = 2)private String formerName;@ColumnWidth(15)@ExcelProperty(value = "公司法人", index = 3)private String legalPerson;@ExcelProperty(value = "区域", index = 4)private String province;@ExcelProperty(value = "录入时间", index = 5)private String createTime;@ColumnWidth(15)@ExcelProperty(value = "公司股东", index = 6)private String stockholder;@ExcelProperty(value = "企业联系方式", index = 7)private String contact;}

Web接口

import lombok.extern.slf4j.Slf4j;
import com.xxx.xxx.domain.vo.ExportExcelVo;
import com.xxx.xxx.domain.vo.ImportExcelVo;
import com.xxx.xxx.util.CommonResponse;
import com.xxx.xxx.util.ExcelUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;/*** 事件控制器*/
@Slf4j
@RestController
@RequestMapping("/api/excel")
public class ExcelController {/*** excel模板下载*/@RequestMapping(value = "/template", method = RequestMethod.GET)public CommonResponse<String> template(HttpServletResponse response){String fileName = "导入模板下载" + System.currentTimeMillis();try {ExcelUtil.export(fileName, null, ImportExcelVo.class, response);} catch (Exception e) {return CommonResponse.error("模板下载失败" + e.getMessage());}return CommonResponse.success("模板下载成功!");}/*** Excel批量导入数据* @param file 导入文件*/@RequestMapping(value = "/import", method = RequestMethod.POST)public CommonResponse<String> importEvents(MultipartFile file){try {List<?> list = ExcelUtil.importExcel(file, ImportExcelVo.class);System.out.println(list);return CommonResponse.success("数据导入完成");} catch (Exception e) {return CommonResponse.error("数据导入失败!" + e.getMessage());}}/*** excel数据导出* @param size  导出条数, 也可以是用户需要导出数据的条件* @return*/@RequestMapping(value = "/export", method = RequestMethod.GET)public CommonResponse<String> export(Long size, HttpServletResponse response){// 模拟根据条件在数据库查询数据ArrayList<ExportExcelVo> excelVos = new ArrayList<>();for (int i = 1; i <= size; i++) {ExportExcelVo excelVo = new ExportExcelVo();excelVo.setContact(String.valueOf(10000000000L + i));excelVo.setName("公司名称" + i);excelVo.setCreditCode("社会性用代码" + i);excelVo.setProvince("地区" + i);excelVo.setLegalPerson("法人" + i);excelVo.setFormerName("曾用名" + i);excelVo.setStockholder("投资人" + i);excelVo.setCreateTime(new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒").format(new Date()));excelVos.add(excelVo);}String fileName = "数据导出" + System.currentTimeMillis();try {ExcelUtil.export(fileName, excelVos, ExportExcelVo.class, response);} catch (Exception e) {return CommonResponse.error("数据导出成功" + e.getMessage());}return CommonResponse.success("数据导出失败!");}}

结果展示
模板下载
浏览器访问模板下载接口,然后会根据接口返回的内容进行解析
在这里插入图片描述
在这里插入图片描述
数据导入
填充数据,在下载下来的模板中填入数据
在这里插入图片描述
利用PostMan进行文件上传
在这里插入图片描述
数据导出
浏览器访问数据导出接口
在这里插入图片描述
在这里插入图片描述

相关文章:

基于EasyExcel的数据导入导出

前言&#xff1a; 代码复制粘贴即可用&#xff0c;主要包含的功能有Excel模板下载、基于Excel数据导入、Excel数据导出。 根据实际情况修改一些细节即可&#xff0c;最后有结果展示&#xff0c;可以先看下结果&#xff0c;是否是您想要的。 台上一分钟&#xff0c;台下60秒&a…...

电子学会C/C++编程等级考试2021年06月(六级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:逆波兰表达式 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* +…...

智能优化算法应用:基于供需算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于供需算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于供需算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.供需算法4.实验参数设定5.算法结果6.参考文献7.MA…...

vue3 setup语法糖写法基本教程

前言 官网地址&#xff1a;Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)下面只讲Vue3与Vue2有差异的地方&#xff0c;一些相同的地方我会忽略或者一笔带过与Vue3一同出来的还有Vite&#xff0c;但是现在不使用它&#xff0c;等以后会有单独的教程使用。目前仍旧使用v…...

利用两个指针的差值求字符串长度

指针和指针也可以相加减&#xff0c;例如定义一个一维数组arr[10]&#xff1b;再定义一个指针&#xff08;int *p&#xff09;指向数组首元素的地址&#xff0c;定义一个指针&#xff08;int* q&#xff09;指向数组最后一个元素的地址&#xff0c;那么q-p的结果就是整个数组的…...

ping命令的工作原理

ping&#xff0c;Packet Internet Groper&#xff0c;是一种因特网包探索器&#xff0c;用于测试网络连接量的程序。Ping 是工作在 TCP/IP 网络体系结构中应用层的一个服务命令&#xff0c; 主要是向特定的目的主机发送 ICMP&#xff08;Internet Control Message Protocol 因特…...

谷歌的开源供应链安全

本内容是对Go项目负责人Russ Cox 在 ACM SCORED 活动上演讲内容[1]的摘录与整理。 SCORED 是Software Supply Chain Offensive Research and Ecosystem Defenses的简称, SCORED 23[2]于2023年11月30日在丹麦哥本哈根及远程参会形式举行。 摘要 &#x1f4a1; 谷歌在开源软件供应…...

分发饼干(贪心算法)

假设你是一位很棒的家长&#xff0c;想要给你的孩子们一些小饼干。但是&#xff0c;每个孩子最多只能给一块饼干。 对每个孩子 i&#xff0c;都有一个胃口值 g[i]&#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸&#xff1b;并且每块饼干 j&#xff0c;都有一个尺寸 s[j]…...

基于ssm旅游景点管理系统设计论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本旅游景点管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…...

用go封装一下封禁功能

思路 封禁业务也是在一般项目中比较常见的业务。我们也将它封装在库中作为功能之一。 我们同样使用adapter作为底层的存储结构&#xff0c;将封禁标示作为k-v结构存储。 把id和服务名称service作为key&#xff0c;把封禁的级别level作为value&#xff0c;以此我们能实现一些比…...

loki 如何格式化日志

部署 grafana-loki 首先介绍一下如何部署 官方文档&#xff1a;部署 grafana-loki 部署命令 设置集群的存储类&#xff0c;如果有默认可以不设置设置命名空间 helm install loki oci://registry-1.docker.io/bitnamicharts/grafana-loki --set global.storageClasslocal -n …...

在Linux上使用mysqldump备份MySQL数据库的详细步骤

MySQL数据库备份是确保数据安全性的关键步骤之一。在Linux系统上&#xff0c;使用mysqldump工具是一种常见、可靠的方法&#xff0c;它能够导出数据库的结构和数据&#xff0c;以便在需要时进行还原。以下是详细的备份步骤&#xff1a; 步骤 1&#xff1a;登录到MySQL服务器 …...

神经网络基础

神经网络 引言 神经网络的历史背景 神经网络的概念最早可以追溯到20世纪40年代&#xff0c;当时的科学家们受到生物神经系统的启发&#xff0c;尝试模拟人脑的信息处理方式。在接下来的几十年里&#xff0c;这个领域经历了多次兴衰。尽管在最初几十年内进展缓慢&#xff0c;…...

你好,C++(2)1.3 C++世界版图1.4 如何学好C++

1.3 C世界版图 C语言的发展过程&#xff0c;不仅是一个特性不断增加、内容不断丰富的过程&#xff0c;更是一个在应用领域中不断攻城略地的过程。在其30余年的发展过程中&#xff0c;C在多个应用领域都得到了广泛的应用和发展。无论是在最初的UNIX/Linux操作系统上&#xff0c…...

Ceph入门到精通- smartctl -l error检查硬盘指标

“smartctl -l error” 是一个 Linux 命令&#xff0c;用于查看磁盘驱动器的 SMART (Self-Monitoring, Analysis and Reporting Technology) 错误日志。SMART 是一种技术&#xff0c;能够监测硬盘驱动器的状态并提供关于硬盘健康状况的信息。 运行该命令后&#xff0c;你将看到…...

【LeetCode刷题】-- 161.相隔为1的编辑距离

161.相隔为1的编辑距离 方法&#xff1a;一次遍历 首先&#xff0c;我们要确认字符串的长度不会相差太远。如果长度差了2个或更多字符&#xff0c;那么 s 和 t 就不可能是一次编辑之差的字符串。 接下来&#xff0c;我们假设 s 的长度总是短于或等于 t 的长度。如果不是这样&…...

SQL进阶理论篇(八):SQL查询的IO成本

文章目录 简介数据库缓冲池查看缓冲池的大小数据页加载的三种方式通过 last_query_cost 统计 SQL 语句的查询成本总结参考文献 简介 本节将介绍磁盘IO是如何加载数据的&#xff0c;重点介绍一下数据库缓冲池的概念。主要包括&#xff1a; 什么是数据库缓冲池&#xff0c;它在…...

宝塔PostgreSQL设置数据库远程访问

宝塔PostgreSQL设置数据库远程访问 宝塔的PostgreSQL1. 添加数据库2. 打开PostgreSQL设置界面3. 修改配置4. 重载配置/重启数据库 Docker的PostgreSQL1. postgresql.conf2. pg_hba.conf3. 重启数据库 注意其他问题 宝塔PostgreSQL设置数据库远程访问&#xff1f;docker容器Post…...

蓝牙协议栈学习笔记

蓝牙协议栈学习笔记 蓝牙简介 蓝牙工作在全球通用的 2.4GHz ISM&#xff08;即工业、科学、医学&#xff09;频段&#xff0c;使用 IEEE802.11 协议 蓝牙 4.0 是迄今为止第一个蓝牙综合协议规范&#xff0c;将三种规格集成在一起。其中最重要的变化就是 BLE&#xff08;Blue…...

XXE利用的工作原理,利用方法及防御的案例讲解

XXE&#xff08;XML外部实体注入&#xff09;利用是一种网络安全攻击手段&#xff0c;其中攻击者利用XML解析器处理外部实体的方式中的漏洞。这种攻击主要针对的是那些使用XML来处理数据的应用程序&#xff0c;尤其是当这些应用程序没有正确限制外部实体的处理时。通过XXE利用&…...

jpa 修改信息拦截

实现目标springbootJPA 哪个人&#xff0c;修改了哪个表的哪个字段&#xff0c;从什么值修改成什么值 import jakarta.persistence.*; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; im…...

JavaEE 09 锁策略

1.锁策略 1.1 乐观锁与悲观锁 其实前三个锁是同一种锁,只是站在不同的角度上去进行描述,此处的乐观与悲观其实是指在预测的角度上看会发生锁竞争的概率大小,概率大的则是悲观锁,概率小的则是乐观锁 乐观锁在加锁的时候就会做较少的事情,加锁的速度较快,但是消耗的cpu资源等也会…...

javacv的视频截图功能

之前做了一个资源库的小项目&#xff0c;因为上传资源文件包含视频等附件&#xff0c;所以就需要时用到这个功能。通过对视频截图&#xff0c;然后作为封面缩略图&#xff0c;达到美观效果。 首先呢&#xff0c;需要准备相关的jar包&#xff0c;之前我用的是低版本的1.4.2&…...

Fiddler中AutoResponder的简单使用

AutoResponder&#xff0c;自动回复器&#xff0c;用于将 HTTP 请求重定向为指定的返回类型。 这个功能有点像是一个代理转发器&#xff0c;可以将某一请求的响应结果替换成指定的资源&#xff0c;可以是某个页面也可以是某个本地文件 1.使用 打开“Fiddler”&#xff0c;点击…...

K8S(一)—安装部署

目录 安装部署前提以下的操作指导(在master)之前都是三台机器都需要执行 安装docker服务下面的操作仅在k8smaster执行 安装部署 前提 以下的操作指导(在master)之前都是三台机器都需要执行 关闭防火墙 [rootk8smaster ~]# vim /etc/selinux/config [rootk8smaster ~]# swa…...

Kubernetes Pod 网段与主机内网网段互通

开发环境的需求 开发环境部署 K8s 后&#xff0c;服务器会部署在 K8s 里&#xff0c;通常 Pod 网段被隔离&#xff0c;主机无法访问 实际开发需求&#xff0c;往往需要当前开发调试的服务主机本地部署&#xff0c;其他服则在 K8s 内 因此&#xff0c;使用 K8s &#xff0c;必…...

go学习redis的学习与使用

文章目录 一、redis的学习与使用1.Redis的基本介绍2.Redis的安装下载安装包即可3.Redis的基本使用1&#xff09;Redis的启动&#xff1a;2&#xff09;Redis的操作的三种方式3&#xff09;说明&#xff1a;Redis安装好后&#xff0c;默认有16个数据库&#xff0c;初始默认使用0…...

娱乐新拐点:TikTok如何改变我们的日常生活?

在数字时代的浪潮中&#xff0c;社交媒体平台不断涌现&#xff0c;其中TikTok以其独特的短视频内容在全球范围内掀起了一场娱乐革命。本文将深入探讨TikTok如何改变我们的日常生活&#xff0c;从社交互动、文化传播到个人创意表达&#xff0c;逐步改写了娱乐的新篇章。 短视频潮…...

【Nginx】Nginx了解(基础)

文章目录 Nginx产生的原因Nginx简介Nginx的作用反向代理负载均衡策略动静分离 Nginx的Windows下的安装Linux下的安装Nginx常用命令 负载均衡功能演示 Nginx产生的原因 背景 一个公司的项目刚刚上线的时候&#xff0c;并发量小&#xff0c;用户使用的少&#xff0c;所以在低并发…...

十九)Stable Diffusion使用教程:ai室内设计案例

今天我们聊聊如何通过SD进行室内设计装修。 方式一:controlnet的seg模型 基础起手式: 选择常用算法,抽卡: 抽到喜欢的图片之后,拖到controlnet里: 选择seg的ade20k预处理器,点击爆炸按钮,得到seg语义分割图,下载下来: 根据语义分割表里的颜色值,到PS里进行修改: 语…...

做网站源代码/成都seo论坛

通过kmeans分析出租车数据并进行可视化&#xff08;1&#xff09;数据准备&#xff08;2&#xff09;创建dataframe&#xff08;3&#xff09;kmeans聚类分析&#xff08;4&#xff09;调用百度API进行数据可视化&#xff08;1&#xff09;数据准备 采用数据为出租车载客时的G…...

四川住房和城乡建设部网站官网/小程序引流推广平台

bootload 加载linux 内核挂载ramdisk.imginit程序启动准备解析init.rc 和init.hardware.rc将early-init Action添加到action_queue队列中将init Action添加到action_queue队列中进入循环执行每个action中的commands里的命令启动service_list中svc_restarting服务监听属性状态变…...

阿里巴巴国际站可以做网站吗/站长工具日本

我用filezilla传的 大几千个文件 传的太慢了 有没有快速一点的方法呢&#xff1f;最快要多久&#xff1f;回答最简单&#xff1a;直接在服务器上git clone最方便&#xff1a;用部署工具Capistrano, Deployer等最快速&#xff1a;系统控的话可以用高速上传工具vagrant-unison打包…...

临沂住房和城乡建设局网站/网络营销策划方案

本文记载了如何在微信小程序里面实现下拉刷新&#xff0c;上拉加载更多 先开看一下界面 大致如此的界面吧。 这个Demo使用了微信的几个Api和事件&#xff0c;我先列出来。 1.wx.request &#xff08;获取远程服务器的数据&#xff0c;可以理解成$.ajax&#xff09; 2. scroll-v…...

镇江建站/巩义网络推广公司

重新换回wamp3.1.3开发环境&#xff0c;发现不能切换版本&#xff0c;主要原因是不能添加php到环境变量里面&#xff0c;具体问题见这篇博客&#xff1a; https://blog.csdn.net/hu_feng903/article/details/81259834 但是去掉了php环境变量&#xff0c;composer这些要怎么用…...

昌乐哪里有做网站的/互联网营销师考试

其它信息 下载: http://cdn.cocos2d-x.org/cocos2d-x-3.0alpha1.zip 完整的更新日志: https://github.com/cocos2d/cocos2d-x/blob/cocos2d-x-3.0alph1/CHANGELOG API 参考&#xff1a;http://www.cocos2d-x.org/reference/native-cpp/V3.0alpha1/index.html 要求 运行环境…...