poi如何实现自定义导出Excel-纵向横向合并单元格,自定义填充数据列
前情提要
首先需要明确自己需要导出的excel构成是如何的,比如我需要导出一个自定义表头的excel表格,第一行A到X是标题需要横向合并单元格,第二行和第三行是表头,A到J需要第二行和第三行纵向合并单元格,K到N的第二行需要横向合并单元格,O到S需要横向合并单元格,T到U需要横向合并单元格,最后V到X需要第二行和第三行纵向合并单元格,再赋值给这些列,合并如图

确保项目中已经包含 Apache POI 的依赖
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version> <!-- 请根据需要选择版本 -->
</dependency>
创建表头
写一个创建表头的方法,首先我们需要创建一个工作簿,再创建一个工作表来存放数据
private void exportPersonnelData(HttpServletResponse response, List<SysUserImportVo> userList) throws IOException {// 创建工作簿Workbook workbook = new XSSFWorkbook();// 创建工作表Sheet sheet = workbook.createSheet("科创");// 创建表头createHeaderRow(workbook, sheet);
}
首先我们按照自己的需要进行表头的创建,我需要先创建一个标题
private static void createHeaderRow(Workbook workbook, Sheet sheet) {// 表头第一行Row row1 = sheet.createRow(0);//在第一行创建row1.setHeightInPoints(25);//设置高度Cell titleCell = row1.createCell(0);//标明是第一行titleCell.setCellValue("我是标题");//写入标题CellStyle titleStyle = workbook.createCellStyle();//创建了一个新的单元格样式对象 Font font = workbook.createFont();//创建了一个新的字体对象 定义单元格中文字的样式font.setFontHeightInPoints((short) 16);//设置字体的高度为16磅font.setBold(true);//将字体设置为粗体titleStyle.setFont(font);//将之前创建的字体应用到单元格样式 // 设置文本居中titleStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中titleCell.setCellStyle(titleStyle);sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 23));//合并第一行中的从第0列到第23列的所有单元格,以便在Excel中形成一个大的标题区域//new CellRangeAddress(0, 0, 0, 23) 表示合并的单元格区域://第一个和第二个参数 0 指定了开始和结束的行号(这里都是第0行)。//第三个和第四个参数 0 和 23 指定了开始和结束的列号(这里是从第0列到第23列)。//这样就会将第一行的第0列到第23列的单元格合并为一个单元格。
}
接下来要进行第二行和第三行的分别纵向横向合并单元格
private static void createHeaderRow(Workbook workbook, Sheet sheet) {//第二行Row headerRow2 = sheet.createRow(1);//第三行Row row2 = sheet.createRow(2);// 设置“苹果”Cell currentPositionCell = headerRow2.createCell(10);currentPositionCell.setCellValue("苹果");sheet.addMergedRegion(new CellRangeAddress(1, 1, 10, 13)); // 合并“苹果”区域// 设置“香蕉”Cell educationCell = headerRow2.createCell(14);educationCell.setCellValue("香蕉");sheet.addMergedRegion(new CellRangeAddress(1, 1, 14, 18)); // 合并“香蕉”区域// 设置“橙子”Cell zcell = headerRow2.createCell(19);zcell.setCellValue("橙子");sheet.addMergedRegion(new CellRangeAddress(1, 1, 19, 20)); // 合并“橙子”区域// 手动赋值headerRow2.createCell(0).setCellValue("序号");headerRow2.createCell(1).setCellValue("葡萄");headerRow2.createCell(2).setCellValue("草莓");headerRow2.createCell(3).setCellValue("蓝莓");headerRow2.createCell(4).setCellValue("菠萝");headerRow2.createCell(5).setCellValue("芒果");headerRow2.createCell(6).setCellValue("桃子");headerRow2.createCell(7).setCellValue("樱桃");headerRow2.createCell(8).setCellValue("橘子");headerRow2.createCell(9).setCellValue("柚子");row2.createCell(10).setCellValue("红富士");row2.createCell(11).setCellValue("青苹");row2.createCell(12).setCellValue("蜜脆");row2.createCell(13).setCellValue("金帅");row2.createCell(14).setCellValue("卡文迪什");row2.createCell(15).setCellValue("红香蕉");row2.createCell(16).setCellValue("小香蕉");row2.createCell(17).setCellValue("冰淇淋香蕉");row2.createCell(18).setCellValue("香甜香蕉");row2.createCell(19).setCellValue("甜橙");row2.createCell(20).setCellValue("血橙");headerRow2.createCell(21).setCellValue("杏子");headerRow2.createCell(22).setCellValue("李子");headerRow2.createCell(23).setCellValue("酪梨");// 合并第二行和第三行的单元格sheet.addMergedRegion(new CellRangeAddress(1, 2, 0, 0)); // 序号sheet.addMergedRegion(new CellRangeAddress(1, 2, 1, 1)); // 葡萄sheet.addMergedRegion(new CellRangeAddress(1, 2, 2, 2)); // 草莓sheet.addMergedRegion(new CellRangeAddress(1, 2, 3, 3)); // 蓝莓sheet.addMergedRegion(new CellRangeAddress(1, 2, 4, 4)); // 菠萝sheet.addMergedRegion(new CellRangeAddress(1, 2, 5, 5)); // 芒果sheet.addMergedRegion(new CellRangeAddress(1, 2, 6, 6)); // 桃子sheet.addMergedRegion(new CellRangeAddress(1, 2, 7, 7)); // 樱桃sheet.addMergedRegion(new CellRangeAddress(1, 2, 8, 8)); // 橘子sheet.addMergedRegion(new CellRangeAddress(1, 2, 9, 9)); // 柚子sheet.addMergedRegion(new CellRangeAddress(1, 2, 21, 21)); // 杏子sheet.addMergedRegion(new CellRangeAddress(1, 2, 22, 22)); // 李子sheet.addMergedRegion(new CellRangeAddress(1, 2, 23, 23)); // 酪梨}
合并后内容显示如图 但是如何设置单元格格式呢

接下来写一下单元格格式 这样就和上面的表头是一模一样显示了
private static void createHeaderRow(Workbook workbook, Sheet sheet) {// 创建单元格样式CellStyle cellStyle = workbook.createCellStyle();Font font2 = workbook.createFont();font2.setFontHeightInPoints((short) 12); // 设置字体大小font2.setBold(true); // 设置为粗体cellStyle.setFont(font2);cellStyle.setAlignment(HorizontalAlignment.CENTER); // 水平居中cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 设置边框cellStyle.setBorderTop(BorderStyle.THIN);cellStyle.setBorderBottom(BorderStyle.THIN);cellStyle.setBorderLeft(BorderStyle.THIN);cellStyle.setBorderRight(BorderStyle.THIN);//第二行Row headerRow2 = sheet.createRow(1);//第三行Row row2 = sheet.createRow(2);// 设置“苹果”Cell currentPositionCell = headerRow2.createCell(10);currentPositionCell.setCellValue("苹果");sheet.addMergedRegion(new CellRangeAddress(1, 1, 10, 13)); // 合并“苹果”区域currentPositionCell.setCellStyle(cellStyle); // 应用样式// 设置“香蕉”Cell educationCell = headerRow2.createCell(14);educationCell.setCellValue("香蕉");sheet.addMergedRegion(new CellRangeAddress(1, 1, 14, 18)); // 合并“香蕉”区域educationCell.setCellStyle(cellStyle); // 应用样式// 设置“橙子”Cell zcell = headerRow2.createCell(19);zcell.setCellValue("橙子");sheet.addMergedRegion(new CellRangeAddress(1, 1, 19, 20)); // 合并“橙子”区域zcell.setCellStyle(cellStyle); // 应用样式// 手动赋值headerRow2.createCell(0).setCellValue("序号");headerRow2.createCell(1).setCellValue("葡萄");headerRow2.createCell(2).setCellValue("草莓");headerRow2.createCell(3).setCellValue("蓝莓");headerRow2.createCell(4).setCellValue("菠萝");headerRow2.createCell(5).setCellValue("芒果");headerRow2.createCell(6).setCellValue("桃子");headerRow2.createCell(7).setCellValue("樱桃");headerRow2.createCell(8).setCellValue("橘子");headerRow2.createCell(9).setCellValue("柚子");row2.createCell(10).setCellValue("红富士");row2.createCell(11).setCellValue("青苹");row2.createCell(12).setCellValue("蜜脆");row2.createCell(13).setCellValue("金帅");row2.createCell(14).setCellValue("卡文迪什");row2.createCell(15).setCellValue("红香蕉");row2.createCell(16).setCellValue("小香蕉");row2.createCell(17).setCellValue("冰淇淋香蕉");row2.createCell(18).setCellValue("香甜香蕉");row2.createCell(19).setCellValue("甜橙");row2.createCell(20).setCellValue("血橙");headerRow2.createCell(21).setCellValue("杏子");headerRow2.createCell(22).setCellValue("李子");headerRow2.createCell(23).setCellValue("酪梨");// 合并第二行和第三行的单元格sheet.addMergedRegion(new CellRangeAddress(1, 2, 0, 0)); // 序号sheet.addMergedRegion(new CellRangeAddress(1, 2, 1, 1)); // 葡萄sheet.addMergedRegion(new CellRangeAddress(1, 2, 2, 2)); // 草莓sheet.addMergedRegion(new CellRangeAddress(1, 2, 3, 3)); // 蓝莓sheet.addMergedRegion(new CellRangeAddress(1, 2, 4, 4)); // 菠萝sheet.addMergedRegion(new CellRangeAddress(1, 2, 5, 5)); // 芒果sheet.addMergedRegion(new CellRangeAddress(1, 2, 6, 6)); // 桃子sheet.addMergedRegion(new CellRangeAddress(1, 2, 7, 7)); // 樱桃sheet.addMergedRegion(new CellRangeAddress(1, 2, 8, 8)); // 橘子sheet.addMergedRegion(new CellRangeAddress(1, 2, 9, 9)); // 柚子sheet.addMergedRegion(new CellRangeAddress(1, 2, 21, 21)); // 杏子sheet.addMergedRegion(new CellRangeAddress(1, 2, 22, 22)); // 李子sheet.addMergedRegion(new CellRangeAddress(1, 2, 23, 23)); // 酪梨for (int i = 0; i < 10; i++){Cell mergedCell = headerRow2.getCell(i); // 获取合并后的单元格(第一列)mergedCell.setCellStyle(cellStyle); // 应用样式}for (int i = 21; i < 24; i++){Cell mergedCell = headerRow2.getCell(i);mergedCell.setCellStyle(cellStyle); // 应用样式}// 确保第三行的每个单元格都有边框样式for (int i = 0; i < 10; i++) {Cell normalCell = row2.createCell(i);normalCell.setCellStyle(cellStyle); // 应用样式}for (int i = 21; i < 24; i++) {Cell normalCell = row2.createCell(i);normalCell.setCellStyle(cellStyle); // 应用样式}for (int i = 10; i < 21; i++){Cell mergedCell = row2.getCell(i);mergedCell.setCellStyle(cellStyle);}}
设置列宽
在主方法内使用设置列宽的方法,在方法外自行设置
private void exportPersonnelData(HttpServletResponse response, List<SysUserImportVo> userList) throws IOException {// 设置列宽(单位为字符的256倍)setColumnWidths(sheet);
}
private static void setColumnWidths(Sheet sheet) {sheet.setColumnWidth(0, 256 * 5); // 序号sheet.setColumnWidth(1, 256 * 10); // 葡萄sheet.setColumnWidth(2, 256 * 5); // 草莓sheet.setColumnWidth(3, 256 * 10); // 蓝莓sheet.setColumnWidth(4, 256 * 15); // 菠萝sheet.setColumnWidth(5, 256 * 5); // 芒果sheet.setColumnWidth(6, 256 * 15); // 桃子sheet.setColumnWidth(7, 256 * 10); // 樱桃sheet.setColumnWidth(8, 256 * 15); // 橘子sheet.setColumnWidth(9, 256 * 10); // 柚子sheet.setColumnWidth(10, 256 * 20); // 红富士sheet.setColumnWidth(11, 256 * 20); // 青苹sheet.setColumnWidth(12, 256 * 10); // 蜜脆sheet.setColumnWidth(13, 256 * 20); // 金帅sheet.setColumnWidth(14, 256 * 15); // 卡文迪什sheet.setColumnWidth(15, 256 * 15); // 红香蕉sheet.setColumnWidth(16, 256 * 20); // 小香蕉sheet.setColumnWidth(17, 256 * 15); // 冰淇淋香蕉sheet.setColumnWidth(18, 256 * 20); // 香甜香蕉sheet.setColumnWidth(19, 256 * 10); // 甜橙sheet.setColumnWidth(20, 256 * 10); // 血橙sheet.setColumnWidth(21, 256 * 10); // 杏子sheet.setColumnWidth(22, 256 * 30); // 李子sheet.setColumnWidth(23, 256 * 15); // 酪梨}
接下来就是在方法内填充数据了
private void exportPersonnelData(HttpServletResponse response, List<SysUserImportVo> userList) throws IOException {// 创建工作簿Workbook workbook = new XSSFWorkbook();// 创建工作表Sheet sheet = workbook.createSheet("科创");// 设置列宽(单位为字符的256倍)setColumnWidths(sheet);// 创建表头createHeaderRow(workbook, sheet);// 填充数据int rowIndex = 3; // 数据从第4行开始int serialNumber = 1; // 序号从1开始for (SysUserImportVo sysUserImportVo : userList) {Row row = sheet.createRow(rowIndex++);row.createCell(0).setCellValue(serialNumber++);// 序号if (sysUserImportVo.getGrape() != null && !sysUserImportVo.getGrape().isEmpty()) {row.createCell(1).setCellValue(sysUserImportVo.getGrape());// 葡萄} else {row.createCell(1).setBlank(); // 设置为空单元格}// ……以此类推}// 填充完数据之后写入到HttpServletResponse中response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setHeader("Content-Disposition", "attachment; filename=我是标题.xlsx");workbook.write(response.getOutputStream());// 关闭workbook.close();
}
导出调用可以这样写
这边用了个子线程导出 需要注意的一点是 我使用的若依框架获取当前登录用户的信息不可在线程内获取 需要先获取再传入线程中
public ResponseEntity<String> export(HttpServletResponse response, SysUserImportVo sysUserImportVo) throws IOException{SysUser user = SecurityUtils.getLoginUser().getUser();Long userId = user.getUserId();// 当前登录用户是否是管理员或人事boolean isAdminOrHr = userService.selectRole(userId);sysUserImportVo.setUserId(userId);Long deptId = user.getDeptId();// 提交导出任务到子线程,并获取 Future 对象Future<?> future = executorService.submit(() -> {try {List<Long> deptIds = Collections.emptyList();if (isAdminOrHr || user.isAdmin()) {deptIds = deptMapper.selectAllDeptList().stream().map(SysDept::getDeptId).collect(Collectors.toList());} else {deptIds = getDeptIds(deptId);}List<SysUserImportVo> userList = userService.selectListByMood(sysUserImportVo, deptIds);// 调用方法导出ExcelexportPersonnelData(response, userList);} catch (IOException e) {// 处理异常e.printStackTrace();}});// 使用Future来监听任务的完成情况try {// 可以选择等待任务完成,或者根据情况进行处理future.get(); // 如果希望阻塞等待任务完成return ResponseEntity.ok("导出任务已提交,并且完成!");} catch (Exception e) {// 处理异常e.printStackTrace();return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("导出任务失败!");}}
至此即可实现自定义表头的导出
相关文章:
poi如何实现自定义导出Excel-纵向横向合并单元格,自定义填充数据列
前情提要 首先需要明确自己需要导出的excel构成是如何的,比如我需要导出一个自定义表头的excel表格,第一行A到X是标题需要横向合并单元格,第二行和第三行是表头,A到J需要第二行和第三行纵向合并单元格,K到N的第二行需…...
6--苍穹外卖-SpringBoot项目中菜品管理 详解(二)
目录 菜品分页查询 需求分析和设计 代码开发 设计DTO类 设计VO类 Controller层 Service层接口 Service层实现类 Mapper层 功能测试 删除菜品 需求设计和分析 代码开发 Controller层 Service层接口 Service层实现类 Mapper层 功能测试 修改菜品 需求分析和设…...
游戏怎么录制?王者荣耀游戏录制指南:iOS与电脑端全面教程
在王者荣耀的战场上,每一个五杀、每一次极限逃生都可能成为你游戏生涯中的高光时刻。但这些瞬间往往转瞬即逝,如何将它们永久保存,成为你游戏历程中不可磨灭的印记呢?本文将为你揭晓答案。无论你是手持iPhone的iOS用户,…...
Vue.js组件开发指南
Vue.js组件开发指南 Vue.js 是一个渐进式的 JavaScript 框架,用于构建用户界面。它的核心是基于组件的开发模式。通过将页面分解为多个独立的、可复用的组件,开发者能够更轻松地构建复杂的应用。本文将深入探讨 Vue.js 组件开发的基础知识,并…...
【流计算】流计算概论
前言 作者在之前写过一个大数据的专栏,包含GFS、BigTable、MapReduce、HDFS、Hadoop、LSM树、HBase、Spark,专栏地址: https://blog.csdn.net/joker_zjn/category_12631789.html?fromshareblogcolumn&sharetypeblogcolumn&sharerI…...
20230819盘锦锦州葫芦岛自驾
2023年08月19日,上午带娃和老人驾车前往朝阳,逛凤凰山,中午吃了免费的素面味道不错。下午开车去鸟化石公园单独买儿童票43元。晚上驾车到盘锦,住红海滩民宿95元。 2023年08月20日,逛盘锦红海滩一天,有稻田画…...
Unity 与虚幻引擎对比:两大游戏开发引擎的优劣分析
在游戏开发领域,Unity 和虚幻引擎(Unreal Engine)是两款最为知名且广泛使用的引擎。它们各有特点,适合不同类型的开发者和项目。在这篇博客中,我们将深入探讨这两大引擎的核心功能、适用场景、优缺点,以及如…...
UDS_4_传输存储的数据功能单元
目录 一. DTC 二. 0x14服务 三. 0x19服务 3.1 0x19服务 3.2 0x01子功能 3.3 0x02子功能 3.4 0x04子功能 3.5 0x06子功能 3.6 0x0A子功能 一. DTC 》DTC-Diagnostic Trouble Code J1939-73 DTCFormat DTC SPN FMI CM OC 8-1位 8-1位 8-6位 5-1位 8位 7-1位 字节1 字节…...
第二百五十八节 JPA教程 - JPA查询选择两个实体示例
JPA教程 - JPA查询选择两个实体示例 以下JPQL从两个实体中选择。 List l em.createQuery("SELECT d, m FROM Department d, Professor m WHERE d m.department").getResultList();例子 以下代码来自Professor.java。 package cn.w3cschool.common;import java.…...
数据库三级模式结构
三级模式结构 1. 外模式(External Schema)——“用户看到的楼层”2. 概念模式(Conceptual Schema)——“图书馆的核心”3. 内模式(Internal Schema)——“图书馆的地下室”举例1. 概念模式的例子2. 外模式的…...
【小程序websocket最佳实践,有心跳和断线重连】
小程序websocket最佳实践,有心跳和断线重连 封装了WebSocketHandler类,用于管理websocket链接,保证链接的稳定和可靠,该类主要适用于小程序,但其设计思想和方法也适用于其他平台。 export default class WebSocketHa…...
自然资源部最新Nature正刊!!!
2024年8月21日,国际顶级期刊《Nature》发表了自然资源部第二海洋研究所李家彪院士为通讯作者,张涛为第一作者的论文“超慢速扩张加克洋中脊的高变化岩浆增生”。这一成果颠覆了国际海洋学术界半个多世纪以来一直认为的超慢速扩张洋中脊岩浆供给极度贫瘠的…...
git分支-创建、合并、删除
Git会将每次提交串成一条时间线,这条时间线就是一个分支。在最初,只有一个master分支 在目录下创建项目 对目录进行输入 项目被修改 创建dev分支 合并分支 删除dev分支...
Python:Spoonfed - (2-10) 激励选择脚本(搬砖)
https://www.patreon.com/posts/python-spoonfed-31572219 2019年11月15日 利用上一课的选择函数,我们现在可以拼凑出一些脚本(有一些事情我们还没有解释,但应该很容易理解)。以下代码将允许您选择当前所选对象的父对象、顶级对…...
VS Code Python 文件导入提示 xxx Module 不存在解决方式
VS Code Python 文件导入提示 xxx Module 不存在解决方式 引言正文如何打开 setting.json 文件引言 之前在 https://blog.csdn.net/u011699626/article/details/142612579?spm=1001.2014.3001.5501 一文中我们介绍了如何配置 VS code 中 Jupyter Notebook 的文件导入环境,这…...
Android中的Activity与Fragment:深入解析与应用场景
在Android应用开发中,Activity和Fragment是两个核心概念,它们各自扮演着不同的角色,共同构成了用户界面的基础。理解并熟练掌握这两个组件的使用,对于开发高效、灵活且用户友好的Android应用至关重要。本文将深入解析Activity与Fr…...
Flux【lora模型】【真人模型】:极致逼真,小红书真实风格|旅游拍照|景点打卡
大家好我是安琪!!! 今天和大家推荐一款基于Flux训练的真人写实的lora模型:Flux_小红书真实风格丨日常照片丨极致逼真。一看这个模型的命名,就可以猜测出以小红书日常真实拍摄的照片为数据集训练而来,该模型…...
python基础语法--顺序结构
Python中的顺序结构主要包括流程控制语句,如 if、while 和 for 语句。这些语句允许你在程序中定义不同的执行路径,从而根据条件或循环次数来改变代码的执行流程。下面详细介绍这些语句的使用方法和示例。 if 语句 if 语句用于根据某个条件来决定是否执…...
软件游戏运行缺少vcruntime140.dll怎么办?总结四种有效简单方法
1. 文件基本信息 1.1 定义与作用 vcruntime140.dll是Microsoft Visual C 2015 Redistributable Package的一部分,它包含了C运行时库,用于支持使用Visual C开发的Windows应用程序。这个动态链接库(DLL)文件提供了程序执行时所需的…...
(undone) 阅读 MapReduce 论文笔记
参考:https://pdos.csail.mit.edu/6.824/papers/mapreduce.pdf 摘要:简单介绍了 MapReduce 是在大型分布式系统上工作的 Introduction 的内容总结: 1.介绍背景:为什么我们需要分布式系统?MapReduce 的意义是哪些 2.简…...
Pixel Epic智识终端效果展示:跨领域研报生成一致性与专业性验证
Pixel Epic智识终端效果展示:跨领域研报生成一致性与专业性验证 1. 产品概览与核心价值 Pixel Epic智识终端是一款基于AgentCPM-Report大模型构建的专业研究报告生成工具。与传统AI工具不同,它创新性地采用了像素RPG游戏的美学设计,将枯燥的…...
CSS 滚动驱动动画:让页面动起来的新维度
CSS 滚动驱动动画:让页面动起来的新维度代码如诗,滚动如歌。让我们用滚动驱动动画的魔法,为用户带来沉浸式的浏览体验。什么是滚动驱动动画? 滚动驱动动画(Scroll-driven Animations)是 CSS 中一项革命性的…...
视频修复终极指南:如何用UNTRUNC拯救你的损坏视频文件
视频修复终极指南:如何用UNTRUNC拯救你的损坏视频文件 【免费下载链接】untrunc Restore a damaged (truncated) mp4, m4v, mov, 3gp video. Provided you have a similar not broken video. 项目地址: https://gitcode.com/gh_mirrors/unt/untrunc 还记得那…...
STM32F4读写SD卡:填一填ST官方HAL库的坑
使用STM32读写SD卡在低功耗存储中的应用是比较常见的,但是网上大多数资料都是基于标准库或者基于寄存器的开发。随着嵌入式设备越来越复杂,使用HAL库能够大大降低开发者的学习成本,从而提高开发效率。近年来,ST官方主推以STM32Cub…...
koanf自定义Provider开发:扩展你的配置源终极指南
koanf自定义Provider开发:扩展你的配置源终极指南 【免费下载链接】koanf Simple, extremely lightweight, extensible, configuration management library for Go. Supports JSON, TOML, YAML, env, command line, file, S3 etc. Alternative to viper. 项目地址…...
一篇文章彻底搞懂Linux驱动的并发控制与中断上下半部机制
在嵌入式 Linux 驱动开发中,并发控制与中断处于极其重要的核心地位。本文,我将结合 CPU 的行为与操作系统的调度,深入分析 spinlock 和 mutex 的本质区别,以及 Linux 中断上下半部。1. 上下文的概念 在深入探究锁和中断之前&#…...
终极指南:如何使用Harepacker-resurrected打造个性化MapleStory游戏体验
终极指南:如何使用Harepacker-resurrected打造个性化MapleStory游戏体验 【免费下载链接】Harepacker-resurrected All in one .wz file/map editor for MapleStory game files 项目地址: https://gitcode.com/gh_mirrors/ha/Harepacker-resurrected 你是否曾…...
开源AI翻译新范式:Pixel Language Portal镜像免配置+GPU算力适配教程
开源AI翻译新范式:Pixel Language Portal镜像免配置GPU算力适配教程 1. 产品概览:像素语言跨维传送门 Pixel Language Portal(像素语言跨维传送门)是一款基于Tencent Hunyuan-MT-7B大模型构建的创新翻译工具。与传统翻译软件不同…...
Plumbum管道与重定向完全教程:构建复杂Shell命令链
Plumbum管道与重定向完全教程:构建复杂Shell命令链 【免费下载链接】plumbum Plumbum: Shell Combinators 项目地址: https://gitcode.com/gh_mirrors/pl/plumbum Plumbum是一个强大的Python库,它让您在Python中编写shell脚本般简洁的代码&#x…...
GRACE/GRACE-FO数据下载全攻略:从零开始搞定三大机构数据源(含最新FTP地址)
GRACE/GRACE-FO数据获取与处理全流程指南:2024年三大机构最新数据源解析 对于刚接触地球物理学和气候研究领域的研究人员来说,获取和处理GRACE/GRACE-FO卫星数据往往面临诸多挑战。本文将系统介绍2024年三大主流数据机构(JPL、GFZ、CSR&…...
