通过easyexcel导入数据,添加表格参数的校验,同表格内校验以及和已有数据的校验

 引入依赖

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

需要导入到某个目录下

如果产品名称相同,就追加里面的型号,如果型号也相同就返回提示,

如果产品名称相同,表格内的数据要和浏览器录入的 型号对应参数保持一致,顺序、名称、数量等都要完全一致

如果产品名称相同,表格内部的 型号对应的参数必须保持一致,顺序、名称、数量等都要完全一致;

例如:

 导入的表格要个浏览器对应上

controller

	/**
	 * 导入设备
	 */
	@PostMapping("importProduct")
	@ApiOperationSupport(order = 11)
	@ApiOperation(value = "导入设备", notes = "传入excel/产品")
	public R importProduct(MultipartFile file, Long categoryId) throws IOException {
		//此处判断文件大小不能为0
		if (file.getSize() == 0) {
			return R.fail("文件大小不能为空");
		}
		if (categoryId == null || categoryId <= 0) {
			return R.fail("请选择所属产品分类");
		}
		return productService.importProduct(file, categoryId);
	}

services

	//导入产品
	@Override
	@Transactional(rollbackFor = Exception.class)
	public R importProduct(MultipartFile file, Long categoryId) throws IOException {
		CategoryEntity category = categoryService.getById(categoryId);
		if (category == null) {
			throw new ServiceException("产品分类不存在");
		}
		DataExcelListener<ProductImportExcel> listener = new DataExcelListener<ProductImportExcel>();
		// headRowNumber(2):表示第一、二行为表头,从第三行取值
		ExcelReader excelReader = EasyExcelFactory.read(file.getInputStream(), ProductImportExcel.class, listener).headRowNumber(2).build();
		excelReader.readAll();
		List<ProductImportExcel> data = listener.getDatas();
		excelReader.finish();
		Map<String, List<CodeProTypeJson>> map = new LinkedHashMap<>();
		//获取表格数据,根据表格每一行的列数量不同,获取数据后组装型号json
		getExcelData(data, map);
		// 转换数据并添加产品
		List<ProductEntity> productList = new ArrayList<>();
		//判断导入的产品名称和已有的产品名称是否相同,如果相同就追加型号
		List<String> productNameList = new ArrayList<>();
		for (Map.Entry<String, List<CodeProTypeJson>> listEntry : map.entrySet()) {
			String productName = listEntry.getKey();
			List<CodeProTypeJson> value = listEntry.getValue();
			ProductEntity product = new ProductEntity();
			product.setCategoryId(categoryId);
			product.setCodeProName(productName);
			product.setCodeProType(JSON.toJSONString(value));
			product.setCodeProTypeNum(value.size());
			product.setEnterpriseId(IotAuthUtil.getEnterpriseId());
			productNameList.add(productName);
			productList.add(product);
		}
		// 批量查询 已经存在的产品 存在就覆盖 不存在就新增
		if (productNameList != null && productNameList.size() > 0) {
			LambdaQueryWrapper<ProductEntity> queryWrapper = new LambdaQueryWrapper<>();
			queryWrapper.in(ProductEntity::getCodeProName, productNameList);
			List<ProductEntity> selectList = baseMapper.selectList(queryWrapper);
			List<ProductEntity> updateList = new ArrayList<>();
			List<ProductEntity> addList = new ArrayList<>();
			for (ProductEntity entity : productList) {
				// 判断产品是否已经添加,如已添加就走修改逻辑,未添加就走添加逻辑
				ProductEntity product = containsProductEntity(entity, selectList);
				if (product != null) {
					entity.setId(product.getId());
					updateList.add(entity);
				} else {
					addList.add(entity);
				}
				/*Long productId = containsProductEntity(entity, selectList);
				if (productId != null) {
					entity.setId(productId);
					updateList.add(entity);
				} else {
					addList.add(entity);
				}*/

			}
			// 批量更新
			if (updateList != null && updateList.size() > 0) {
				this.updateBatchById(updateList);
			}
			// 批量添加
			if (addList != null && addList.size() > 0) {
				this.saveBatch(addList);
			}
		}
		return R.success("导入成功!");
	}

 Excel导入数据 解析监听器 用于获取excel表格的数据

package com.bluebird.code.util;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.metadata.Cell;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Excel导入数据 解析监听器 用于获取excel表格的数据
 */
public class DataExcelListener<T> extends AnalysisEventListener<T> {
    /**
     * 自定义用于暂时存储data
     * 可以通过实例获取该值
     */
    private List<T> datas = new ArrayList<>();

    /**
     * 每解析一行都会回调invoke()方法
     *
     * @param object  读取后的数据对象
     * @param context 内容
     */
    @Override
    @SuppressWarnings("unchecked")
    public void invoke(Object object, AnalysisContext context) {
        T data = (T) object;
        //数据存储到list,供批量处理,判断每一行是否为空行。
		if (data != null && !isEmptyRow(context.readRowHolder().getCellMap())) {
			datas.add(data);
		}

    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //解析结束销毁不用的资源
        //注意不要调用datas.clear(),否则getDatas为null
    }

    /**
     * 返回数据
     *
     * @return 返回读取的数据集合
     **/
    public List<T> getDatas() {
        return datas;
    }

    /**
     * 设置读取的数据集合
     *
     * @param datas 设置读取的数据集合
     **/
    public void setDatas(List<T> datas) {
        this.datas = datas;
    }


	/**
	 * 判断一行是否为空行
	 * @param cellMap 当前行的单元格映射
	 * @return 如果所有单元格都为空,则返回 true,否则返回 false
	 */
	private boolean isEmptyRow(Map<Integer, Cell> cellMap) {
		for (Object cellValue : cellMap.values()) {
			if (cellValue != null && !cellValue.toString().trim().isEmpty()) {
				return false;
			}
		}
		return true;
	}

}

获取数据后组装型号json串 (同时处理表格内部相同产品名称不同型号参数名的问题,要确保相同参数名称的参数名保持一致)

// 获取数据后组装型号json串 (同时处理表格内部相同产品名称不同型号参数名的问题,要确保相同参数名称的参数名保持一致)
	public void getExcelData(List<ProductImportExcel> data, Map<String, List<CodeProTypeJson>> map) {
		int count = 2;
		// 判断产品名称和型号是否相等,如过相等就返回提示,产品名和型号组成合并后需要唯一
		Map<String, String> proNameTypeMap = new HashMap<>();
		// 定义一个map集合,key:产品名称,value:型号集合的名称拼接
		Map<String, String> mapProductType = new LinkedHashMap<>();
		for (ProductImportExcel entity : data) {
			count++;
			String productName = entity.getCodeProName();
			String codeProType = entity.getCodeProType();
			String proNameType = productName + codeProType;

			if (StringUtils.isBlank(productName) || StringUtils.isEmpty(productName)) {
				throw new ServiceException("第 " + count + " 行产品名称不能为空!");
			}
			if (StringUtils.isBlank(codeProType) || StringUtils.isEmpty(codeProType)) {
				throw new ServiceException("第 " + count + " 行规格型号不能为空!");
			}
			//
			String proNameTypeStr = proNameTypeMap.get(proNameType);
			if (StringUtils.isNotBlank(proNameTypeStr)) {
				throw new ServiceException("第 " + count + " 行和第 " + (count - 1) + "产品名称下的规格型号不能重复!");
			}
			proNameTypeMap.put(proNameType, proNameType);

			List<CodeProTypeJson> list = map.get(productName);
			CodeProTypeJson json = new CodeProTypeJson();

			List<CodeProTypeJson.SkuParamsList> listDate = new ArrayList<>();
			json.setSkuName(entity.getCodeProType());
			json.setSkuId(IdWorker.getIdStr());

			// 将参数名进行拼接
			StringBuilder paramSb = new StringBuilder();
			// 根据型号参数名字处理表格数据,如果此单元格为空就不处理(因为每个产品的型号数量不确定)
			if (StringUtils.isNotEmpty(entity.getParamName1())) {
				CodeProTypeJson.SkuParamsList skuParamsList = new CodeProTypeJson.SkuParamsList();
				skuParamsList.setParamId(IdWorker.getIdStr());
				skuParamsList.setParamName(entity.getParamName1());
				skuParamsList.setParamValue(entity.getParamValue1());
				listDate.add(skuParamsList);
				paramSb.append(entity.getParamName1());
			}
			// 根据型号参数名字处理表格数据,如果此单元格为空就不处理(因为每个产品的型号数量不确定)
			if (StringUtils.isNotEmpty(entity.getParamName2())) {
				CodeProTypeJson.SkuParamsList skuParamsList = new CodeProTypeJson.SkuParamsList();
				skuParamsList.setParamId(IdWorker.getIdStr());
				skuParamsList.setParamName(entity.getParamName2());
				skuParamsList.setParamValue(entity.getParamValue2());
				listDate.add(skuParamsList);
				paramSb.append("->");
				paramSb.append(entity.getParamName2());
			}
			// 根据型号参数名字处理表格数据,如果此单元格为空就不处理(因为每个产品的型号数量不确定)
			if (StringUtils.isNotEmpty(entity.getParamName3())) {
				CodeProTypeJson.SkuParamsList skuParamsList = new CodeProTypeJson.SkuParamsList();
				skuParamsList.setParamId(IdWorker.getIdStr());
				skuParamsList.setParamName(entity.getParamName3());
				skuParamsList.setParamValue(entity.getParamValue3());
				listDate.add(skuParamsList);
				paramSb.append("->");
				paramSb.append(entity.getParamName3());
			}
			// 根据型号参数名字处理表格数据,如果此单元格为空就不处理(因为每个产品的型号数量不确定)
			if (StringUtils.isNotEmpty(entity.getParamName4())) {
				CodeProTypeJson.SkuParamsList skuParamsList = new CodeProTypeJson.SkuParamsList();
				skuParamsList.setParamId(IdWorker.getIdStr());
				skuParamsList.setParamName(entity.getParamName4());
				skuParamsList.setParamValue(entity.getParamValue4());
				listDate.add(skuParamsList);
				paramSb.append("->");
				paramSb.append(entity.getParamName4());
			}

			// 根据型号参数名字处理表格数据,如果此单元格为空就不处理(因为每个产品的型号数量不确定)
			if (StringUtils.isNotEmpty(entity.getParamName5())) {
				CodeProTypeJson.SkuParamsList skuParamsList = new CodeProTypeJson.SkuParamsList();
				skuParamsList.setParamId(IdWorker.getIdStr());
				skuParamsList.setParamName(entity.getParamName5());
				skuParamsList.setParamValue(entity.getParamValue5());
				listDate.add(skuParamsList);
				paramSb.append("->");
				paramSb.append(entity.getParamName5());
			}
			// 根据型号参数名字处理表格数据,如果此单元格为空就不处理(因为每个产品的型号数量不确定)
			if (StringUtils.isNotEmpty(entity.getParamName6())) {
				CodeProTypeJson.SkuParamsList skuParamsList = new CodeProTypeJson.SkuParamsList();
				skuParamsList.setParamId(IdWorker.getIdStr());
				skuParamsList.setParamName(entity.getParamName6());
				skuParamsList.setParamValue(entity.getParamValue6());
				listDate.add(skuParamsList);
				paramSb.append("->");
				paramSb.append(entity.getParamName6());
			}
			// 根据型号参数名字处理表格数据,如果此单元格为空就不处理(因为每个产品的型号数量不确定)
			if (StringUtils.isNotEmpty(entity.getParamName7())) {
				CodeProTypeJson.SkuParamsList skuParamsList = new CodeProTypeJson.SkuParamsList();
				skuParamsList.setParamId(IdWorker.getIdStr());
				skuParamsList.setParamName(entity.getParamName7());
				skuParamsList.setParamValue(entity.getParamValue7());
				listDate.add(skuParamsList);
				paramSb.append("->");
				paramSb.append(entity.getParamName7());
			}
			// 根据型号参数名字处理表格数据,如果此单元格为空就不处理(因为每个产品的型号数量不确定)
			if (StringUtils.isNotEmpty(entity.getParamName8())) {
				CodeProTypeJson.SkuParamsList skuParamsList = new CodeProTypeJson.SkuParamsList();
				skuParamsList.setParamId(IdWorker.getIdStr());
				skuParamsList.setParamName(entity.getParamName8());
				skuParamsList.setParamValue(entity.getParamValue8());
				listDate.add(skuParamsList);
				paramSb.append("->");
				paramSb.append(entity.getParamName8());
			}
			// 将参数名拼接后转换字符串
			String paramSbStr = paramSb.toString();
			// 根据当前行的产品名称去map集合获取已经存入的参数名的拼接串
			String paramNameMap = mapProductType.get(productName);
			if (Func.isNotBlank( paramNameMap ) && !paramNameMap.equals( paramSbStr )) {
				String msg = "[ " + paramNameMap + " ] 和 [ " + paramSbStr + " ] 型号参数名称、数量、顺序需保持一致";
				throw new ServiceException(" 产品名称为:[ " + productName + " ] 的型号参数与表格其他行的参数名称或顺序不一致,请修改!</br>" + msg);
			}
			// 如果校验通过后添加参数拼接串到map集合中
			mapProductType.put(productName, paramSbStr);

			json.setSkuParamsList(listDate);
			if (list == null) {
				list = new ArrayList<>();
			}

			List<CodeProTypeJson> typeJsons = map.get(productName);
			if (typeJsons != null && typeJsons.size() > 0) {
				typeJsons.add(json);
				map.put(productName, typeJsons);
			} else {
				list.add(json);
				map.put(productName, list);
			}
		}
	}

判断产品是否已经添加,如已添加就走修改逻辑,未添加就走添加逻辑  excel:entity

	// 判断产品是否已经添加,如已添加就走修改逻辑,未添加就走添加逻辑  excel:entity
	private static ProductEntity containsProductEntity(ProductEntity entity, List<ProductEntity> selectList) {
		for (ProductEntity item : selectList) {
			if (item.getCodeProName().equals(entity.getCodeProName())) {
				// 如果导入的产品名称和已经添加的产品名称相同,就追加型号,如果型号相同,就返回提示
				List<CodeProTypeJson> itemTypeJsonList = JSONObject.parseArray(Func.toStr(item.getCodeProType()), CodeProTypeJson.class);
				List<CodeProTypeJson> excelTypeJsonList = JSONObject.parseArray(Func.toStr(entity.getCodeProType()), CodeProTypeJson.class);
				for (CodeProTypeJson itemJson : itemTypeJsonList) {
					for (CodeProTypeJson excelJson : excelTypeJsonList) {
						if (Objects.equals(itemJson.getSkuName(), excelJson.getSkuName())) {
							throw new ServiceException(" 产品名称为: " + item.getCodeProName() + " 的 " + itemJson.getSkuName() + " 型号已存在,请先修改该型号");
						}
					}
				}
				// 比较 如果导入的产品名称和数据库已有的数据产品名称相同,就比对型号的名称和顺序是否一致,如果不一致就返回提示
				if (itemTypeJsonList != null && itemTypeJsonList.size() > 0 && excelTypeJsonList != null && excelTypeJsonList.size() > 0) {
					// 获取查询到的第一个型号的参数列表
					CodeProTypeJson codeProTypeJson = itemTypeJsonList.get(0);
					List<CodeProTypeJson.SkuParamsList> itemSkuParamsList = codeProTypeJson.getSkuParamsList();
					// 将参数名进行拼接
					StringBuilder sbItem = new StringBuilder();
					for (int i = 0; i < itemSkuParamsList.size(); i++) {
						CodeProTypeJson.SkuParamsList param = itemSkuParamsList.get(i);
						sbItem.append(param.getParamName());
						if (i < itemSkuParamsList.size() - 1) {
							sbItem.append("->");
						}
					}
					String itemTypeJson = sbItem.toString();
					// 遍历excel表格里面的所有型号对应的参数列表
					for (CodeProTypeJson json : excelTypeJsonList) {
						List<CodeProTypeJson.SkuParamsList> skuParamsList = json.getSkuParamsList();
						// 遍历某个型号的所有参数名,将参数名进行拼接
						StringBuilder sbJson = new StringBuilder();
						for (int i = 0; i < skuParamsList.size(); i++) {
							CodeProTypeJson.SkuParamsList param = skuParamsList.get(i);
							sbJson.append(param.getParamName());
							if (i < skuParamsList.size() - 1) {
								sbJson.append("->");
							}
						}
						String excelTypeJson = sbJson.toString();
						System.out.println("itemTypeJson " + itemTypeJson);
						System.out.println("excelTypeJson " + excelTypeJson);
						System.out.println(itemTypeJson.equals(excelTypeJson));
						// 比对数据库查询的 拼接参数和excel表格里面的 拼接参数是否一致
						if (!itemTypeJson.equals(excelTypeJson)) {
							String msg = "原参数[ " + itemTypeJson + " ] 新参数 [ " + excelTypeJson + " ]";
							throw new ServiceException(" 产品名称为:[ " + item.getCodeProName() + " ]的型号参数与已有参数名称不一致或顺序不一致,请修改!</br>" + msg);
						}
					}
				}
				itemTypeJsonList.addAll(excelTypeJsonList);
				entity.setCodeProType(JSON.toJSONString(itemTypeJsonList));
				entity.setCodeProTypeNum(itemTypeJsonList.size());
				entity.setId(item.getId());
				return entity;
			}
		}
		return null;
	}

ProductEntity实体类

package com.bluebird.code.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import com.bluebird.core.tenant.mp.TenantEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 赋码 - 产品表 实体类 
 */
@Data
@TableName("t_code_product")
@ApiModel(value = "Product对象", description = "赋码 - 产品表")
@EqualsAndHashCode(callSuper = true)
public class ProductEntity extends TenantEntity {

	/**
	 * 企业id
	 */
	@ApiModelProperty(value = "企业id")
	private Long enterpriseId;
	/**
	 * 产品名称
	 */
	@ApiModelProperty(value = "产品名称")
	private String codeProName;
	/**
	 * 产品编号
	 */
	@ApiModelProperty(value = "产品编号")
	private String codeProNum;
	/**
	 * 产品分类
	 */
	@ApiModelProperty(value = "产品分类")
	private Long categoryId;
	/**
	 * 产品图片
	 */
	@ApiModelProperty(value = "产品图片")
	private String codeProImage;

	/**
	 * 产品主图图片
	 */
	@ApiModelProperty(value = "产品主图图片")
	private String codeMainImage;


	/**
	 * 产品视频
	 */
	@ApiModelProperty(value = "产品视频")
	private String codeProVideo;
	/**
	 * 产品型号(第一组元素必须为规格型号)
	 *
	 * @see com.bluebird.code.dto.CodeProTypeJson
	 */
	@ApiModelProperty(value = "产品型号(第一组元素必须为规格型号)")
//	private CodeProTypeJson codeProType;
	private String codeProType;
	/**
	 * 产品简介
	 */
	@ApiModelProperty(value = "产品简介")
	private String codeProDesc;
	/**
	 * 规格数量
	 */
	@ApiModelProperty(value = "规格数量")
	private Integer codeProTypeNum;
	/**
	 * 排序
	 */
	@ApiModelProperty(value = "排序")
	private Integer sort;
	/**
	 * 备注
	 */
	@ApiModelProperty(value = "备注")
	private String remark;

}

CodeProTypeJson 产品型号Json对象 (第一组元素必须为规格型号)

package com.bluebird.code.dto;

import lombok.Data;

import java.util.List;

/***
 * 产品型号Json对象 (第一组元素必须为规格型号)
 *
 *
 * @return:
 * @date: 2024/6/20
 */
@Data
public class CodeProTypeJson {

	//产品id
	private String skuId;

	//产品型号
	private String skuName;

	//规格英文名称
	private String skuEnName;

	//产品规格参数List
	private List<SkuParamsList> skuParamsList;

	@Data
	public static class SkuParamsList {
		//规格id
		private String paramId;
		//规格名称
		private String paramName;
		//规格英文名称
		private String paramEnName;
		//规格参数值
		private String paramValue;
	}
}

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

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

相关文章

这玩意终于有免费的了———Navicat Premium Lite

免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 去下载吧&…

基于Teager-Kaiser能量算子的肌电信号降噪方法(MATLAB)

Teager-Kaiser能量算子是一种非线性算子&#xff0c;它能有效提取信号的瞬时能量&#xff0c;对信号瞬时变化具有良好的时间分辨率。Teager-Kaiser能量算子只需信号三个采样点&#xff0c;即可快速跟踪信号的幅值和角频率变化&#xff0c;计算实现简单、运算量小。 clc clear a…

【 香橙派 AIpro评测】大语言模型实战教程:香橙派 AIpro部署LLMS大模型实站(保姆级教学)

引言 OrangePi AIpro 这块板子作为业界首款基于昇腾深度研发的AI开发板&#xff0c;一经发布本博主就火速去关注了&#xff0c;其配备的 8/20TOPS澎湃算力是目前开发板市场中所具备的最大算力&#xff0c;可谓是让我非常眼馋啊&#xff01;这么好的板子那必须拿来用用&#xff…

WPF 3D绘图 点云 系列五

基本概念:点云是某个坐标系下的点的数据集。 可能包含丰富的信息,包括三维坐标X,Y,Z、颜色、分类值、强度值、时间等等 点云可以将现实世界原子化,通过高精度的点云数据可以还原现实世界。万物皆点云。 通过三维激光扫描仪进行数据采集获取点云数据,其次通过二维影像进行…

初次使用GitHub教程入门

注册一个github账户 访问地址&#xff1a;https://github.com/&#xff0c;点击右上角sign up&#xff0c;录入以下信息&#xff0c;邮箱&#xff0c;密码&#xff0c;账号&#xff0c;会有邮箱验证&#xff0c;跟着步骤来就好了 配置 本机上设置你的github的邮箱和用户名 …

R语言学习,入门

我是一名6年开发经验的程序员&#xff0c;后端&#xff0c;大数据&#xff0c;前端都会。 现在加入了医疗行业&#xff0c;要做数据分析&#xff0c;前同事的实验室生信专业的&#xff0c;用的是R语言&#xff0c;为了跑通他的程序。就来学一下吧&#xff0c;看了一下好像挺简…

农村生活污水处理监测系统解决方案

一、概述 随着国民经济的发展和农村生活水平的提高&#xff0c;农村生活用水量越来越大&#xff0c;随之而来的污水产量也越来越大&#xff0c;农村生活污染对环境的压力越来越明显。环境保护意识的逐渐增强&#xff0c;使得人们对青山绿水的希望更为迫切&#xff0c;为满足人民…

Nordic 52832作为HID 键盘连接配对电视/投影后控制没反应问题的分析和解决

问题现象&#xff1a;我们的一款HID键盘硬件一直都工作的很好&#xff0c;连接配对后使用起来和原装键盘效果差不多&#xff0c;但是后面陆续有用户反馈家里的电视等蓝牙设备配对连接我们的键盘后&#xff0c;虽然显示已连接&#xff0c;但实际上控制不了。设备涉及到了好些品牌…

【操作与配置】VSCode配置Python及Jupyter

Python环境配置 可以参见&#xff1a;【操作与配置】Python&#xff1a;CondaPycharm_pycharmconda-CSDN博客 官网下载Python&#xff1a;http://www.python.org/download/官网下载Conda&#xff1a;Miniconda — Anaconda documentation VSCode插件安装 插件安装后需重启V…

layui-表格

1.使用方法 加上table标签 加上classlayui-table colgroup是列属性 tr是行td是列 thead是表头&#xff0c;后面一一对应 2.基础属性 加lay-even逐行换色 加lay-skin 设置边框风格

竞赛 深度学习+opencv+python实现昆虫识别 -图像识别 昆虫识别

文章目录 0 前言1 课题背景2 具体实现3 数据收集和处理3 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数&#xff1a;2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 4 MobileNetV2网络5 损失函数softmax 交叉熵5.1 softmax函数5.2 交叉熵损失函数 6 优化器SGD7 学…

企业多存储方式如何兼顾安全统一管理、便捷流畅访问的双向需求?

数据和文件存储是企业最基础的需求&#xff0c;常见的存储方式有磁盘存储、NAS存储、SAN存储、云存储、分布式存储、闪存存储等&#xff1b;随着企业规模的扩大、业务结构的复杂化&#xff0c;企业内部可能会同时出现多种存储方式、多个存储设备并行使用的情况。 这样的使用场景…

Ubuntu24.04(22.04+版本通用)Miniconda与Isaacgym

1. ubuntu24.04安装minicondda mkdir -p ~/miniconda3 wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh解释下这段代码 bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3~/miniconda3/miniconda.sh: 指向Mi…

Meta 发布 Meta 3D Gen 文本生成3D模型

Meta推出了 Meta 3D Gen &#xff08;3DGen&#xff09;&#xff0c;这是一种用于文本到 3D 资产生成的最先进的快速管道。3DGen 可在一分钟内提供具有高提示保真度和高质量 3D 形状和纹理的 3D 资产创建。 它支持基于物理的渲染 &#xff08;PBR&#xff09;&#xff0c;这是…

【笔记】强化学习,gym的命令行图形化界面适配

搞了一大堆还是搞不出来放弃了 最后用matplotlib画出来看 import gym import matplotlib.pyplot as plt from IPython import display import numpy as np %matplotlib inlineenv gym.make(CartPole-v1, render_mode"rgb_array") observation env.reset() a 0 f…

新手教学系列——使用uWSGI对Flask应用提速

在构建和部署Flask应用时,性能和稳定性是两个关键的因素。为了提升Flask应用的性能,我们可以借助uWSGI这个强大的工具。本文将详细介绍为什么要使用uWSGI、uWSGI的底层原理,并提供一个实例配置,帮助你更好地理解和应用这个工具。 为什么要使用uWSGI uWSGI 是一个应用服务…

CentOS 7.9 快速更换 阿里云源教程

CentOS 7.9 更换源教程 总结 # 下载 wget yum -y install wget # 备份 yum 源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak # 下载阿里云的yum源到 /etc/yum.repos.d/ # 此处以 CentOS 7 为例&#xff0c;如果是其它版本或者系统的话&#…

微软工具合集 -- Microsoft PowerToys v0.82.0

软件简介 PowerToys是由微软开发的一款免费系统工具集&#xff0c;专为Windows 10和Windows 11系统设计。它提供了一系列高效实用的工具&#xff0c;旨在帮助用户提升操作系统的使用效率和个性化程度。PowerToys工具集深受系统管理员和高级用户的喜爱&#xff0c;通过集成多种…

Laravel介绍与学习入门

Laravel 是一款优雅且功能强大的 PHP Web 开发框架&#xff0c;它被广泛认为是 PHP 领域内构建现代 Web 应用程序的最佳选择之一。Laravel 提供了一套简洁、富有表现力的语法&#xff0c;使得开发者能够高效地编写清晰、可维护的代码。以下是 Laravel 的一些关键特点和入门概念…

Java线程同步的特征和安全类型

一线程同步的特征 ◆不同的线程在执行以同一个对象作为锁标记的同步代码块或同步方法时&#xff0c;因为要获得这个对象的锁而相互牵制&#xff0c;多个并发线程访问同一资源的同步代码块或同步方法时。 ◆同一时刻只能有一个线程进入synchronized(this)同步代码块。 ◆当一个…