自定义注解+反射在excel导入时获取字典表字段对应的值

1 篇文章 0 订阅
1 篇文章 0 订阅
该博客介绍了如何通过自定义注解和反射技术来优化Excel数据导入过程,避免重复代码。在实体类中使用注解指定字典表字段,然后通过反射获取这些注解,查询字典表并映射到相应字段。同时,强调了查询字典表接口需缓存,以及处理行政区划等可能存在的重名问题。示例展示了教职工信息导入实体类的实现,并展示了导入处理方法。
摘要由CSDN通过智能技术生成

自定义注解+反射在excel导入时获取字典表字段对应的值

1、思路:

用反射得到实体的上的自定义注解 ,从字典表数据源中找到注解对应的值,不用写很多重复代码,但是并不会改善效率,需要注意的地方就是查询字典表数据的接口一定要加缓存机制,不然循环查数据库就很恐怖;还有就是像行政区划这种很容易重名的字段表不太好使,因为我将字典表数据的值作为map的key,id作为map的value,重名要报错,只有单独写方法去匹配,说到底这种几十上百个字段的实体就不应该导入,还要校验数据,细节根本抠不完,我快遭不住了

2、注解:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DictTranslate
{
	/**
	 * 字典表名称
	 * @return 字典表名称
	 */
	String dataSource();

	/**
	 * 目标字段
	 * @return 目标字段
	 */
	String targetField();


}

3、反射处理

/**
	 * 匹配 字典表 mc 字段 ;将wid值赋值给targetfield字段
	 *
	 * @param dataList dataList
	 */
	public <T> void parseDictText(List<T> dataList)
	{

		if (CollectionUtils.isNotEmpty(dataList))
		{

			for (int i = 0; i < dataList.size(); i++)
			{

				T result = dataList.get(i);

				Field[] fields = result.getClass().getDeclaredFields();

				for (Field field : fields)
				{
					//检查带有 【DictTranslate】的注解
					DictTranslate annotation = field.getAnnotation(DictTranslate.class);

					if (annotation != null)
					{

						String dataSource = annotation.dataSource();

						String targetFieldStr = annotation.targetField();

						field.setAccessible(true);

						try
						{
							String fieldValue = (String) field.get(result);

							if (StringUtils.isNotEmpty(fieldValue))
							{

								//查询字典表
								DictPojo dictPojo = new DictPojo();

								dictPojo.setTableName(dataSource);

								List<TbzGbBsHbhZjDto> dictList = dictApiService.findDictDataByTableName(dictPojo);

								//名称作为key wid作为value
								// TODO: 2022/3/5 行政区划有重名
								String s = null;
								if (CollectionUtils.isNotEmpty(dictList))
								{

									Map<String, String> collect = dictList.stream().collect(Collectors.toMap(TbzGbBsHbhZjDto::getMc, TbzGbBsHbhZjDto::getWid));
									s = collect.get(fieldValue);

								} else
								{

									log.info("字典表不存在:" + dataSource);
								}
								//匹配字段
								Field targetField = result.getClass().getDeclaredField(targetFieldStr);

								targetField.setAccessible(true);

								if (StringUtils.isNotEmpty(s))
								{
									targetField.set(result, s);
								} else
								{

									//-1代表错误不能导入
									//targetField.set(result, "-1");
									Excel excelAnno = field.getAnnotation(Excel.class);
									if (excelAnno != null)
									{
										throw new CommonException("第【" + (i+2) + "】行 【" + excelAnno.name() + "】 不存在于系统中");
									} else
									{
										throw new CommonException("导入失败");
									}

								}
								targetField.setAccessible(false);
							}

						} catch (IllegalAccessException | NoSuchFieldException e)
						{
							log.error(e.getMessage());
						} finally
						{
							field.setAccessible(false);
						}

					}

				}

			}

		}

	}

4、举例:

(1)这是教职工基本信息的实体类其中的性别字段:

	@ApiModelProperty(value = "<字典表> T_BZGB_XB 性别 GB/T 2261.1")
	@TableField("XBM")
	private String xbm;

	@ApiModelProperty(value = "性别")
	@Excel(name = "性别")
	@DictTranslate(dataSource = "T_BZGB_XB",
			targetField = "xbm")
	@TableField(exist = false)
	private String xbmc;

(2)使用easypoi导入

/**
	 * 导入教职工信息
	 *
	 * @param file file
	 */
	public void importJzg(MultipartFile file) throws Exception
	{

		List<JzgJbxxEntity> jzgList = ExcelImportUtil.importExcel(file.getInputStream(), JzgJbxxEntity.class, new ImportParams());

		dictTranslateService.parseDictText(jzgList);
        
        log.info("导入中....")
	}

(3)打个断点看到效果:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值