【EasyExcel】复杂导出操作-自定义颜色样式等(版本3.1.x)
文章目录
- 前言
- 一、自定义拦截器
- 二、自定义操作
- 1.自定义颜色
- 2.合并单元格
- 三、复杂操作示例
- 1.实体(使用了注解式样式):
- 2.自定义拦截器
- 3.代码
- 4.最终效果
前言
本文简单介绍阿里的EasyExcel的复杂导出操作,包括自定义样式,根据数据合并单元格等。
点击查看EasyExcel官方文档
一、自定义拦截器
要实现复杂导出,靠现有的拦截器怕是不大够用,EasyExcel 已经有提供部分像是 自定义样式的策略HorizontalCellStyleStrategy



通过源码,我们不难发现其原理正是实现了拦截器接口,使用了afterCellDispose方法,在数据写入单元格后会调用该方法,因此,需要进行复杂操作,我们需要自定义拦截器,在afterCellDispose方法进行逻辑处理,其中我们可以通过context参数获取到表,行,列及单元格数据等信息:

二、自定义操作
1.自定义颜色
由于WriteCellStyle 及CellStyle接口的设置单元格背景颜色方法setFillForegroundColor不支持自定义颜色,我在网上找了半天,以及询问阿里自家ai助手通义得到的答案都是往里塞一个XSSFColor这样的答案,但这个方法传参是一个short类型的index呀,是预设好的颜色,里面也没有找到其他重载方法。(这里针对的是导出xlsx文件)

而真正可以自定义颜色的是XSSFCellStyle类,XSSFCellStyle实现CellStyle接口,并重载了该方法,于是我们只需要在workbook.createCellStyle()的时候将其强转为XSSFCellStyle:
// 将背景设置成浅蓝色
XSSFColor customColor = new XSSFColor(new java.awt.Color(181, 198, 234), null);
XSSFCellStyle style = (XSSFCellStyle)workbook.createCellStyle();
style.setFillForegroundColor(customColor);
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cell.setCellStyle(style);
在idea我们可以使用 ctrl + alt + 鼠标点击接口,来查看接口的所有实现类(HSSF是针对xls的):

然而在我们自定义的拦截器中,操作当前单元格样式时会无法生效,这是因为在3.1.x版本后有一个FillStyleCellWriteHandler拦截器,他会把OriginCellStyle和WriteCellStyle合并,会已WriteCellStyle样式为主,他的order是50000,而我们自定义的拦截器默认是0,因此我们修改的样式会被覆盖。


解决方法很简单,我们可以在我们的自定义拦截器重写order方法,将其值设置大于50000即可
@Overridepublic int order() {return 50001;}
如果你没有使用自定义拦截器(如HorizontalCellStyleStrategy )以及没有设置WriteCellStyle 样式,则还可以将ignoreFillStyle置为true,
@Overridepublic void afterCellDispose(CellWriteHandlerContext context) {context.setIgnoreFillStyle(true);// 做其他样式操作}
2.合并单元格
```java@Overridepublic void afterCellDispose(CellWriteHandlerContext context) {// 判断当前为表头,不执行操作if (isHead) {log.info("\r\n当前为表头, 不执行操作");return;}// 获取当前单元格context.getCell()// 当前 SheetSheet sheet = cell.getSheet();// 当前单元格所在行索引int rowIndexCurr = cell.getRowIndex();// 当前单元格所在列索引int columnIndex = cell.getColumnIndex();// 当前单元格所在行的上一行索引int rowIndexPrev = rowIndexCurr - 1;// 当前单元格所在行的 Row 对象Row rowCurr = cell.getRow();// 当前单元格所在行的上一行 Row 对象Row rowPrev = sheet.getRow(rowIndexPrev);// 当前单元格的上一行同列单元格Cell cellPrev = rowPrev.getCell(columnIndex);// 合并同列不同行的相邻两个单元格sheet.addMergedRegion(new CellRangeAddress(rowIndexPrev, rowIndexCurr,columnIndex, columnIndex));}
需要注意的是,如果要合并的单元格已经被其他单元格合并过,则不能直接使用这个合并方法,需要先解除合并,再进行组合合并:
// 从 Sheet 中,获取所有合并区域List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();// 判断是否合并过boolean merged = false;// 遍历合并区域集合for (int i = 0; i < mergedRegions.size(); i++) {CellRangeAddress cellAddresses = mergedRegions.get(i);// 判断 cellAddress 的范围是否是从 rowIndexPrev 到 cell.getColumnIndex()if (cellAddresses.isInRange(rowIndexPrev, cell.getColumnIndex())) {// 解除合并sheet.removeMergedRegion(i);// 设置范围最后一行,为当前行cellAddresses.setLastRow(rowIndexCurr);// 重新进行合并sheet.addMergedRegion(cellAddresses);merged = true;break;}}// merged=false,表示当前单元格为第一次合并if (!merged) {CellRangeAddress cellAddresses = new CellRangeAddress(rowIndexPrev, rowIndexCurr, cell.getColumnIndex(), cell.getColumnIndex());sheet.addMergedRegion(cellAddresses);}
三、复杂操作示例
自定义拦截器代码如下(示例):
1.实体(使用了注解式样式):
package com.mhqs.demo.tool.easyExcel.entity;import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentFontStyle;
import com.alibaba.excel.annotation.write.style.HeadFontStyle;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import lombok.Data;
import lombok.EqualsAndHashCode;import java.math.BigDecimal;/*** 账单实体类* @author 棉花* */
@Data
@EqualsAndHashCode(callSuper = false)
@HeadFontStyle(fontHeightInPoints = 10)
@HeadRowHeight(27)
@ColumnWidth(13)
@ContentFontStyle(fontName = "宋体",fontHeightInPoints = 11)
public class DemoEntity extends EasyExcelEntity {@ExcelProperty({"账期"})private String settlePeriod;@ExcelProperty({"服务商"})private String stockCreatorMchid;@ExcelProperty({"地区"})private String place;@ExcelProperty({"金额(元)"})private BigDecimal consumeAmount;public DemoEntity(String settlePeriod, String stockCreatorMchid,String place, BigDecimal consumeAmount){this.settlePeriod = settlePeriod;this.stockCreatorMchid = stockCreatorMchid;this.place = place;this.consumeAmount = consumeAmount;}}
2.自定义拦截器
package com.mhqs.demo.tool.easyExcel.handler;import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.StyleUtil;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.mhqs.demo.tool.easyExcel.entity.DemoEntity;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;import java.math.BigDecimal;
import java.util.*;/*** @author bcb* 账单导出样式处理*/
public class CustomCellWriteHandler implements CellWriteHandler {/*** 自定义颜色*/private final java.awt.Color color;/*** 自定义颜色样式*/private CellStyle colorfulCellStyle;/*** 自定义特殊金额样式*/private CellStyle specialCellStyle;/*** 头样式*/private final WriteCellStyle headWriteCellStyle;/*** 内容样式*/private final WriteCellStyle contentWriteCellStyle;/*** 头样式(可自定义颜色)*/private CellStyle headCellStyle;/*** 内容样式(可自定义颜色)*/private CellStyle contentCellStyle;public CustomCellWriteHandler(WriteCellStyle headWriteCellStyle,WriteCellStyle contentWriteCellStyle, java.awt.Color color) {this.headWriteCellStyle = headWriteCellStyle;this.contentWriteCellStyle = contentWriteCellStyle;this.color = color;}@Overridepublic void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {// 在创建单元格之前的操作(如果需要)Workbook workbook = writeSheetHolder.getSheet().getWorkbook();if (colorfulCellStyle == null) {colorfulCellStyle = createColorfulCellStyle(workbook);}// 合并样式(以WriteCellStyle为主)headCellStyle = StyleUtil.buildCellStyle(workbook, colorfulCellStyle, headWriteCellStyle);contentCellStyle = StyleUtil.buildCellStyle(workbook, workbook.createCellStyle(), contentWriteCellStyle);}/** 创建自定义颜色样式*/private CellStyle createColorfulCellStyle(Workbook workbook) {XSSFColor customColor = new XSSFColor(color, null);XSSFCellStyle style = (XSSFCellStyle)workbook.createCellStyle();// 设置自定义颜色style.setFillForegroundColor(customColor);style.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 设置边框style.setBorderTop(BorderStyle.THIN);style.setBorderBottom(BorderStyle.THIN);style.setBorderLeft(BorderStyle.THIN);style.setBorderRight(BorderStyle.THIN);// 设置垂直对齐方式style.setVerticalAlignment(VerticalAlignment.CENTER);// 设置水平对齐方式style.setAlignment(HorizontalAlignment.CENTER);return style;}/** 创建自定义特殊金额样式*/private CellStyle createSpecialCellStyle(Workbook workbook) {if (specialCellStyle == null) {XSSFCellStyle style = (XSSFCellStyle)createColorfulCellStyle(workbook);Font font = workbook.createFont();// 字体加粗font.setBold(true);style.setFont(font);specialCellStyle = style;}return specialCellStyle;}/*** 在 Cell 写入后处理** @param writeSheetHolder* @param writeTableHolder* @param cellDataList* @param cell 当前 Cell* @param head* @param relativeRowIndex 表格内容行索引,从除表头的第一行开始,索引为0* @param isHead 是否是表头,true表头,false非表头*/@Overridepublic void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {// 当前 SheetSheet sheet = cell.getSheet();// 判断当前为表头,执行对应样式操作if (isHead) {cell.setCellStyle(headCellStyle);} else {cell.setCellStyle(contentCellStyle);}// 判断当前为表头,不执行操作if (isHead || relativeRowIndex == 0) {return;}int columnIndex = cell.getColumnIndex();// 当前 Cell 所在行索引int rowIndexCurr = cell.getRowIndex();// 当前 Cell 所在行的上一行索引int rowIndexPrev = rowIndexCurr - 1;// 当前 Cell 所在行的 Row 对象Row rowCurr = cell.getRow();// 当前 Cell 所在行的上一行 Row 对象Row rowPrev = sheet.getRow(rowIndexPrev);// 当前单元格的上一行同列单元格Cell cellPrev = rowPrev.getCell(columnIndex);// 当前单元格的值Object cellValueCurr = cell.getCellType() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();if (columnIndex == 3 && cellValueCurr != null && (double)cellValueCurr > 200) {// 判断金额大于200就设置特定颜色并加粗,并将上一列同一行的数据也设置特定颜色CellStyle cellStyle = createSpecialCellStyle(sheet.getWorkbook());cell.setCellStyle(cellStyle);// 当前单元格的同行上一列单元格Cell cellPreC = rowCurr.getCell(columnIndex - 1);cellPreC.setCellStyle(colorfulCellStyle);}// 上面单元格的值Object cellValuePrev = cellPrev.getCellType() == CellType.STRING ? cellPrev.getStringCellValue() : cellPrev.getNumericCellValue();/** 只判断前两列相同行数据*/if (columnIndex != 0 && columnIndex != 1) {return;}// 判断当前单元格与上面单元格是否相等,不相等不执行操作if (!cellValueCurr.equals(cellValuePrev)) {return;}/** 当第一列上下两个单元格不一样时,说明不是一个账期数据*/if (!rowPrev.getCell(0).getStringCellValue().equals(rowCurr.getCell(0).getStringCellValue())) {return;}// 从 Sheet 中,获取所有合并区域List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();// 是否合并过boolean merged = false;// 遍历合并区域集合for (int i = 0; i < mergedRegions.size(); i++) {CellRangeAddress cellAddresses = mergedRegions.get(i);//判断 cellAddress 的范围是否是从 rowIndexPrev 到 cell.getColumnIndex()if (cellAddresses.isInRange(rowIndexPrev, columnIndex)) {// 从集合中移除sheet.removeMergedRegion(i);// 设置范围最后一行,为当前行cellAddresses.setLastRow(rowIndexCurr);// 重新添加到 Sheet 中sheet.addMergedRegion(cellAddresses);// 已完成合并merged = true;break;}}// merged=false,表示当前单元格为第一次合并if (!merged) {CellRangeAddress cellAddresses = new CellRangeAddress(rowIndexPrev, rowIndexCurr, columnIndex, columnIndex);sheet.addMergedRegion(cellAddresses);}}/*** 获取当前处理器优先级*/@Overridepublic int order() {return 50001;}}
3.代码
public static void main(String[] args) {String fileName = "D:\\temp\\账单.xlsx";// 设置 Cell 样式WriteCellStyle writeCellStyle = new WriteCellStyle();// 设置垂直对齐方式writeCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 设置水平对齐方式writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 设置边框writeCellStyle.setBorderTop(BorderStyle.THIN);writeCellStyle.setBorderBottom(BorderStyle.THIN);writeCellStyle.setBorderLeft(BorderStyle.THIN);writeCellStyle.setBorderRight(BorderStyle.THIN);// 自定义颜色java.awt.Color color = new java.awt.Color(181, 198, 234);List<DemoEntity> dataList = new ArrayList<>();for (int i = 0; i < 5; i++) {dataList.add(new DemoEntity("202301","服务商" + i%2,"地区" + i,new BigDecimal(i * 100)));}dataList.sort(Comparator.comparing(DemoEntity::getSettlePeriod).thenComparing(DemoEntity::getStockCreatorMchid));ExcelWriter excelWriter = EasyExcel.write(fileName, DemoEntity.class).build();WriteSheet writeSheet = EasyExcel.writerSheet(0, "账单").registerWriteHandler(new CustomCellWriteHandler(null,writeCellStyle,color)).build();excelWriter.write(dataList, writeSheet);// 需要多sheet则可以继续// WriteSheet writeSheet2 = EasyExcel.writerSheet(1, "第二个sheet")excelWriter.finish();}
4.最终效果

待续…
参考文章:
easyexcel 3.1.0+,设置RBG背景颜色
EasyExcel导出多sheet并设置单元格样式
EasyExcel的CellWriteHandler注入CellStyle不生效
相关文章:
【EasyExcel】复杂导出操作-自定义颜色样式等(版本3.1.x)
文章目录 前言一、自定义拦截器二、自定义操作1.自定义颜色2.合并单元格 三、复杂操作示例1.实体(使用了注解式样式):2.自定义拦截器3.代码4.最终效果 前言 本文简单介绍阿里的EasyExcel的复杂导出操作,包括自定义样式,根据数据合并单元格等。…...
机器学习 ---线性回归
目录 摘要: 一、简单线性回归与多元线性回归 1、简单线性回归 2、多元线性回归 3、残差 二、线性回归的正规方程解 1、线性回归训练流程 2、线性回归的正规方程解 (1)适用场景 (2)正规方程解的公式 三、衡量…...
深度学习每周学习总结J5(DenseNet-121 +SE 算法实战与解析 - 猴痘识别)
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 0. 总结 数据导入及处理部分:本次数据导入没有使用torchvision自带的数据集,需要将原始数据进行处理包括数据导入…...
VBA学习笔记:点击单元格显示指定的列
应用场景: 表格中列数较多,特定条件下隐藏一些无关的列,只保留相关的列,使表格更加清晰。 示例:原表格如下 点击一年级,只显示一年级相关的科目: 点击二年级,只显示二年级相关的科…...
windows C#-LINQ概述
语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。 数据查询历来都表示为简单的字符串,没有编译时类型检查或 IntelliSense 支持。 此外,需要针对每种类型的数据源了解不同的查询语言:SQL 数据库、XML 文档、各种 Web 服…...
vue项目npm run serve出现【- Network: unavailable】(从排查到放弃)
1. 问题现象 环境: 系统:win11node:v16.20.2“vue”: “2.6.10” 执行npm run serve启动vue项目,期望: App running at:- Local: http://localhost:9528/ - Network: http://x.x.x.x:9528/实际: App runn…...
R语言贝叶斯分析:INLA 、MCMC混合模型、生存分析肿瘤临床试验、间歇泉喷发时间数据应用|附数据代码...
全文链接:https://tecdat.cn/?p38273 多模态数据在统计学中并不罕见,常出现在观测数据来自两个或多个潜在群体或总体的情况。混合模型常用于分析这类数据,它利用不同的组件来对数据中的不同群体或总体进行建模。本质上,混合模型是…...
C++ 关于类与对象(中篇)一篇详解!(运算符重载)
赋值运算符重载 运算符重载 C 为了 增强代码的可读性 引入了运算符重载 , 运算符重载是具有特殊函数名的函数 ,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。 函数名字为:关键…...
Scala的set
//Set的特点:唯一(元素不相同);无序 case class Book(var bookName:String,var author:String,var price:Double){} object test27 {def main(args: Array[String]): Unit {//定义一个可变setval set1 scala.collection.mutable…...
Linux---常用shell脚本
目录 一.网络服务 开启network服务 网口IP配置 聚合口配置 前言 秋招拿到了科大讯飞的offer,可是由于某些原因无法完成三方签署,心情还是比较失落的,或许写一篇技术博客,活跃一下大脑思维也是一种不错的放松方式。 一.网络服务 …...
windows二进制安全零基础(二)
文章目录 栈(The Stack)调用约定(Calling Conventions)函数返回机制 在x86架构中,栈(Stack)是一个非常重要的内存区域,它用于支持线程的短期数据需求,如函数调用、局部变…...
git常用命令+搭vscode使用
1.克隆远程代码 git clone http:xxx git clone ssh:xxx clone的url 中 https和 ssh是有区别的: git中SSH和HTTP连接有什么区别-CSDN博客 当然https拉下来的代码每次pull /push都需要验证一次自己的账户和密码,可以config进行配置不用每次手敲: 解决VScode中每次git pu…...
如何在C#中处理必盈接口返回的股票数据?
在必盈接口返回股票数据后,在 C# 中可通过以下步骤进行处理: 数据获取 使用 HttpWebRequest 或 HttpClient 类向必盈接口发送请求以获取数据。以 HttpWebRequest 为例,构建请求并发送,获取响应流后读取为字符串形式的 JSON 数据。…...
01 最舒适的python开发环境
0 前言 我自己经过尝试,总结出python3开发环境的最舒适方式。 python3安装创建虚拟环境 venvjupyter notebook 笔记本安装vscode插件(Python, Pylance, Jupyter) 1 python3安装 ubuntu系统下安装最新版本的python3 sudo apt update sudo apt install python32 …...
【PyTorch】libtorch_cpu.so: undefined symbol: iJIT_NotifyEvent
【PyTorch】libtorch_cpu.so: undefined symbol: iJIT_NotifyEvent 1 报错信息2 原因3 解决方法 1 报错信息 conda install pytorch1.13.1 torchaudio0.13.1 torchvision0.14.1 cudatoolkit11.7 -c pytorch在 conda 环境中安装 torch 后测试,得到下面的错误&#x…...
快速利用c语言实现线性表(lineList)
线性表是数据结构中最基本和简单的一个,它是n的相同类型数据的有序序列,我们也可以用c语言中的数组来理解线性表。 一、线性表声明 我们定义一个线性表的结构体,内部有三个元素:其中elem是一个指针,指向线性表的头&am…...
量子计算与人工智能的交汇:科技未来的新引擎
引言 在当今飞速发展的科技世界,人工智能(AI)和量子计算无疑是最受瞩目的两大前沿领域。人工智能凭借其在数据处理、模式识别以及自动化决策中的强大能力,已经成为推动各行业数字化转型的重要力量。而量子计算则通过颠覆传统计算机…...
51单片机使用NRF24L01进行2.4G无线通信
本文并不打算详细介绍NRF24L01的各个功能寄存器及指令的详细用法,因为网上都可以搜到很多非常详细的教程文档,这里只是介绍一些基本概念、用法以及代码的解释,旨在帮助新手能够快速上手调通快速使用。 基础概念 该模块使用的是SPI协议&…...
HelloMeme 上手即用教程
HelloMeme是一个集成空间编织注意力的扩散模型,用于生成高保真图像和视频。它提供了一个代码库,包含实验代码和预训练模型,支持PyTorch和FFmpeg。用户可以通过简单的命令行操作来生成图像和视频。 本文将详细介绍,如何在GPU算力租…...
自定义call方法和apply方法
自定义call方法 //Fn:要执行的函数,obj:函数中this的指向,args:剩余参数function call(Fn, obj, ...args) {//判断if (obj undefined || obj null) {obj globalThis; //全局对象 globalThis:es11新增的特性,用来指向…...
多模态2025:技术路线“神仙打架”,视频生成冲上云霄
文|魏琳华 编|王一粟 一场大会,聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中,汇集了学界、创业公司和大厂等三方的热门选手,关于多模态的集中讨论达到了前所未有的热度。其中,…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
