EasyExcel导出带自定义下拉框数据的Excel模板

文章目录

  • 前言📝
  • 一、导入依赖
  • 二、创建导出工具
    • 1.创建模板实体类
    • 2.创建自定义注解
    • 3.添加动态选择接口
    • 4.EasyExcelUtil工具类
  • 三、导出、导入Excel接口
    • 1.导出接口
    • 2.导入接口
    • 3.导出结果
  • 总结

前言📝

在项目中导入excel时需要通过下拉框选择值传入,所以需要在导出模板的时候,把下拉框数据一起导出到excel中


在这里插入图片描述

一、导入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>${easyexcel.version}</version>
</dependency>
<easyexcel.version>2.2.10</easyexcel.version>

二、创建导出工具

1.创建模板实体类

创建Excel导出模板表头对应的实体类

代码如下(示例):

/**
 * 表头类
 *
 * @author wangjian
 * @date 2024-04-22 10:32
 */
@Data
@ColumnWidth(25)
@HeadRowHeight(15)
@ContentRowHeight(15)
public class TravelGroupExportExcel implements Serializable {

    /**
     * 游客姓名
     */
    @ExcelProperty(index = 0, value = "*游客姓名")
    private String userName;

    /**
     * 国家地区
     */
    @ExcelProperty(index = 1, value = "*国家地区")
    @ExcelSelected(sourceClass = CountrySelected.class)
    private String countryAreaTypeStr;

    /**
     * 证件号
     */
    @ExcelProperty(index = 2, value = "*证件号")
    private String idCard;

    /**
     * 联系电话
     */
    @ExcelProperty(index = 3, value = "*联系电话")
    private String phone;

    /**
     * 优待身份
     */
    @ExcelProperty(index = 4, value = "优待身份(选填)")
    @ExcelSelected(sourceClass = IdentitySelected.class)
    private String specialCode;

    /**
     * 模板版本
     */
    @ExcelProperty(index = 5, value = "模板版本")
    private String version;
}

2.创建自定义注解

创建自定义注解,标注导出的列为下拉框类型,并为下拉框设置内容

代码如下(示例):

/**
 * 标注导出的列为下拉框类型,并为下拉框设置内容
 *
 * @author MaoDeShu
 * @date 2024-04-22 10:32
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelSelected {
    /**
     * 固定下拉内容
     */
    String[] source() default {};

    /**
     * 动态下拉内容
     */
    Class<? extends ExcelDynamicSelect>[] sourceClass() default {};

    /**
     * 设置下拉框的起始行,默认为第二行
     */
    int firstRow() default 1;

    /**
     * 设置下拉框的结束行,默认为最后一行
     */
    int lastRow() default 0x10000;
}

Excel选择解析类

/**
 * 导入Excel选择解析类
 *
 * @author MaoDeShu
 * @date 2024-04-22 10:32
 */
@Data
@Slf4j
public class ExcelSelectedResolve {
    /**
     * 下拉内容
     */
    private String[] source;

    /**
     * 设置下拉框的起始行,默认为第二行
     */
    private int firstRow;

    /**
     * 设置下拉框的结束行,默认为最后一行
     */
    private int lastRow;

    public String[] resolveSelectedSource(ExcelSelected excelSelected) {
        if (excelSelected == null) {
            return null;
        }

        // 获取固定下拉框的内容
        String[] source = excelSelected.source();
        if (source.length > 0) {
            return source;
        }

        // 获取动态下拉框的内容
        Class<? extends ExcelDynamicSelect>[] classes = excelSelected.sourceClass();
        if (classes.length > 0) {
            try {
                ExcelDynamicSelect excelDynamicSelect = classes[0].newInstance();
                String[] dynamicSelectSource = excelDynamicSelect.getSource();
                if (dynamicSelectSource != null && dynamicSelectSource.length > 0) {
                    return dynamicSelectSource;
                }
            } catch (InstantiationException | IllegalAccessException e) {
                log.error("解析动态下拉框数据异常", e);
            }
        }
        return null;
    }
}

3.添加动态选择接口

创建动态选择接口及实现类,这里可以根据自己的业务逻辑去实现

ExcelDynamicSelect.java

/**
 * 获取下拉框数据接口
 *
 * @author MaoDeShu
 * @date 2024-04-22 10:32
 */
public interface ExcelDynamicSelect {

    /**
     * 获取动态生成的下拉框可选数据
     *
     * @return
     */
    String[] getSource();
}

实现类

CountrySelected.java

/**
 * 获取下拉框数据接口-国家地区
 *
 * @author MaoDeShu
 * @date 2024-04-22 10:32
 */
@Service
public class CountrySelected implements ExcelDynamicSelect{
    @Override
    public String[] getSource() {
    	// 这里根据自己的业务处理,这里示例写死
        return new ArrayList<String>(){{add("中国");add("中国台湾");add("中国香港");add("中国澳门");}}.toArray(new String[]{});
    }
}

IdentitySelected .java

/**
 * 获取下拉框数据接口-身份选择
 *
 * @author MaoDeShu
 * @date 2024-04-22 10:32
 */
@Service
public class IdentitySelected implements ExcelDynamicSelect{
    @Override
    public String[] getSource() {
    	// 这里根据自己的业务处理,这里示例写死
        return new ArrayList<String>(){{add("单选");add("多选");add("判断");add("问答");}}.toArray(new String[]{});
    }
}

4.EasyExcelUtil工具类

创建EasyExcelUtil工具类,实现Excel模板导出、导入

/**
 * excel工具类
 *
 * @author MaoDeShu
 * @date 2024-04-22 10:32
 */
@Slf4j
public class EasyExcelUtil {

    /**
     * 创建即将导出的sheet页(sheet页中含有带下拉框的列)
     *
     * @param head      导出的表头信息和配置
     * @param sheetNo   sheet索引
     * @param sheetName sheet名称
     * @param <T>       泛型
     * @return sheet页
     */
    public static <T> WriteSheet writeSelectedSheet(Class<T> head, Integer sheetNo, String sheetName) {
        Map<Integer, ExcelSelectedResolve> selectedMap = resolveSelectedAnnotation(head);

        return EasyExcel.writerSheet(sheetNo, sheetName)
                .head(head)
                .registerWriteHandler(new SelectedSheetWriteHandler(selectedMap))
                .build();
    }

    /**
     * 解析表头类中的下拉注解
     *
     * @param head 表头类
     * @param <T>  泛型
     * @return Map<下拉框列索引, 下拉框内容> map
     */
    private static <T> Map<Integer, ExcelSelectedResolve> resolveSelectedAnnotation(Class<T> head) {
        Map<Integer, ExcelSelectedResolve> selectedMap = new HashMap<>();

        // getDeclaredFields(): 返回全部声明的属性;getFields(): 返回public类型的属性
        Field[] fields = head.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            // 解析注解信息
            ExcelSelected selected = field.getAnnotation(ExcelSelected.class);
            ExcelProperty property = field.getAnnotation(ExcelProperty.class);
            if (selected != null) {
                ExcelSelectedResolve excelSelectedResolve = new ExcelSelectedResolve();
                String[] source = excelSelectedResolve.resolveSelectedSource(selected);
                if (source != null && source.length > 0) {
                    excelSelectedResolve.setSource(source);
                    excelSelectedResolve.setFirstRow(selected.firstRow());
                    excelSelectedResolve.setLastRow(selected.lastRow());
                    if (property != null && property.index() >= 0) {
                        selectedMap.put(property.index(), excelSelectedResolve);
                    } else {
                        selectedMap.put(i, excelSelectedResolve);
                    }
                }
            }
        }
        return selectedMap;
    }

    /**
     * 动态设置注解中的字段值
     *
     * @param clazz    注解所在的实体类
     * @param attrName 要修改的注解属性名
     * @param valueMap 要设置的属性值
     * @return
     */
    public static Class dynamicReviseAnnotationParam(Class clazz, String attrName
            , Map<String, String> valueMap) {

        Field[] declaredFields = clazz.getDeclaredFields();
        try {
            if (valueMap != null) {
                for (Field f : declaredFields) {
                    if (f.isAnnotationPresent(ExcelProperty.class)) {
                        ExcelProperty annotation = f.getAnnotation(ExcelProperty.class);
                        InvocationHandler handler = Proxy.getInvocationHandler(annotation);
                        Field field = handler.getClass().getDeclaredField("memberValues");
                        field.setAccessible(true);
                        // 注解信息
                        Map memberValues = (Map) field.get(handler);
                        String[] arr = (String[]) memberValues.get(attrName);
                        String oldValue = arr[0];
                        String newValue = valueMap.get(oldValue);
                        if (StrUtil.isNotBlank(newValue)) {
                            List newArr = new ArrayList();
                            newArr.add(newValue);
                            memberValues.put(attrName, newArr.toArray(new String[arr.length]));
                        }
                    }
                }
            }
        } catch (NoSuchFieldException | IllegalAccessException e) {
            log.error("动态添加注解数据失败!");
            e.printStackTrace();
            throw new BizException("动态添加注解数据失败!");
        }
        return clazz;
    }

    /**
     * 导出带下拉框的模板excel
     *
     * @param response
     * @param filename
     */
    public static void exportExcelTemplateBySelected(HttpServletRequest request, HttpServletResponse response
            , String filename, Class clazz, Map<String, String> replaceMap) {
        try {
            if (StrUtil.isBlank(filename)) {
                filename = "模板下载";
            }
            String agent = request.getHeader("USER-AGENT").toLowerCase();
            if (agent.contains("firefox")) {
                filename = new String(filename.getBytes(), "ISO8859-1");
            } else {
                filename = URLEncoder.encode(filename, "UTF-8");
            }
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", filename + ".xlsx"));
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Pragma", "no-cache");
            response.setDateHeader("Expires", -1);
            response.setCharacterEncoding("UTF-8");

            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();

            Class dynamicClazz = dynamicReviseAnnotationParam(clazz, "value", replaceMap);

            WriteSheet writeSheet = EasyExcelUtil.writeSelectedSheet(dynamicClazz, 0, "sheet");

            excelWriter.write(new ArrayList<String>(), writeSheet);
            excelWriter.finish();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("导出模板失败!");
            throw new BizException("导出模板失败!");
        }
    }

    /**
     * 模型解析监听器 -- 每解析一行会回调invoke()方法,整个excel解析结束会执行doAfterAllAnalysed()方法
     *
     * @param <E>
     */
    public static class ModelExcelListener<E> extends AnalysisEventListener<E> {

        private List<E> dataList = new ArrayList<E>();
        private Map<Integer, String> dataMap = new HashMap<Integer, String>(16);

        @Override
        public void invoke(E object, AnalysisContext context) {
            dataList.add(object);
        }

        @Override
        public void doAfterAllAnalysed(AnalysisContext context) {
        }

        @Override
        public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
            log.info("表头数据 excelHead= {}", headMap);
            dataMap.putAll(headMap);
        }

        public List<E> getDataList() {
            return dataList;
        }

        @SuppressWarnings("unused")
        public void setDataList(List<E> dataList) {
            this.dataList = dataList;
        }

        public Map<Integer, String> getDataMap() {
            return dataMap;
        }

        @SuppressWarnings("unused")
        public void setDataMap(Map<Integer, String> dataMap) {
            this.dataMap = dataMap;
        }
    }

    /**
     * 使用 模型 来读取Excel
     *
     * @param inputStream Excel的输入流
     * @param clazz       模型的类
     * @return 返回 模型 的列表
     */
    public static <E> List<E> readExcelWithModel(InputStream inputStream, Class<?> clazz) {
        // 解析每行结果在listener中处理
        ModelExcelListener<E> listener = new ModelExcelListener<>();
        try {
            EasyExcel.read(inputStream, clazz, listener).sheet().doRead();
        } catch (Exception e) {
            //throw new BusinessException("导入数据有问题,请修改后再上传");
            throw new BizException("导入数据有问题,请修改后再上传!");
        }
        return listener.getDataList();
    }

    /**
     * 使用 模型 来读取Excel
     *
     * @param inputStream Excel的输入流
     * @param clazz       模型的类
     * @return 返回 模型 的列表
     */
    public static <E> ModelExcelListener<E> readListener(InputStream inputStream, Class<?> clazz) {
        // 解析每行结果在listener中处理
        ModelExcelListener<E> listener = new ModelExcelListener<>();
        try {
            EasyExcel.read(inputStream, clazz, listener).sheet().doRead();
        } catch (Exception e) {
            //throw new BusinessException("导入数据有问题,请修改后再上传");
            throw new BizException("导入数据有问题,请修改后再上传!");
        }
        return listener;
    }

}

SelectedSheetWriteHandler.java

/**
 * 对cell进行下拉框设置操作
 *
 * @author MaoDeShu
 * @date 2024-04-22 10:32
 */
@AllArgsConstructor
public class SelectedSheetWriteHandler implements SheetWriteHandler {

    private final Map<Integer, ExcelSelectedResolve> selectedMap;

    /**
     * Called before create the sheet
     */
    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    /**
     * Called after the sheet is created
     */
    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        // 这里可以对cell进行任何操作globalCountryArea
        Sheet sheet = writeSheetHolder.getSheet();
        DataValidationHelper helper = sheet.getDataValidationHelper();
        selectedMap.forEach((k, v) -> {
            // 设置下拉列表的行: 首行,末行,首列,末列
            CellRangeAddressList rangeList = new CellRangeAddressList(v.getFirstRow(), v.getLastRow(), k, k);
            // 设置下拉列表的值
            DataValidationConstraint constraint = helper.createExplicitListConstraint(v.getSource());
            // 设置约束
            DataValidation validation = helper.createValidation(constraint, rangeList);
            // 阻止输入非下拉选项的值
            validation.setErrorStyle(DataValidation.ErrorStyle.STOP);

            // 处理Excel兼容性问题
            if (validation instanceof XSSFDataValidation) {
                validation.setShowErrorBox(true);
                validation.setSuppressDropDownArrow(true);
            } else {
                validation.setSuppressDropDownArrow(false);
            }
            validation.createErrorBox("提示", "请输入下拉选项中的内容");
            sheet.addValidationData(validation);
        });
        // 冻结表头
        sheet.createFreezePane(0,1);
    }
}

三、导出、导入Excel接口

1.导出接口

@Slf4j
@RestController
@RequestMapping("/api/test")
@RequiredArgsConstructor
public class TestController {

    @PostMapping("/exportExcel")
    public void exportExcel(@RequestParam(value = "filename", required = false) @ApiParam(value = "文件名称") String filename,
                      HttpServletRequest request, HttpServletResponse response) {

        HashMap<String, String> replaceMap = new HashMap<>();
        replaceMap.put("模板版本", "V1.0");
		// 这里replaceMap是需要替换表头的值,将"模板版本"替换为"V1.0"
        EasyExcelUtil.exportExcelTemplateBySelected(request, response, filename, TravelGroupExportExcel.class, replaceMap);
    }
}

2.导入接口

@Slf4j
@RestController
@RequestMapping("/api/test")
@RequiredArgsConstructor
public class TestController {

    @PostMapping("/importExcel")
    public String importExcel(HttpServletRequest request, HttpServletResponse response) {

        try {
            MultipartHttpServletRequest multipart = (MultipartHttpServletRequest) request;
            MultiValueMap<String, MultipartFile> map = multipart.getMultiFileMap();
            MultipartFile file = null;
            for (Map.Entry<String, List<MultipartFile>> entry : map.entrySet()) {
                List<MultipartFile> files = entry.getValue();
                if (files == null || files.size() == 0) {
                    return "文件为空!";
                }
                file = files.get(0);
            }
            if (file != null) {
                EasyExcelUtil.ModelExcelListener listener = EasyExcelUtil.readListener(
                        file.getInputStream(), TravelGroupExcelModel.class);
				// 获取到excel信息
                List<TravelGroupExcelModel> excelModelList = listener.getDataList();

                // 获取excel表头
                Map<Integer, String> headMap = listener.getDataMap();
                if (headMap.isEmpty() || headMap.size() != 6) {
                    return "导入模板格式错误,请下载正确的模板修改后重新上传!";
                }

                if (excelProperties.getIsCheckVersion()) {
                    String version = headMap.get(headMap.size() - 1);
                    if (!excelProperties.getVersion().equalsIgnoreCase(version)) {
                        return "导入模板版本错误,请下载更新正确的模板后重新上传!";
                    }
                }

                if (CollUtil.isEmpty(excelModelList)) {
                    return "获取导入数据为空,请检查模板或数据格式是否正确!";
                }
              	// 后续处理 excelModelList 
            }
        } catch (Exception e) {
            e.printStackTrace();
            return e.getMessage();
        }
        return null;
    }
}

3.导出结果


总结

以上就是今天要讲的内容,本文仅仅简单介绍了Java使用EasyExcel导出带自定义下拉框数据的Excel模板,侧重于实践教学,希望能给大家一个参考。

⭕关注博主,不迷路 ⭕

创作不易,关注💖、点赞👍、收藏🎉就是对作者最大的鼓励👏,欢迎在下方评论留言🧐

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决在Outlook中预定Teams会议不显示入会链接的问题

今天遇到一个很蛋疼的teams问题&#xff0c;花了点时间才解决。本来以为是很简单的问题&#xff0c;随便网上冲浪一下就能找到答案的&#xff0c;结果根本就没有好的解决方案&#xff0c;所以我分享出来希望后来的老哥少走点弯路。 问题描述 简单来说&#xff0c;就是在Outlo…

Pytorch入门—Tensors张量的学习

Tensors张量的学习 张量是一种特殊的数据结构&#xff0c;与数组和矩阵非常相似。在PyTorch中&#xff0c;我们使用张量来编码模型的输入和输出&#xff0c;以及模型的参数。 张量类似于NumPy的ndarrays&#xff0c;只是张量可以在GPU或其他硬件加速器上运行。事实上&#xf…

IntelliJ IDEA 配置JDK

IntelliJ IDEA-之配置JDK 我们的开发神器IDEA安装好了之后&#xff0c;在实际开发中&#xff0c;我们如何去配置好JDK的版本呢&#xff1f; 注意&#xff1a;需要保证JDK在已经成功安装的情况下&#xff0c;再进行IDEA的配置 现在就行动&#xff0c;让IntelliJ IDEA成为你征…

Windows系统使用powershell批量移动特定起始位置的“快捷方式”

移动特定起始位置的“快捷方式” 快捷方式都对应一个的目标和“起始位置”&#xff0c;现在想要把特定起始位置的快捷方式移动到一个文件夹中。 新建文本文档&#xff0c;输入如下内容&#xff1a; # 设置变量 $oldPath "D:\111\111_1" $newPath "D:\111\1…

C语言—操作符详解(操作符、进制转换、原码反码补码、结构体)

1.操作符分类 算术操作符&#xff1a; 、- 、 * 、 / 、%移位操作符&#xff1a;<< >> //移动的是二进制位位操作符&#xff1a;& | ^ //使用二进制位进行计算赋值操作符&#…

前端js面试题--从字符串中删除删除注释代码

问题&#xff1a;从字符串中删除删除注释代码 描述&#xff1a; solution(weex,rex # and react\nflutter\nnative ssss !hybrid app, [#, !]) 写一个solution函数清除后面参数数组里面的字符串 打印效果 代码1 思路&#xff1a; 将字符全凡是有去掉标志符号的全部添加\n…

Ubuntu20.4中复现Graspness

Ubuntu20.4中复现Graspness 文章目录 Ubuntu20.4中复现Graspness1.安装cuda和cudnn2.安装pytorch3.安装MinkowskiEngine4.编译graspnetAPI5. RuntimeError: "floor" "_vml_cpu" not implemented for IntRefernece &#x1f680;非常重要的环境配置&#x1…

pyqt 分组框控件QGroupBox

pyqt 分组框控件QGroupBox 分组框控件QGroupBox介绍效果代码 分组框控件QGroupBox介绍 QGroupBox提供了一个框架&#xff0c;用于将其他控件&#xff08;如按钮、滑块、标签等&#xff09;组合在一起。 QGroupBox 通常包含一个标题栏和一个内容区域。标题栏显示文本标签&#…

经典回溯算法之N皇后问题

问题描述&#xff1a; 有一个N*N的棋盘&#xff0c;需要将N个皇后放在棋盘上&#xff0c;保证棋盘的每一行每一列每一左斜列每一右斜列都最多只能有一个皇后。 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如…

关于模型参数融合的思考

模型参数融合通常指的是在训练过程中或训练完成后将不同模型的参数以某种方式结合起来&#xff0c;以期望得到更好的性能。这种融合可以在不同的层面上进行&#xff0c;例如在神经网络的不同层之间&#xff0c;或者是在完全不同的模型之间。模型参数融合的目的是结合不同模型的…

探索智慧生活:百度Comate引领人工智能助手新潮流

文章目录 百度Comate介绍1. 什么是百度Comate&#xff1f;主要特点 2. Comate的核心功能智能问答功能语音识别功能语音助手功能个性化服务 使用教程(以vscode为例)1. 下载和安装Comate2. 插件配置方式1&#xff1a;无License用户方式2&#xff1a;购买License用户 3. 常用操作快…

软件设计师

软件设计师 第一章 计算机系统基础原/反/补/移码例题&#xff1a; 浮点数例题 海明校验码例题 CISC和RISC*流水线例题 存储系统cache*主存编址计算例题&#xff1a; 可靠性例题 性能指标例题 第二章 操作系统进程例题 PV操作 信号量例题 前驱图例题 死锁计算例题 段页式存储例题…

阵痛中的乳业产业,何时才能成为下一个啤酒产业?

说起饮品&#xff0c;近年来中国啤酒业中各大品牌齐齐聚焦高端化的趋势绝对值得一提。然而&#xff0c;与之相反&#xff0c;国内乳业却是仍未进入高端化阶段&#xff0c;甚至陷入了周期底部中。 图源&#xff1a;中国圣牧财报 增收降利 牧企承受巨大的供需缺口压力 从产业链…

设计模式(2)创造型设计模式

创建型模式 创建型模式1.工厂模式1.1 抽象工厂模式&#xff08;Abstract factory&#xff09;1.2 工厂方法模式&#xff08;Factory Method&#xff09;1.3 简单工厂模式&#xff08;Simple Factory&#xff09; 2. 建造者模式&#xff08;Builder&#xff09;3. 原型模式&…

P8799 [蓝桥杯 2022 国 B] 齿轮

P8799 [蓝桥杯 2022 国 B] 齿轮 分析 最右边的齿轮的转速是最左边齿轮的q倍 最右边的齿轮的半径是最左边齿轮的q倍 题意即为&#xff1a;查询数组中是否存在两个数&#xff0c;其中一个是另一个的q倍 题目范围&#xff1a;查询次数q:2*10^5&#xff0c;数组范围2*10^5&…

2024付费进群系统,源码及搭建变现视频课程(教程+源码)

前三节讲解搭建支付对接&#xff0c;后两节讲解一些引流变现的方法&#xff0c;还有一种变现就是帮人搭建这样的平台&#xff0c;因为全网都没有一套完整的视频教怎么搭建的&#xff0c;有也只是文字教程&#xff0c;一般新人根本看不懂&#xff0c;我视频实操演示&#xff0c;…

学习经验分享【36】论文投稿写作(非理工科文章)

业务进一步扩展&#xff0c;可辅导非理工科偏文科性质的论文辅导&#xff0c;有需要评职称但没有时间精力研究的或者其他相关需求的朋友可咨询了解。 人工智能技术在各领域的发展和思考&#xff0c;类似这种主题的文章。

压缩和归档库-LZ4介绍

1.简介 LZ4是一种快速的压缩算法&#xff0c;提供压缩和解压缩的速度&#xff0c;而牺牲了压缩率。它被设计用于快速的数据压缩和解压缩&#xff0c;特别是用于数据存储和传输。LZ4通常用于需要高速数据处理的场景&#xff0c;如数据库、日志文件处理和实时数据传输。 LZ4的特…

进一步分析并彻底解决 Flink container exit 143 问题

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

腾讯游戏海外扩张,增持芬兰游戏开发商股份持股比例增至14.8%

易采游戏网5月8日消息&#xff0c;近日腾讯再次出手&#xff0c;大幅增持了芬兰知名游戏开发商Remedy Entertainment的股份&#xff0c;持股比例猛增至14.8%。这一举动引起了业界和投资者的广泛关注。 据了解&#xff0c;腾讯此次增持是在2024年4月24日完成的。根据芬兰法律规…