【JAVA】easyExcel导出导入使用

news2024/11/16 17:33:27

EasyExcel是阿里巴巴开源插件之一,主要解决了poi框架使用复杂,sax解析模式不容易操作,数据量大起来容易OOM,解决了POI并发造成的报错。主要解决方式:通过解压文件的方式加载,一行一行地加载,并且抛弃样式字体等不重要的数据,降低内存的占用。

EasyExcel在SpringBoot的集成 引入对应的pom依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.11</version>
</dependency>

excel常用注解

@ExcelProperty
@ColumnWith 列宽
@ContentFontStyle 文本字体样式
@ContentLoopMerge 文本合并
@ContentRowHeight 文本行高度
@ContentStyle 文本样式
@HeadFontStyle 标题字体样式
@HeadRowHeight 标题高度
@HeadStyle 标题样式
@ExcelIgnore 忽略项
@ExcelIgnoreUnannotated 忽略未注解

@Data
public class Member {/**
   * EasyExcel使用:导出时忽略该字段
   */
  @ExcelIgnore
  private Integer id;@ExcelProperty("用户名")
  @ColumnWidth(20)
  private String username;/**
   * EasyExcel使用:日期的格式化
   */
  @ColumnWidth(20)
  @ExcelProperty("出生日期")
  @DateTimeFormat("yyyy-MM-dd")
  private Date birthday;/**
   * EasyExcel使用:自定义转换器
   */
  @ColumnWidth(10)
  @ExcelProperty(value = "性别", converter = GenderConverter.class)
  private Integer gender;
}

GenderConverter转换器的代码实现如下:


public class GenderConverter implements Converter<Integer> {private static final String MAN = "男";
  private static final String WOMAN = "女";
​
​
  @Override
  public Class<?> supportJavaTypeKey() {
    // 实体类中对象属性类型
    return Integer.class;
  }@Override
  public CellDataTypeEnum supportExcelTypeKey() {
    // Excel中对应的CellData属性类型
    return CellDataTypeEnum.STRING;
  }@Override
  public Integer convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty,
                                   GlobalConfiguration globalConfiguration) {
    // 从Cell中读取数据
    String gender = cellData.getStringValue();
    // 判断Excel中的值,将其转换为预期的数值
    if (MAN.equals(gender)) {
      return 0;
    } else if (WOMAN.equals(gender)) {
      return 1;
    }
    return null;
  }@Override
  public CellData<?> convertToExcelData(Integer integer, ExcelContentProperty excelContentProperty,
                                        GlobalConfiguration globalConfiguration) {
    // 判断实体类中获取的值,转换为Excel预期的值,并封装为CellData对象
    if (integer == null) {
      return new CellData<>("");
    } else if (integer == 0) {
      return new CellData<>(MAN);
    } else if (integer == 1) {
      return new CellData<>(WOMAN);
    }
    return new CellData<>("");
  }
}

字段注解 类注解
@ColumnWith(列宽)
@ColumnWidth(全局列宽)
@ExcelProperty(字段配置)
@HeadFontStyle(头样式)
@HeadRowHeight(标题高度)
@ContentFontStyle(内容字体样式)
@ContentRowHeight(内容高度)
@ExcelProperty
必要的一个注解,注解中有三个参数value,index,converter分别代表列明,列序号,数据转换方式 value和index只能二选一,通常不用设置converter
1.value 通过标题文本对应
2.index 通过文本行号对应
3.converter 转换器,通常入库和出库转换使用,如性别入库0和1,出库男和女

public class ImeiEncrypt {
    @ExcelProperty(value = "值")
    private String valueField;

    @ExcelProperty(value = 1,converter =IndustryIdConverter.class)
    private String indexField;

    @ExcelProperty(value = "值对应和转换器",converter =IndustryIdConverter.class)
    private String valueAndConverterField;
}

@ColumnWith 设置列宽度,只有一个参数value,value的单位是字符长度,最大可以设置255个字符,因为一个excel单元格最大可以写入的字符个数就是255个字符。

public class ImeiEncrypt {
    @ColumnWidth(value = 18)
    private String imei;
}

@ContentFontStyle 用于设置单元格内容字体格式的注解

参数:
fontName 字体名称
fontHeightInPoints 字体高度
italic 是否斜体
strikeout 是否设置删除水平线
color 字体颜色
typeOffset 偏移量
underline 下划线
bold 是否加粗
charset 编码格式

@ContentLoopMerge 用于设置合并单元格的注解

参数:
eachRow
columnExtend

@ContentRowHeight 用于设置行高

参数:
value 行高,-1代表自动行高

@ContentStyle 设置内容格式注解

参数:
dataFormat 日期格式
hidden 设置单元格使用此样式隐藏
locked 设置单元格使用此样式锁定
quotePrefix 在单元格前面增加`符号,数字或公式将以字符串形式展示
horizontalAlignment 设置是否水平居中
wrapped 设置文本是否应换行。将此标志设置为true通过在多行上显示使单元格中的所有内容可见
verticalAlignment 设置是否垂直居中
rotation 设置单元格中文本旋转角度。03版本的Excel旋转角度区间为-90°90°,07版本的Excel旋转角度区间为0°180°
indent 设置单元格中缩进文本的空格数
borderLeft 设置左边框的样式
borderRight 设置右边框样式
borderTop 设置上边框样式
borderBottom 设置下边框样式
leftBorderColor 设置左边框颜色
rightBorderColor 设置右边框颜色
topBorderColor 设置上边框颜色
bottomBorderColor 设置下边框颜色
fillPatternType 设置填充类型
fillBackgroundColor 设置背景色
fillForegroundColor 设置前景色
shrinkToFit 设置自动单元格自动大小

@HeadFontStyle 用于定制标题字体格式

参数 含义
fontName 设置字体名称
fontHeightInPoints 设置字体高度
italic 设置字体是否斜体
strikeout 是否设置删除线
color 设置字体颜色
typeOffset 设置偏移量
underline 设置下划线
charset 设置字体编码
bold 设置字体是否加粗

@HeadRowHeight 设置标题行行高

参数 含义
value 设置行高,-1代表自动行高

@HeadStyle 设置标题样式

参数 含义
dataFormat 日期格式
hidden 设置单元格使用此样式隐藏
locked 设置单元格使用此样式锁定
quotePrefix 在单元格前面增加`符号,数字或公式将以字符串形式展示
horizontalAlignment 设置是否水平居中
wrapped 设置文本是否应换行。将此标志设置为true通过在多行上显示使单元格中的所有内容可见
verticalAlignment 设置是否垂直居中
rotation 设置单元格中文本旋转角度。03版本的Excel旋转角度区间为-90°90°,07版本的Excel旋转角度区间为0°180°
indent 设置单元格中缩进文本的空格数
borderLeft 设置左边框的样式
borderRight 设置右边框样式
borderTop 设置上边框样式
borderBottom 设置下边框样式
leftBorderColor 设置左边框颜色
rightBorderColor 设置右边框颜色
topBorderColor 设置上边框颜色
bottomBorderColor 设置下边框颜色
fillPatternType 设置填充类型
fillBackgroundColor 设置背景色
fillForegroundColor 设置前景色
shrinkToFit 设置自动单元格自动大小

@ExcelIgnore 不将该字段转换成Excel

@ExcelIgnoreUnannotated 没有注解的字段都不转换

基础综合示例

//行高全部设为40
@HeadRowHeight(value = 40)
//标题全部居中
@HeadStyle(horizontalAlignment = CENTER)
public class SupervisionDailyExportProcessDTO {
	//"二、问题整改情况"是大标题,"序号"是大标题下面的子标题
    @ExcelProperty({"二、问题整改情况", "序号"})
    @ContentStyle(horizontalAlignment = CENTER)
    private Integer id;
    @ExcelProperty({"二、问题整改情况", "问题来源"})
    //单独设置这一列列宽为40
    @ColumnWidth(value = 40)
    @ContentStyle(wrapped = true, horizontalAlignment = CENTER)
    private String questionOrigin;
    @ExcelProperty({"二、问题整改情况", "督察点位"})
    @ColumnWidth(value = 40)
    @ContentStyle(wrapped = true, horizontalAlignment = CENTER)
    private String supervisionPoint;
    @ExcelProperty({"二、问题整改情况", "问题内容"})
    @ColumnWidth(value = 40)
    @ContentStyle(wrapped = true, horizontalAlignment = CENTER)
    private String questionContents;
    @ExcelProperty({"二、问题整改情况", "责任单位"})
    @ColumnWidth(value = 30)
    @ContentStyle(horizontalAlignment = CENTER)
    private String orgName;
    @ExcelProperty({"二、问题整改情况", "整改情况"})
    @ColumnWidth(value = 40)
    @ContentStyle(wrapped = true, horizontalAlignment = CENTER)
    private String processSituation;
}

补充颜色

NPOI Excel 单元格颜色对照表,在引用了 NPOI.dll 后可通过 ICellStyle 接口的 FillForegroundColor 属性实现 Excel 单元格的背景色设置,FillPattern 为单元格背景色的填充样式。
NPOI Excel 单元格背景颜色设置方法以及颜色对照表:

ICellStyle style = workbook.CreateCellStyle();
style.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
style.FillPattern = FillPattern.SolidForeground;
 
ICell cell = workbook.CreateSheet().CreateRow(0).CreateCell(0);
cell.CellStyle = style;

在这里插入图片描述
在这里插入图片描述

easyExcel使用

EasyExcelUtils 导出工具类

package com.sjasoft.framework.utils;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.lang.Nullable;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.print.DocFlavor;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * 导出工具类
 *
 * @author zlf
 */
public class EasyExcelUtils {

    /**
     * 导出公共方法
     *
     * @param datas    要导出的数据集
     * @param clazz    导出的实体
     * @param fileName 导出文件名称
     * @throws IOException
     */
    public static void export(List datas, @Nullable Class<?> clazz, String fileName, String sheetName) throws IOException {
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletResponse response = sra.getResponse();
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        // 设置文件名
        String exportFileName = URLEncoder.encode(fileName, "UTF-8");
        //String exportSheetName = URLEncoder.encode(sheetName, "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + exportFileName + ExcelTypeEnum.XLSX.getValue());
        // 创建一个写出的单元格样式对象
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 设置水平对齐方式
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 设置填充前景色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
        // 创建写出Excel的字体对象
        WriteFont headWriteFont = new WriteFont();
        //设置字体高度
        //headWriteFont.setFontHeightInPoints((short) 10);
        headWriteCellStyle.setWriteFont(headWriteFont);
        headWriteCellStyle.setWrapped(true);
        // 创建一个写出的单元格样式对象
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        //设置内容靠中对齐
        //contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

        // 边框设置
        /*contentWriteCellStyle.setBorderTop(BorderStyle.THIN);             // 设置单元格上边框为细线
        contentWriteCellStyle.setBorderBottom(BorderStyle.THICK);         // 设置单元格下边框为粗线
        contentWriteCellStyle.setBorderLeft(BorderStyle.MEDIUM);         // 设置单元格左边框为中线
        contentWriteCellStyle.setBorderRight(BorderStyle.MEDIUM_DASHED); // 设置单元格右边框为中虚线*/
        // 设置行样式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        // 设置自定义自适应列宽样式
        ExcelWidthStyleStrategy excelWidthStyleStrategy = new ExcelWidthStyleStrategy();
        // 如果不用模板的方式导出的话,是doWrite
        EasyExcel.write(response.getOutputStream(), clazz)
            .excelType(ExcelTypeEnum.XLSX)
            .autoCloseStream(true)
            .registerWriteHandler(horizontalCellStyleStrategy)
            .registerWriteHandler(excelWidthStyleStrategy)
            .sheet(sheetName)
            .doWrite(datas);
    }

    /**
     * 根据Excel模板,批量导入数据
     *
     * @param file  导入的Excel
     * @param clazz 解析的类型
     * @return 解析完成的数据
     */
    public static List<?> importExcel(MultipartFile file, Class<?> clazz) {
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("没有文件或者文件内容为空!");
        }
        List<?> dataList;
        BufferedInputStream ipt;
        try {
            InputStream is = file.getInputStream();
            // 用缓冲流对数据流进行包装
            ipt = new BufferedInputStream(is);
            // 数据解析监听器
            ExcelListener<?> listener = new ExcelListener<>();
            // 读取数据
            EasyExcel.read(ipt, clazz, listener).sheet().doRead();
            // 获取去读完成之后的数据
            dataList = listener.getList();
        } catch (Exception e) {
            throw new RuntimeException("数据导入失败!" + e);
        }
        return dataList;
    }
}

ExcelListener Excel数据解析监听器, 数据解析方法异步执行

package com.sjasoft.framework.utils;
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中数据的类型
 * @author zlf
 */
@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> getList() {
        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
     */
    @Override
    public void invoke(T data, AnalysisContext context) {
        dataList.add(data);
    }

    /**
     * 读取表头内容
     *
     * @param headMap 表头部数据
     * @param context 数据解析上下文
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        // 在此处可以进行表头的校验,headMap对应的就是表头的数据
        // 在此处有个很奇怪的地方,就是当用户导入的文件没有任何表头的时候,也就是表头这一行为空
        // 表头检验则不会进行这个函数,且数据导入成功,所以这个地方要确认清楚
        // 最后我是在拿到所有数据,包括表头,再取第一行为表头进行校验
        //System.out.println("表头:" + headMap);
    }

    /**
     * 流中的数据解析完成之后,就会调用此方法
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 数据解析完成,解锁
        retryLock = true;
    }

    /**
     * 解析过程如果发生异常,会调用此方法
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) {
        throw new RuntimeException("Excel数据异常,请检查或联系管理员!");
    }
}

ExcelWidthStyleStrategy 自适应宽度工具类

package com.sjasoft.framework.utils;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExcelWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {

    // 单元格的最大宽度
    private static final int MAX_COLUMN_WIDTH = 200;
    // 缓存(第一个Map的键是sheet的index, 第二个Map的键是列的index, 值是数据长度)
    private final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>(8);

    // 重写设置列宽的方法
    @Override
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder,
                                  List<WriteCellData<?>> cellDataList,
                                  Cell cell,
                                  Head head,
                                  Integer relativeRowIndex,
                                  Boolean isHead) {
        boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);
        // 当时表头或者单元格数据列表有数据时才进行处理
        if (needSetWidth) {
            Map<Integer, Integer> maxColumnWidthMap = CACHE.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>(16));
            // 获取数据长度
            Integer columnWidth = this.dataLength(cellDataList, cell, isHead);
            if (columnWidth >= 0) {
                if (columnWidth > MAX_COLUMN_WIDTH) {
                    columnWidth = MAX_COLUMN_WIDTH;
                }
                // 确保一个列的列宽以表头为主,如果表头已经设置了列宽,单元格将会跟随表头的列宽
                Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());

                if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
                    maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);
                    // 如果使用EasyExcel默认表头,那么使用columnWidth * 512
                    // 如果不使用EasyExcel默认表头,那么使用columnWidth * 256
                    // 如果是自己定义的字体大小,可以再去测试这个参数常量
                    writeSheetHolder
                        .getSheet()
                        .setColumnWidth(cell.getColumnIndex(), columnWidth * 512);
                }

            }
        }
    }

    /**
     * 获取当前单元格的数据长度
     */
    private Integer dataLength(List<WriteCellData<?>> cellDataList,
                               Cell cell,
                               Boolean isHead) {
        if (isHead) {
            return cell.getStringCellValue().getBytes().length;
        } else {
            WriteCellData cellData = cellDataList.get(0);
            CellDataTypeEnum type = cellData.getType();
            if (type == null) {
                return -1;
            } else {
                switch (type) {
                    case STRING:
                        return cellData.getStringValue().getBytes().length;
                    case BOOLEAN:
                        return cellData.getBooleanValue().toString().getBytes().length;
                    case NUMBER:
                        return cellData.getNumberValue().toString().getBytes().length;
                    default:
                        return -1;
                }
            }
        }
    }
}

调用

Controller

   @ApiOperation("导出日志明细")
    @PostMapping("/exportLogDetailInfo")
    public void exportLogDetailInfo(@RequestBody LogDetailParam detailParam) throws IOException{
        logService.exportLogDetailInfo(detailParam);
    }

service

  @SystemLog("导出日志明细")
    public void exportLogDetailInfo(LogDetailParam detailParam) throws IOException {
        List<LogDetailVo> logDetailList = tLogListDao.getLogDetailInfo(detailParam);
        if(CollectionUtil.isEmpty(logDetailList)){
            throw  new RuntimeException("未查询到数据,请调整条件后重新导出");
        }
        //导出文件名称
        String fileName = new String("导出日志明细" + DateUtil.format(new Date(),"yyyyMMddHHmmss"));
        EasyExcelUtils.export(logDetailList
            ,LogDetailVo.class,fileName,"导出日志明细");
    }

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

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

相关文章

【剑指 offer】数组中出现次数超过一半的数字

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;算法训练营&#x1f447; 数 组 中 出 现 次 数 超 过 一 半 的 数 字 核心考点: 数组使用&#xff0c;简单算法的设计 描述&#xff1a; 给一个长度为 n 的数组&#xff0c;数组中有一个数字出现的次数超…

php:php-fpm平滑重启为什么无效

一、问题 今天修改了fpm一些配置&#xff0c;需要上线重启fpm&#xff0c;但是发现一瞬间出现很多502的错误请求&#xff0c;查看日志发现以下错误 fpm&#xff1a;重启日志 nginx&#xff1a;错误日志 2023/04/23 15:19:00 [error] 9#0: *1893053661 recv() failed (104: Co…

【服务器数据恢复】重装系统导致分区无法访问的数据恢复案例

服务器数据恢复环境&#xff1a; 磁盘柜raid卡15块磁盘组建一组raid5磁盘阵列&#xff0c;划分2个lun&#xff1b; 上层操作系统划分若干分区&#xff0c;通过LVM扩容方式将其中一个分区加入到了root_lv中&#xff0c;其他分区格式化为XFS文件系统。 服务器故障&#xff1a; 为…

S/MIME电子邮件证书,符合FDA邮件安全要求

美国食品和药物管理局 &#xff08;FDA&#xff09;要求合作伙伴提交或接收电子监管信息时&#xff0c;必须使用数字证书保障通信安全。 01 为什么FDA使用数字证书保障通信安全&#xff1f; 为了维护数据完整性、准确性,有组织地管理文件,FDA为接受机构的电子监管提交设置了电子…

基于开源 web3引擎的三维系统的开发

目录 结合图像特征的平滑恢复技术 1.开发步骤 &#xff12; 应用案例开发 结束语 应用 &#xff37;&#xff45;&#xff42;&#xff13;&#xff24; 引擎开发的计算机仿真系统或虚拟现实系统均需在 &#xff37;&#xff45;&#xff42; 浏览 器 上 运 行 &#xff0…

MII、 RMII、 GMII、 RGMII 接口介绍

1、RGMII 接口概要 以太网的通信离不开物理层 PHY 芯片的支持&#xff0c;以太网 MAC 和 PHY 之间有一个接口&#xff0c;常用的接口有MII、 RMII、 GMII、 RGMII 等。 MII&#xff08;Medium Independent Interface&#xff0c; 媒体独立接口&#xff09;&#xff1a; MII 支持…

技术招聘演化论:怎样从纸上答题升级到实战编程?

创新赛道的出现 一些企业或许已经对招聘管理系统&#xff08;Applicant Tracking System&#xff0c;简称 ATS&#xff09;有一定了解&#xff0c;ATS 可以帮助企业管理招聘流程&#xff0c;其中包括发布招聘信息、接收简历、筛选候选人和安排面试等。在中国&#xff0c;一些知…

seata1.6.0 单机,集群搭建 基于nacos注册中心 mysql数据库

seata1.6.0 单机&#xff0c;集群搭建 基于nacos注册中心 mysql数据库 大纲 1 单机搭建2 集群搭建 由于项目中的dubbo版本为2.6.0 故客户端程序&#xff08;TM RM&#xff09;使用seata-all 1.4.2 &#xff0c;服务端&#xff08;TC&#xff09;使用seata-server-1.6.0.zip …

SQL Server基础 第六章 聚合函数和分组查询

前言 在数据查询的很多场合&#xff0c;除了需要显示数据表的原始数据&#xff0c;还需要对这些数据进行分析、汇总以及求极值等&#xff0c; 如获取公司员工的人数、工资总额、最高工资、最低工资和平均工资等。本章我们将通过学习SQL Server 聚合函数轻松获取上述数据。另外&…

基于Java+SpringBoot+vue学生学习平台详细设计实现

基于JavaSpringBootvue学生学习平台详细设计实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式 文章目…

软件架构的演进(超详细)

文章目录 前言1、什么是单体架构2、分布式架构3、SOA架构4、微服务架构总结 前言 之前对各种架构一直有所了解&#xff0c;但也只是了解&#xff0c;没有过多的研究为什么架构在慢慢演进&#xff0c;新架构代替老架构的理由是什么&#xff0c;而刚好最近学习了一下架构的演进过…

人工智能会取代人工翻译吗?

当今社会正处于语言和技术高速发展的阶段&#xff0c;因此语言和技术的碰撞是不可避免的——甚至有些人说这种碰撞已经发生了&#xff0c;我们只是在等待尘埃落定。数字化、物联网、人工智能和机器学习&#xff0c;以及更进一步——智能手机、语音识别&#xff0c;以及互联网和…

27《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》中文分享

​《Protein Actions Principles and Modeling》-《蛋白质作用原理和建模》 本人能力有限&#xff0c;如果错误欢迎批评指正。 第六章&#xff1a;The principles of protein folding kinetics &#xff08;蛋白质折叠动力学的原理&#xff09; 整个二级结构通常作为一个单…

JS规范及常见问题

数字和字符串不能混合使用。 做加减法可能出错 "1"1 "11"做判断可能出错 "2"<"11"false几种for循环的使用: for(var i0;i<list.length;i): es5,需要拿到下标时、遍历非标准数组如FileList时for(var i in obj): es5,遍历对象时…

SpringBoot接口传递自定义参数,参数解析器

Hi I’m Shendi SpringBoot接口传递自定义参数&#xff0c;参数解析器 简介 我的需求&#xff1a;编写了一个日志微服务&#xff0c;使用方式是 创建日志对象 - 日志流程 - 完成日志对象&#xff0c;这样的方式使用时就需要在每个接口都去创建和完成一下&#xff0c;多出了一点…

查看 AndroidManifest.xml 文件内容,解决全是二进制代码问题

想查看打包后apk的AndroidManifest.xml文件内容&#xff0c;之前都是将后缀apk改为zip&#xff0c;直接解压查看&#xff0c;有时会遇到都是二进制代码&#xff0c;给出集中查看明文的方法&#xff1a; 方法一、通过android studio自带的Analyze apk 功能 通过 studio Build …

9.7 字符串的指针和指向字符串的指针变量

9.7 字符串的指针和指向字符串的指针变量 一.字符串表示形式二.字符串指针做函数参数1.数组名做函数参数2.数组指针做函数参数 三.字符指针变量与字符数组&#xff08;1&#xff09;字符数组是由若干个元素组成&#xff0c;每个元素中存放一个字符。&#xff08;2&#xff09;赋…

优化配置Little Snitch for Mac的规则和设置

Little Snitch for Mac是一款专业的macOS防火墙软件&#xff0c;它可以帮助你控制应用程序是否访问网络或者磁盘&#xff0c;并对系统不可信的进程和信息进行监控。如果你想保护你的Mac的网络安全&#xff0c;那么你需要了解如何配置和优化Little Snitch for Mac的规则和设置。…

证件照换底色,快试试这3种方法,方便还快捷

由于我们不论是在生活还是学习中&#xff0c;有时候总会要上传一些证件照&#xff0c;而当你手上有证件照准备上传时&#xff0c;发现底色不对&#xff0c;是不是很抓狂&#xff0c;电子证件照片换底色怎么弄&#xff1f;很多小伙伴还在因为证件照底色不对而重新拍&#xff1f;…

PureComponent和React.memo()区别

文章目录 前言一、区别二、用法 前言 本篇文章主要讲解了&#xff0c;PureComponent和React.memo()区别及用法。 一、区别 PureComponent 和 React.memo() 都是 React 中优化组件性能的方式。 PureComponent 是一个类组件&#xff0c;而 React.memo() 是一个高阶函数。 Reac…