easyExcel自定义导出,指定列,设置请求头背景色,加入合计行,设置合计行字体,背景色等等

效果图

1.引入easyExcel pom

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

2.工具类-自定义样式handler-CustomCellWriteHandler



import java.util.HashMap;

import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.write.handler.AbstractCellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
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.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
/**
 * easyexcel自定义行列样式
 * 表头背景色,合计行背景色-字体颜色,
 * @author cf
 *
 * @date 2023-11-28 11:18:23
 */
public class CustomCellWriteHandler extends AbstractCellWriteHandler {

	// 字体颜色
	private Short colorIndex;
	// 背景颜色
	private Short bgColorIndex;
	// 行,以及对应的列,多个列逗号拼接,全列,-1
	private HashMap<Integer, String> rowColMap;

	/**
	 * 
	 * @param bgColorIndex -1 不设置
	 * @param colorIndex   -1 不设置
	 * @param rowColMap    value = -1,整行
	 */
	public CustomCellWriteHandler(Short bgColorIndex, Short colorIndex, HashMap<Integer, String> rowColMap) {
		this.colorIndex = colorIndex;
		this.bgColorIndex = bgColorIndex;
		this.rowColMap = rowColMap;
	}

	@Override
	public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
			Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
		// 设置行高
		int rowIndex = row.getRowNum();
		System.out.println("当前行: " + rowIndex);
		short height = 600;
		row.setHeight(height);
	}

	@Override
	public void afterCellDispose(CellWriteHandlerContext context) {
		Cell cell = context.getCell();
		int rowIndex = cell.getRowIndex();
		int cellIndex = cell.getColumnIndex();

		// 自定义宽度处理

		// 自定义样式处理
		// 当前事件会在 数据设置到poi的cell里面才会回调
		// 判断不是头的情况 如果是fill 的情况 这里会==null 所以用not true
		Boolean head = context.getHead();
		if (BooleanUtils.isNotTrue(head)) {

			// 指定行 列设置背景色
			if (null != rowColMap && rowColMap.get(rowIndex) != null && !rowColMap.get(rowIndex).equals("-1")
					&& rowColMap.get(rowIndex).contains(cellIndex + "")) {
				setCellStyle(context, cell);
				// 某几行设置背景色
			} else if (null != rowColMap && rowColMap.get(rowIndex) != null && rowColMap.get(rowIndex).equals("-1")) {
				setCellStyle(context, cell);
			}
//            if (cell.getColumnIndex() == 8 && cell.getStringCellValue().contains("已通过")) {
//                // 拿到poi的workbook
//                Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
//                // 这里千万记住 想办法能复用的地方把他缓存起来 一个表格最多创建6W个样式
//                // 不同单元格尽量传同一个 cellStyle
//                CellStyle cellStyle = workbook.createCellStyle();
//                cellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
//                // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND
//                cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
//                cell.setCellStyle(cellStyle);
//                // 由于这里没有指定dataformat 最后展示的数据 格式可能会不太正确
//                // 这里要把 WriteCellData的样式清空, 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到
//                // cell里面去 会导致自己设置的不一样(很关键)
//                context.getFirstCellData().setWriteCellStyle(null);
//            } 
		} else {
			// 表头

		}
	}

	private void setCellStyle(CellWriteHandlerContext context, Cell cell) {
		Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
		Font font = workbook.createFont();
		font.setFontName("宋体");
		font.setBold(true);
		if (colorIndex >= 0) {
			font.setColor(colorIndex);
		}
//		font.setFontHeightInPoints((short)11);
		CellStyle cellStyle = workbook.createCellStyle();
		cellStyle.setFillForegroundColor(bgColorIndex);
		if (bgColorIndex >= 0) {
			cellStyle.setFillForegroundColor(bgColorIndex);
		}
		// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND
		cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		cellStyle.setFont(font);
		cellStyle.setAlignment(HorizontalAlignment.CENTER);
		cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
		cellStyle.setBorderBottom(BorderStyle.MEDIUM);
		cellStyle.setBorderLeft(BorderStyle.MEDIUM);
		cellStyle.setBorderRight(BorderStyle.MEDIUM);
		cellStyle.setBorderTop(BorderStyle.MEDIUM);

		// 样式写入单元格
		cell.setCellStyle(cellStyle);

		// 由于这里没有指定dataformat 最后展示的数据 格式可能会不太正确
		// 这里要把 WriteCellData的样式清空, 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将
		// WriteCellStyle 设置到
		// cell里面去 会导致自己设置的不一样
		context.getFirstCellData().setWriteCellStyle(null);
	}

	/**
	 * 表头背景色等设置
	 * 
	 * @return
	 */
	public static HorizontalCellStyleStrategy getStyleStrategy() {

		// 头的策略
		WriteCellStyle headWriteCellStyle = new WriteCellStyle();
		// 设置对齐
		// headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
		// 背景色, 设置为绿色,也是默认颜色
		headWriteCellStyle.setFillForegroundColor(IndexedColors.CORNFLOWER_BLUE.getIndex());
		// 字体
		// WriteFont headWriteFont = new WriteFont();
		// headWriteFont.setFontHeightInPoints((short) 12);
		// headWriteCellStyle.setWriteFont(headWriteFont);

		// 内容的策略
		WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
		// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了
		// FillPatternType所以可以不指定
		// contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
		contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
		// 背景绿色
		contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE1.getIndex());

		// 字体策略
		WriteFont contentWriteFont = new WriteFont();
		// contentWriteFont.setFontHeightInPoints((short) 12);
		contentWriteCellStyle.setWriteFont(contentWriteFont);
		// 设置 自动换行
		contentWriteCellStyle.setWrapped(true);
		// 设置 垂直居中
		contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
		// 设置 水平居中
		contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
		// 设置边框样式
		contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
		contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
		contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
		contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);

		// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
		HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle,
				contentWriteCellStyle);
		return horizontalCellStyleStrategy;
	}
}

3.工具类-导出  ExcelUtils

package com.yintong.xgj.common.util.excel;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.springframework.beans.BeanUtils;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;


/**
 * excel工具类
 *
 */
public class ExcelUtils {

	/**
	 * Excel导出
	 *
	 * @param response  response
	 * @param fileName  文件名
	 * @param sheetName sheetName
	 * @param list      数据List
	 * @param pojoClass 对象Class
	 * @param columns   自定义列表
	 */
	public static void exportExcel(HttpServletResponse response, String fileName, String sheetName, List<?> list,
			Class<?> pojoClass, Set<String> columns) throws IOException {
		if (StringUtils.isBlank(fileName)) {
			// 当前日期
			fileName = DateUtils.format(new Date());
		}

		response.setContentType("application/vnd.ms-excel");
		response.setCharacterEncoding("UTF-8");
		fileName = URLEncoder.encode(fileName, "UTF-8");
		response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
		// 写入合计行样式;默认表头只有一行
//        TotalRowHandler totalRowHandler = new TotalRowHandler(list.size());
		// 指定行列
		HashMap<Integer, String> rowColMap = new HashMap<>();
//        rowColMap.put(1,"1,2");
//        rowColMap.put(2,"2");
		rowColMap.put(list.size(), "-1");// 合计行,最后一行设置颜色
		CustomCellWriteHandler totalRowHandler = new CustomCellWriteHandler((short) -1, IndexedColors.RED.index,
				rowColMap);
		if (columns != null && columns.size() > 0) {// 自定义列
			EasyExcel.write(response.getOutputStream(), pojoClass).includeColumnFieldNames(columns)
					.registerWriteHandler(CustomCellWriteHandler.getStyleStrategy())
					.registerWriteHandler(totalRowHandler).sheet(sheetName).doWrite(list);
		} else {
			EasyExcel.write(response.getOutputStream(), pojoClass)
					.registerWriteHandler(CustomCellWriteHandler.getStyleStrategy())
					.registerWriteHandler(totalRowHandler).sheet(sheetName).doWrite(list);
		}

	}

	/**
	 * Excel导出,先sourceList转换成List<targetClass>,再导出
	 *
	 * @param response    response
	 * @param fileName    文件名
	 * @param sheetName   sheetName
	 * @param sourceList  原数据List
	 * @param targetClass 目标对象Class
	 */
	public static void exportExcelToTarget(HttpServletResponse response, String fileName, String sheetName,
			List<?> sourceList, Class<?> targetClass, Set<String> columns) throws Exception {
		List<Object> targetList = new ArrayList<Object>(sourceList.size());
		for (Object source : sourceList) {
			Object target = targetClass.newInstance();
			BeanUtils.copyProperties(source, target);
			targetList.add(target);
		}
		exportExcel(response, fileName, sheetName, targetList, targetClass, columns);
	}

	/**
	 * 导入
	 * 
	 * @param file
	 * @param targetClass
	 * @return
	 * @throws Exception
	 */
	public static List<Object> importExcelToTarget(MultipartFile file, Class<?> targetClass) throws Exception {
		List<Object> list = EasyExcel.read(file.getInputStream()).head(targetClass).sheet().doReadSync();
		return list;
	}

}

4.demo

实体

import java.math.BigDecimal;
import java.util.Date;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.HeadStyle;
import com.yintong.xgj.entity.enums.TypeStateConvert;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(value = "采购入库导出", description = "")
@HeadStyle(fillBackgroundColor = 24)
public class GoodsInExcel {

	@ApiModelProperty(value = "工单号")
	@ExcelProperty(value = "工单号")
	private String orderNo;
	@ApiModelProperty(value = "时间" )
	@ExcelProperty(value = "时间" )
	@ColumnWidth(20)
	@DateTimeFormat(value = "yyyy-MM-dd HH:mm:ss")
	private Date actionTime;
	@ApiModelProperty(value = "单据类型")
	@ExcelProperty(value = "单据类型" ,converter = TypeStateConvert.class)
	@ColumnWidth(15)
    private Integer typeState;
	@ApiModelProperty(value = "配件编码")
	@ExcelProperty(value = "配件编码")
	@ColumnWidth(15)
	private String postionNumber;
	@ApiModelProperty(value = "配件名称")
	@ExcelProperty(value = "配件名称")
	@ColumnWidth(15)
	private String gname;
	@ApiModelProperty(value = "规格")
	@ExcelProperty(value = "规格")
	private String spec;
	@ApiModelProperty(value = "单位")
	@ExcelProperty(value = "单位")
	private String unit;
	@ApiModelProperty(value = "数量")
	@ExcelProperty(value = "数量")
	private BigDecimal numbers;
	@ApiModelProperty(value = "单价")
	@ExcelProperty(value = "单价")
	private BigDecimal cost;
	@ApiModelProperty(value = "金额")
	@ExcelProperty(value = "金额")
	private BigDecimal price;
	@ApiModelProperty(value = "供应商")
	@ExcelProperty(value = "供应商")
	private String ftname;
	@ApiModelProperty(value = "采购人")
	@ExcelProperty(value = "采购人")
	private String acUserName;
	@ApiModelProperty(value = "备注")
	@ExcelProperty(value = "备注")
	@ColumnWidth(30)
	private String des;
	public GoodsInExcel() {
	};
}

接口

    @ApiOperation(value = "导出",response = GoodsInExcel.class)
	@GetMapping("inPageExport")
	@Permit(permit = "inPageExport")
	public void inPageExport(HttpServletResponse response,GoodsRecordQuery data,String columns) throws Exception {
        //查询数据
		List<Object> list = recordsService.exportList(data);
        //设置自定义导出列
		Set<String> hashSet = new HashSet<>();
		if (columns != null) {
			hashSet.addAll(Arrays.asList(columns.split(",")));
		}
        //获取或者计算合计行数据
		BigDecimal reduce = list.stream().map(gr ->{return gr.getNumbers();}).reduce(BigDecimal.ZERO, BigDecimal::add);
		BigDecimal reduce1 = list.stream().map(gr ->{return gr.getPrice();}).reduce(BigDecimal.ZERO, BigDecimal::add);
		GoodsRecord hj = new GoodsRecord();
		hj.setPrice(reduce1);
		hj.setNumbers(reduce);
		hj.setOrderNo("合计");
        //加入到导出数据最后一行
		list.add(hj);
        //调用工具类导出接口
		ExcelUtils.exportExcelToTarget(response, "明细表", "明细", list, GoodsInExcel.class,hashSet);
	}

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

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

相关文章

GAN:DCGAN-深度卷积生成对抗网络

论文&#xff1a;https://arxiv.org/pdf/1511.06434.pdf 发表&#xff1a;ICLR 2016 一、架构创新 1&#xff1a;全卷积网络&#xff1a;用逐步卷积代替确定性的空间池化函数&#xff08;如maxpooling&#xff09;&#xff0c;使网络学习自己的空间下采样。使用这种方法&#…

【文献阅读笔记】关于GANomaly的异常检测方法

文章目录 1、GANomaly: Semi-Supervised Anomaly Detection via Adversarial Training模型主要创新 2、Skip-GANomaly: Skip Connected and AdversariallyTrained Encoder-Decoder Anomaly Detection模型主要创新点 3、Industrial surface defect detection and localization u…

15 网关实战: 微服务集成Swagger实现在线文档

上节介绍了网关层面聚合API文档,通过网关的路由信息找到了各个服务的请求地址,这节讲一下微服务如何集成Swagger。 网关的API文档默认调用的是微服务的**/v2/api-docs**这个接口获取API详细信息,比如文章服务的URL:http://localhost:9000/blog-article/v2/api-docs,返回信…

【DeepLearning.AI】吴恩达系列课程——使用Gradio构建AI应用

目录 前言一、Gradio介绍1-1、Gradio介绍1-2、安装1-3、小栗子 二、使用Gradio构建AI应用2-1、NLP任务2-1-1、文本摘要2-1-2、命名实体识别 2-2、聊天任务&#xff08;ChatYuan&#xff09;2-2-1、模型介绍2-2-2、模型下载、参数设置2-2-3、模型测试2-2-4、嵌入到Gradio里2-2-5…

leetcode:2864. 最大二进制奇数(python3解法)

难度&#xff1a;简单 给你一个 二进制 字符串 s &#xff0c;其中至少包含一个 1 。 你必须按某种方式 重新排列 字符串中的位&#xff0c;使得到的二进制数字是可以由该组合生成的 最大二进制奇数 。 以字符串形式&#xff0c;表示并返回可以由给定组合生成的最大二进制奇数。…

SVN代码回滚之Update item to thisversion和Revert to this version 区别

背景 在使用SVN管理代码时免不了进行代码的合并或者回退&#xff0c;本篇主要讲回退至某个版本的SVN操作。 内容 对目标代码右键查看log&#xff0c;选中某个你想回滚的版本&#xff0c;然后右键会看到如下图 假设log中已经有5个版本&#xff0c;分别为1&#xff0c;2&…

Phpstudy v8.0/8.1小皮升级Apache至最新,同时升级openssl版本httpd-2.4.58 apache 2.4.58

1.apache官网下载最新版本的apache 2.4.58 2.phpstudy下apache停止运行&#xff0c;把原来的Apache文件夹备份一份 复制图中的文件替换apache目录下文件 3.phpstudy中开启apache

用按层次顺序遍历二叉树的方法,设计算法统计树中度为1的结点数目

用按层次顺序遍历二叉树的方法&#xff0c;设计算法统计树中度为1的结点数目 代码思路&#xff1a; 层序遍历的实现需要借助一个辅助队列 首先将根结点入队&#xff0c;然后根出队&#xff0c;把根的两个子树入队 然后下面循环执行&#xff1a;队头元素出队&#xff0c;队头元…

手机文件怎么传到电脑?简单方法分享!

将手机文件传输到电脑可以将其备份&#xff0c;以防数据丢失或意外情况发生。并且电脑具有更强大的处理能力&#xff0c;可以将文件进行编辑、修改、转换等操作&#xff0c;大大提高了工作效率。那么&#xff0c;手机文件怎么传到电脑&#xff1f;本文将为大家提供简单易懂的解…

[SpringCloud] SpringCloud配置中心的核心原理

SpringCloud是什么时候去拉取配置中心的配置中心客户端的配置信息为什么要写在bootstrap文件中对象中注入的属性是如何动态刷新的一些开源的配置中心是如何整合SpringCloud的 文章目录 1.从SpringBoot的启动过程说起1.1 大致过程 2.准备Environment的核心操作2.1 前置操作 3.pr…

Redis 两种持久化方式 AOF 和 RDB

目录 一、Redis 的持久化 二、Redis 的持久化方式 RDB RDB 介绍 RDB 的触发方式&#xff1a;. 三、RDB的文件生成策略 四、Save 和 Bgsave 命令的区别 六、RDB 最佳配置 七、触发机制-不容忽略方式 AOF 一、AOF介绍 二、RDB所存在的问题 三、AOF 三种策略 四、AOF…

6.15合并二叉树(LC617-E)

算法&#xff1a; 前序、中序、后序都可以&#xff0c;这道题正常逻辑一般都是用前序 正确代码&#xff1a; 这里就是在root1这颗树上改的&#xff0c;也可以新建一个树。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode …

Long-Context下LLM模型架构全面介绍

深度学习自然语言处理 原创作者&#xff1a;cola 随着ChatGPT的快速发展&#xff0c;基于Transformer的大型语言模型(LLM)为人工通用智能(AGI)铺平了一条革命性的道路&#xff0c;并已应用于知识库、人机界面和动态代理等不同领域。然而&#xff0c;存在一个普遍的限制:当前许多…

「Verilog学习笔记」非整数倍数据位宽转换8to12

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 要实现8bit数据至12bit数据的位宽转换&#xff0c;必须要用寄存器将先到达的数据进行缓存。8bit数据至12bit数据&#xff0c;相当于1.5个输入数据拼接成一个输出数据&#…

【1】AR Tag 在ros中的使用

1.定义 AR Tag 是一种用于增强现实&#xff08;AR&#xff09;应用中的视觉标记&#xff0c;用于跟踪和定位虚拟物体在现实世界中的位置。 AR Tag由黑白正方形图像表示&#xff0c;图像内部有黑色边框中的某些图案。它与我们经常用到的二维码长得类似&#xff0c;原理其实也一…

动态规划专项---状态机模型

文章目录 大盗阿福股票买卖IV股票买卖V设计密码修复DNA 一、大盗阿福OJ链接 本题思路:状态表示当前第i家店铺选择偷或者不偷的最大利益。状态计算:f[i][0]std::max(f[i-1][0],f[i-1][1]);//如果第i家店铺被偷,则第i-1家店铺不能被偷&#xff0c;f[i][1]f[i-1][0]w[i]…

Django整合回顾

web应用 什么是web&#xff1a;通过web访问web应用程序&#xff0c;很方便&#xff0c;用户只需要一个浏览器即可。是典型的浏览器/服务器端架构的产物 cs架构与bs架构 应用程序有C/S B/S两种模式&#xff1a;b/s 本质上还是c/s mysql属于c/s架构&#xff0c;只是我们的服务…

Harmony OS4开发入门

项目目录介绍 ArkTS介绍 简单案例&#xff1a; State times: number 0State msg: string "hello"State a: any "hello"build() {Row() {Column() {Button(点我${this.times}次).backgroundColor("#360").onClick(() > {this.times}).wid…

歌手荆涛演唱的《春节回家》,一种情感的表达和文化的传承

歌手荆涛演唱的《春节回家》&#xff0c;一种情感的表达和文化的传承 春节回家&#xff0c;是中国传统文化中最为重要的传统节日之一&#xff0c;也是亿万华夏儿女最为期待的日子。每当春节临近&#xff0c;无论身在何处&#xff0c;人们都会收拾行囊&#xff0c;踏上归途&…

VScode集成python开发环境和基本插件下载配置

VSCode开发工具 下载VSCode VSCode官方首页&#xff1a;Visual Studio Code - Code Editing. Redefined 点击Download for Windows下载 安装过程一路下一步即可&#xff0c;其中建议勾选 将"通过Code打开"操作添加到Windows资源管理器目录上下文菜单方便我们直接通过…