EasyExcel 动态设置表格的背景颜色和排列

        项目中使用EasyExcel把数据以excel格式导出,其中设置某一行、某一列单元格的背景颜色、排列方式十分常用,记录下来方便以后查阅。

1. 导入maven依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.1.0</version><scope>compile</scope>
</dependency>

2. 导出字段实体类:

@Data
@NoArgsConstructor
@Accessors(chain = true)
public class AchievementParamExcelDto {/*** 字段是动态配置的,配置哪些显示哪些*/@ExcelProperty(value = "产品类别", converter = NullConverter.class)@AchievementParam("0001001")private String type;@ExcelProperty(value = "商品名称(开票名称)", converter = NullConverter.class)@AchievementParam("0001002")private String commodityName;@ExcelProperty(value = "品牌", converter = NullConverter.class)@AchievementParam("0001003")private String brand;@ExcelProperty(value = "型号", converter = NullConverter.class)@AchievementParam("0001004")private String model;@ExcelProperty(value = "技术规格", converter = NullConverter.class)@AchievementParam("0001005")private String technicalSpecifications;@ExcelProperty(value = "单位", converter = NullConverter.class)@AchievementParam("0001006")private String unit;@ExcelProperty(value = "数量", converter = IntegerNumberConverter.class)@AchievementParam("0001007")private Integer num;@ExcelProperty(value = "单价", converter = IntegerNumberConverter.class)@AchievementParam("0001008")private BigDecimal unitPrice;@ExcelProperty(value = "小计(元)", converter = IntegerNumberConverter.class)@AchievementParam("0001009")@NumberFormat("#.00")private BigDecimal subtotal;@ExcelProperty(value = "物料代码", converter = NullConverter.class)@AchievementParam("0001010")private String materialCode;@ExcelProperty("备注")@AchievementParam("0001011")private String remark;@ExcelProperty(value = "序号", converter = IntegerNumberConverter.class)@AchievementParam("0001012")private Integer index;@ExcelProperty(value = "销售项名称", converter = NullConverter.class)@AchievementParam("0001013")private String name;@ExcelProperty(value = "销售项编码", converter = NullConverter.class)@AchievementParam("0001014")private String itemCode;public AchievementParamExcelDto(int index, AchievementVo vo, String remark) {this.index = index;this.name = handleNull(vo.getName());this.type = handleNull(vo.getType());this.commodityName = handleNull(vo.getCommodityName());this.brand = handleNull(vo.getBrand());this.model = handleNull(vo.getModel());this.technicalSpecifications = handleNull(vo.getTechnicalSpecifications());this.unit = handleNull(vo.getUnit());this.num = StringUtils.isEmpty(vo.getNum()) ? 0: Integer.parseInt(vo.getNum());this.unitPrice = vo.getUnitPrice();this.subtotal = vo.getSubtotal();this.materialCode = StringUtils.isEmpty(vo.getMaterialCode()) ? "无固定物料" : vo.getMaterialCode();this.remark = remark;this.itemCode = StringUtils.isEmpty(vo.getItemCode()) ? (StringUtils.isEmpty(vo.getMaterialCode()) ? "— —" : vo.getMaterialCode()) : vo.getItemCode();}private String handleNull(String str) {return StringUtils.isEmpty(str) ? "— —" : str;}
}

3. 数据导出业务,并在业务中实现动态设置背景颜色和排列方式:

private void doDownloadAchievementExcelFile(List<AchievementsExportParamEntity> achievementExportParam,List<AchievementParamExcelDto> result, HttpServletResponse response, String fileName) {if (CollectionUtils.isEmpty(achievementExportParam)) {return;}// excel表头List<List<String>> header = new ArrayList<>();// 需要导出的数据字段List<String> includeColumnFiledNames = new ArrayList<>();// 导出实体类中所有的字段Field[] fields = ReflectUtil.getFields(AchievementParamExcelDto.class);achievementExportParam.sort(Comparator.comparing(AchievementsExportParamEntity::getSort));// 通过配置导出的字段来动态设置表头和行字段数据for (AchievementsExportParamEntity achievementsExportParamEntity : achievementExportParam) {String paramCode = achievementsExportParamEntity.getParamCode();//设置需要导出的头、行字段for (Field field : fields) {AchievementParam annotation = field.getAnnotation(AchievementParam.class);if (annotation == null) {continue;}if (StringUtils.equals(paramCode, annotation.value())) { // 判断字段是否有配置导出header.add(Lists.newArrayList(achievementsExportParamEntity.getParamName())); // 添加头数据includeColumnFiledNames.add(field.getName()); // 添加需要导出的行字段数据break;}}}/******************下面是设置背景颜色和排列方式的关键代码******************/// 按类型进行设置背景颜色Map<Integer, Short> rowBackColor = new HashMap<>();for (int i = 0; i < result.size(); i++) {AchievementParamExcelDto achievementParamExcelDto = result.get(i);String remark = achievementParamExcelDto.getRemark();if ("软件".equals(remark)) {// 表格的行索引从1开始,列索引从0开始rowBackColor.put(i + 1, IndexedColors.LEMON_CHIFFON.index);} else if ("硬件".equals(remark)) {rowBackColor.put(i + 1, IndexedColors.LIGHT_TURQUOISE.index);} else if ("模型".equals(remark)) {rowBackColor.put(i + 1, IndexedColors.LIGHT_GREEN.index);}else if ("实施服务".equals(remark)) {rowBackColor.put(i + 1, IndexedColors.LIGHT_CORNFLOWER_BLUE.index);}}// 导出时技术规格居左显示,其它剧中显示Map<Integer, HorizontalAlignment> horizontalAlignmentMap = new HashMap<>();for (int i = 0; i < header.size(); i++) {if ("技术规格".equals(header.get(i).get(0))) {horizontalAlignmentMap.put(i, HorizontalAlignment.LEFT);} else {horizontalAlignmentMap.put(i, HorizontalAlignment.CENTER);}}try {Class<? extends AchievementParamExcelDto> aClass = AchievementParamExcelDto.class;// 设置字段顺序Set<String> orderColumn = new LinkedHashSet<>(includeColumnFiledNames);for (Field field : fields) {orderColumn.add(field.getName());}setExcelIndex(aClass, new ArrayList<>(orderColumn));response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");response.setCharacterEncoding("utf-8");fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");EasyExcel.write(response.getOutputStream(), aClass).registerWriteHandler(new CustomCellWriteHandler(rowBackColor, horizontalAlignmentMap)).registerWriteHandler(new WidthWriteHandler()).sheet("成果物清单").head(header).includeColumnFieldNames(includeColumnFiledNames).doWrite(result);} catch (Exception e) {log.error("download error", e);throw new BusinessException(ErrorCodes.FILE_DOWNLOAD_ERROR);}}

4. 在自定义样式的handle中根据配置数据动态显示样式:

public class CustomCellWriteHandler implements CellWriteHandler {// 一个表格最多创建6W个样式,把每行的背景色放到集合中,统一设置,避免设置失败Map<Integer, Short> rowBackColor = new HashMap<>();// 排列样式集合Map<Integer, HorizontalAlignment> horizontalAlignmentMap = new HashMap<>();public CustomCellWriteHandler() {}public CustomCellWriteHandler(Map<Integer, Short> rowBackColor, Map<Integer, HorizontalAlignment> horizontalAlignmentMap) {this.rowBackColor = rowBackColor;this.horizontalAlignmentMap = horizontalAlignmentMap;}@Overridepublic void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {// 设置行高short height = 600;row.setHeight(height);}@Overridepublic void afterCellDispose(CellWriteHandlerContext context) {Cell cell = context.getCell();// 当前事件会在 数据设置到poi的cell里面才会回调// 判断不是头的情况 如果是fill 的情况 这里会==null 所以用not trueif (!BooleanUtils.isNotTrue(context.getHead())) { // 表头Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();CellStyle cellStyle = workbook.createCellStyle();// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUNDcellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 颜色// 设置rgb颜色byte[] rgb = new byte[]{(byte) 192, 0, 0};XSSFCellStyle xssfCellColorStyle = (XSSFCellStyle) cellStyle;xssfCellColorStyle.setFillForegroundColor(new XSSFColor(rgb, null));xssfCellColorStyle.setAlignment(HorizontalAlignment.CENTER);xssfCellColorStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 宽度// 边框xssfCellColorStyle.setBorderBottom(BorderStyle.THIN);xssfCellColorStyle.setBorderLeft(BorderStyle.THIN);xssfCellColorStyle.setBorderRight(BorderStyle.THIN);xssfCellColorStyle.setBorderTop(BorderStyle.THIN);// 字体Font font = workbook.createFont();font.setBold(true);font.setFontHeightInPoints((short) 11);font.setFontName("微软雅黑");font.setColor(IndexedColors.WHITE.getIndex());xssfCellColorStyle.setFont(font);cell.setCellStyle(xssfCellColorStyle);context.getFirstCellData().setWriteCellStyle(null);} else { // 单元格// 拿到poi的workbookWorkbook workbook = context.getWriteWorkbookHolder().getWorkbook();// 不同单元格尽量传同一个 cellStyleCellStyle cellStyle = workbook.createCellStyle();/***************下面是关键代码,根据表格的行号和列号与设置的数据进行匹配后动态设置***********/// 行号-重要***Integer rowIndex = context.getRowIndex();// 如果设置了每行的样式,动态设置;没有设置则统一设置为白色背景if (null != rowBackColor.get(rowIndex)) {// 拿到设置的颜色Short colorIndex = rowBackColor.get(rowIndex);cellStyle.setFillForegroundColor(colorIndex);} else {// 默认背景颜色cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());}// 列号-重要***Integer columnIndex = context.getColumnIndex();// 技术规格左对齐,其它剧中对齐if (null != horizontalAlignmentMap.get(columnIndex)) {cellStyle.setAlignment(horizontalAlignmentMap.get(columnIndex));} else {cellStyle.setAlignment(HorizontalAlignment.CENTER);}// 垂直居中cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 边框cellStyle.setBorderBottom(BorderStyle.THIN);cellStyle.setBorderLeft(BorderStyle.THIN);cellStyle.setBorderRight(BorderStyle.THIN);cellStyle.setBorderTop(BorderStyle.THIN);// 字体Font font = workbook.createFont();font.setFontHeightInPoints((short) 8);font.setFontName("微软雅黑");cellStyle.setFont(font);// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUNDcellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);cell.setCellStyle(cellStyle);// 由于这里没有指定dataformat 最后展示的数据 格式可能会不太正确// 这里要把 WriteCellData的样式清空, 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到// cell里面去 会导致自己设置的不一样(很关键)context.getFirstCellData().setWriteCellStyle(null);}}
}

5. 至此,主要的代码实现完了,实现的效果:

 

在第3步中,有涉及到几个方法或实体类,这里对应给出补充:

①入参result,是上一步从数据库中查询并封装后的数据,大致如下:

List<AchievementParamExcelDto> result = new ArrayList<>();
int index = 1;
for (AchievementVo achievementVo : distAchievementDto.getSaleList()) {result.add(new AchievementParamExcelDto(index++, achievementVo, localeMessage.getMessage(LanguageCn.PRODUCT_TYPE_SOFTWARE)));
}
for (AchievementVo achievementVo : distAchievementDto.getHardwareList()) {if (achievementVo.getSubtotal() != null && achievementVo.getSubtotal().compareTo(BigDecimal.ZERO) > 0) { // 只导出小计大于0的数据result.add(new AchievementParamExcelDto(index++, achievementVo, localeMessage.getMessage(LanguageCn.PRODUCT_TYPE_HARDWARE)));}
}
for (AchievementVo achievementVo : distAchievementDto.getModelList()) {result.add(new AchievementParamExcelDto(index++, achievementVo, localeMessage.getMessage(LanguageCn.PRODUCT_TYPE_MODEL)));
}
for (AchievementVo achievementVo : distAchievementDto.getServiceList()) {result.add(new AchievementParamExcelDto(index++, achievementVo, localeMessage.getMessage(LanguageCn.PRODUCT_TYPE_SERVICE)));
}

 distAchievementDto对应的数据结构如下(AchievementVo便是业务中数据实体类了,可参考效果图中的字段):

@Data
@NoArgsConstructor
@AllArgsConstructor
public class DistAchievementDto implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "软件销售清单", example = "[]")private List<AchievementVo> saleList = new ArrayList<>();@ApiModelProperty(value = "实施服务销售清单", example = "[]")private List<AchievementVo> serviceList = new ArrayList<>();@ApiModelProperty(value = "硬件销售清单", example = "[]")private List<AchievementVo> hardwareList = new ArrayList<>();@ApiModelProperty(value = "模型清单", example = "[]")private List<AchievementVo> modelList = new ArrayList<>();
}

② 入参 achievementExportParam 是从数据库中查出的配置导出的字段:

@EqualsAndHashCode(callSuper = true)
@Data
public class AchievementsExportParamEntity extends AbstractEntity implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty("导出类别:1-SPS;2-供方案使用;5-海外版本")private Integer exportType;@ApiModelProperty("导出字段编码")private String paramCode;@ApiModelProperty("导出字段名称")private String paramName;@ApiModelProperty("是否选中:0-否 1-是 默认值是0")private String paramSelected;@ApiModelProperty("导出顺序")private Integer sort;
}

 ③ 排序方法 setExcelIndex

@SuppressWarnings("unchecked")
private synchronized void setExcelIndex(Class<?> aClass, List<String> columnNames) throws NoSuchFieldException, IllegalAccessException {//获取当前对象的字段ArrayList<Field> fields = Lists.newArrayList(aClass.getDeclaredFields());Class<?> superclass = aClass.getSuperclass();if (superclass != null) {//有父类则获取父类对象的字段fields.addAll(Lists.newArrayList(superclass.getDeclaredFields()));}for (int i = 0; i < columnNames.size(); i++) {for (Field field : fields) {if (!field.getName().equals(columnNames.get(i))) continue;ExcelProperty annotation = field.getAnnotation(ExcelProperty.class);if (annotation == null) continue;InvocationHandler handler = Proxy.getInvocationHandler(annotation);//获取 AnnotationInvocationHandler 的 memberValues 字段Field fieldMv = handler.getClass().getDeclaredField("memberValues");//因为这个字段是 private final 修饰,所以要打开权限fieldMv.setAccessible(true);Map<Object, Object> memberValues = (Map<Object, Object>) fieldMv.get(handler);if (!memberValues.containsKey("value")) continue;memberValues.put("index", i);}}
}

④ 自定义单元格宽度样式 WidthWriteHandler

public class WidthWriteHandler extends AbstractColumnWidthStyleStrategy {private final Map<String, Integer> map = new ImmutableMap.Builder<String, Integer>().put("序号", 9).put("名称", 18).put("产品类别", 32).put("商品名称(开票名称)", 22).put("品牌", 10).put("型号", 25).put("技术规格", 30).put("单位", 9).put("数量", 9).put("单价(元)", 9).put("小计(元)", 9).put("单价(美元)", 9).put("小计(美元)", 9).put("物料代码", 12).put("成果物类别", 11).put("销售项编码", 12).build();@Overrideprotected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell,Head head, Integer relativeRowIndex, Boolean isHead) {if (isHead) {String stringCellValue = cell.getStringCellValue();Integer integer = map.get(stringCellValue.trim());if (null == integer) {integer = 18;}Sheet sheet = writeSheetHolder.getSheet();int columnIndex = cell.getColumnIndex();// 列宽40sheet.setColumnWidth(columnIndex, integer * 256);}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AccessClient在苹果电脑闪退,解决方法

AccessClient 2 年前突然闪退了&#xff0c;一直没管&#xff0c;最近弄一个 electron打包&#xff0c;一直提示找不到 python&#xff0c;解决了 python 解释器后&#xff0c;顺手把AccessClient闪退解决了&#xff0c;解决思路如下&#xff1a; 1.在AccessClient点击鼠标右…

NVM:安装配置使用(详细教程)

文章目录 一、简介二、安装 nvm三、配置 nvm 镜像四、配置环境变量五、使用教程5.1 常用命令5.2 具体案例 六、结语 一、简介 在实际的开发和学习中可能会遇到不同项目的 node 版本不同&#xff0c;而出现的兼容性问题。 而 nvm 就可以很好的解决这个问题&#xff0c;它可以在…

ActiveMQ 反序列化漏洞CVE-2015-5254复现

文章目录 一、产生原因二、利用条件三、利用过程四、PoC&#xff08;概念验证&#xff09;五、poc环境验证使用find搜索vulhub已安装目录打开activeMQ组件查看配置文件端口启动镜像-文件配置好后对于Docker 镜像下载问题及解决办法设置好镜像源地址&#xff0c;进行重启docker查…

【Python】【数据分析】深入探索 Python 数据可视化:Seaborn 可视化库详解

目录 引言一、Seaborn 简介二、安装 Seaborn三、Seaborn 的基本图形3.1 散点图&#xff08;Scatter Plot&#xff09;3.2 线图&#xff08;Line Plot&#xff09;3.3 条形图&#xff08;Bar Plot&#xff09;3.4 箱型图&#xff08;Box Plot&#xff09;3.5 小提琴图&#xff0…

某药业数据中心与重工集团灾备中心SAP监测实战应用

在当今数字化转型的浪潮中&#xff0c;企业的IT系统承载着前所未有的业务压力。作为业务运营的核心支撑&#xff0c;SAP系统的稳定性和性能优化成为运维团队关注的重点。本文将结合两个实际案例——某药业集团数据中心&#xff08;以下简称“药业数据中心”&#xff09;与某重工…

Qt编译MySQL数据库驱动

目录 Qt编译MySQL数据库驱动 测试程序 Qt编译MySQL数据库驱动 &#xff08;1&#xff09;先找到MySQL安装路径以及Qt安装路径 C:\Program Files\MySQL\MySQL Server 8.0 D:\qt\5.12.12 &#xff08;2&#xff09;在D:\qt\5.12.12\Src\qtbase\src\plugins\sqldrivers\mysql下…

开发布局总结

线性布局 (Row/Column) 概述&#xff1a; 线性容器Row和Column构建。线性布局是其他布局的基础&#xff0c;其子元素在线性方向上&#xff08;水平方向和垂直方向&#xff09;依次排列。线性布局的排列方向由所选容器组件决定&#xff0c;Column容器内子元素按照垂直方向排列…

网络数据包分析

Target 实践内容&#xff1a;使用 Wireshark 捕获和分析网络流量。 涉及知识点&#xff1a;Wireshark 基本使用、数据包结构、理解网络协议分析、网络流量分析。 Trial Wireshark使用WinPCAP作为接口&#xff0c;直接与网卡进行数据报文交换。 Wireshark基本使用 勾选 WLA…

游戏引擎学习第45天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾 我们刚刚开始研究运动方程&#xff0c;展示了如何处理当人物遇到障碍物时的情况。有一种版本是角色会从障碍物上反弹&#xff0c;而另一版本是角色会完全停下来。这种方式感觉不太自然&#xff0c;因为在游戏中&#xff0c;…

微知-C语言如何指定弱符号?(#define WEAK __attribute__((weak)); WEAK int foo(void))

背景 在C语言中&#xff0c;弱符号是一种特殊的符号&#xff0c;它可以被重定义&#xff0c;但在链接时&#xff0c;只会使用被重定义的符号。 在某些情况下&#xff0c;我们需要在多个文件中定义相同的函数&#xff0c;但只使用其中一个函数。本文将介绍如何在C语言中实现弱符…

windos系统安装-mysql 5.7 zip压缩包教程

一, 安装包下载 在mysql官网上下载mysql5.7版本的压缩包 官方网址: https://dev.mysql.com/downloads/mysql/5.7.html#downloads选择历史版本 选择系统和数据库版本下载 下载完成后解压到安装的目录 二, 新增数据目录,配置文件, 配置环境变量 新建data文件夹用于存放数据库…

Tengine 搭建手册

简介 官网&#xff1a; tengine.taobao.org/ Tengine是由[淘宝](http://en.wikipedia.org/wiki/Taobao)发起的Web服务器项目。它在[Nginx](https://nginx.org/)的基础上&#xff0c;针对大访问量网站的需求&#xff0c;添加了很多高级功能和特性。Tengine的性能和稳定性已经在…

MybatisPlus-配置加密

配置加密 目前配置文件中的很多参数都是明文&#xff0c;如果开发人员发生流动&#xff0c;很容易导致敏感信息的泄露。所以MybatisPlus支持配置文件的加密和解密功能。 我们以数据库的用户名和密码为例。 生成秘钥 首先&#xff0c;我们利用AES工具生成一个随机秘钥&#…

【机器学习(五)】分类和回归任务-AdaBoost算法-Sentosa_DSML社区版 (2)11

文章目录 一、算法概念11一、算法原理&#xff08;一&#xff09;分类算法基本思路1、训练集和权重初始化2、弱分类器的加权误差3、弱分类器的权重4、Adaboost 分类损失函数5、样本权重更新6、AdaBoost 的强分类器 &#xff08;二&#xff09;回归算法基本思路1、最大误差的计算…

前端入门之VUE--ajax、vuex、router,最后的前端总结

前言 VUE是前端用的最多的框架&#xff1b;这篇文章是本人大一上学习前端的笔记&#xff1b;欢迎点赞 收藏 关注&#xff0c;本人将会持续更新。本人不是学前端的&#xff0c;这个是大一的时候上学的和做的笔记&#xff0c;那个时候学的也蒙&#xff0c;故这里对前端做一个总…

GB28181系列三:GB28181流媒体服务器ZLMediaKit

我的音视频/流媒体开源项目(github) GB28181系列目录 目录 一、ZLMediaKit介绍 二、 ZLMediaKit安装、运行(Ubuntu) 1、安装 2、运行 3、配置 三、ZLMediaKit使用 一、ZLMediaKit介绍 ZLMediaKit是一个基于C11的高性能运营级流媒体服务框架&#xff0c;项目地址&#xf…

人工智能增强的音频和聊天协作服务

论文标题&#xff1a;AI-enabled Audio and Chat Collaboration Services 中文标题&#xff1a;人工智能增强的音频和聊天协作服务 作者信息&#xff1a; Emil P. Andersen, Norwegian Defence Research Establishment (FFI), Kjeller, NorwayJesper R. Goksr, Sindre E. Ha…

构建树莓派温湿度监测系统:从硬件到软件的完整指南

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

企业内训|阅读行业产品运营实战训练营-某运营商数字娱乐公司

近日&#xff0c;TsingtaoAI公司为某运营商旗下数字娱乐公司组织的“阅读行业产品运营实战训练营”在杭州落下帷幕。此次训练营由TsingtaoAI资深互联网产品专家程靖主持。该公司的业务骨干——来自内容、市场、业务、产品与技术等跨部门核心岗位、拥有8-10年实战经验的中坚力量…

vue+node+mysql8.0,详细步骤及报错解决方案

1.下载需要安装的插件 下载express npm install express下载cors&#xff0c;用于处理接口跨域问题 npm install cors下载mysql npm install mysql 2.配置服务器 可以在vue项目的src同级创建server文件夹&#xff08;这里的位置可随意选择&#xff09; 然后依次创建&#…