赞
踩
前端首先,我是用的avue,当然你们也可以自己选择vue,这里我就用avue演示,vue的我会提示一遍,基本都是比着葫芦画瓢。
我们点击上传时应该有的模态框,这里有两个重要的方法uploadAfter是上传到minio成功后和importHandle提交form表单的方法,最后一个handleReset清空是跟后面的内置方法有关
当然里面有一些自定义函数和方法,我这里是列出来了,这个是form表单绑定的option
第一个内置条件,马赛克是上传到minio的路径,需要自己设置过对象存储(原理是先上传到minio然后在用路径文件读取,简单说就是先上传在读取,点击文件的时候已经到我们服务器的里面了)
这里是上传后的文件,其实已经到服务器的存储区域了,只是提交的时候里面的字段和属性如何后端需要一些特俗字段,在这里加上,比如区分什么类型,什么需求,后端的东西会在后面说到
第一个内置方法,这里是指上传的文件必须是xls文件,然后我这里是导入时由一个excel弄出一堆,alreadyNum是需要catch去监控的,一般是打开模态框或者模态框里面清空的时候需要为0
下面是验证的效果就是为干这两件事
这里是删除的方法
点击你上传的文件,右侧有一个“×”, 效果是这样的
这个是上传失败的回调,这个我就不用说了吧
这个方法是minio上传后,回调的res也就是文件去和form表单数据绑定,因为v-modle是filesForm
提交也就是后端,马赛克是我需要在form设置的特殊属性,跟后端区分某些东西有关,具体怎么写需要看需求,也就是自己的业务逻辑
提交后,来到后端首先这种事一般是出现再实现类里面,Controller就不用我说了吧
唯一要注意的是
这个是前端传过来的类,里面的数据是需要自己设置的按自己需求添加一些字段和属性
然后我们直接进入实现类,直至主题关键代码,link字段是minio中的路径
这个是io流方法,这里我隐藏了特殊的区分属性
InformationImportExcelChangeDataListener为导入的设置,涉及到数据的转化,这里我就不截图了,这里我是用的3.1.1的
@Slf4j public class InformationImportExcelChangeDataListener extends AnalysisEventListener<Map<Integer, String>>{ private static final Integer BATCH_COUNT = 3000;//每隔3000条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收 private static final Integer TOTAL_COLUMN = 9;//总列数 private 业务逻辑里的service service = null;//service层 private 导入的entity类 entity= null;//entity类 private Integer totalRow=0;//默认总条数(从excel中获取的行数) private final AtomicLong succLong = new AtomicLong(0);//满足条件的条数 private final AtomicLong failLong = new AtomicLong(0);//不满足条件的条数 public String batchId=null;//同一批次标识 private List<导入的entity类> list = new ArrayList<>();//已读取到需要保存的材料数据 //构造的函数 public InformationImportExcelChangeDataListener(导入的entity类 entity,业务逻辑里的service service){ this.service = service;//业务逻辑里的service层 this.entity= entity;//entity类 }
@Override public void invoke(Map<Integer, String> data, AnalysisContext analysisContext) { handleData(data);//处理数据 this.totalRow += 1;//记录excel总行数 }
@Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { batchInsertData();//剩余数据入库处理 }
public void handleData(Map<Integer, String> data){ try{ //处理数据 if(Func.isEmpty(data.get(1))){ failLong.addAndGet(1);//加一条 return;//执行下一次循环,不往下执行 } //补齐字段数据,补齐的字段数据设置为空 if(data.size() != TOTAL_COLUMN){ for(int i= data.size() ;i<TOTAL_COLUMN;i++){ if(data.containsKey(i)){ data.put(i,null); } } } 去new一个自己的entity类 entity ent = new entity(); //按照导入的文件来 data.get(0)即为你导入文件的第一列也就是A 这里是业务逻辑不能直接写,需要看需求,但是这里的类型已经写了模板 ent.setString(Func.isEmpty(data.get(0))? null:data.get(0));//文本类 ent.setDouble(Func.isEmpty(data.get(0))? null:(AutoUtil.isNumber(data.get(0)).Func.toDouble(data.get(0)):null))//Double类 ent.setInteger(Func.isEmpty(data.get(0))? null: (AutoUtil.isNumber(data.get(0))? Func.toInt(data.get(0)):null))//Integer类
succLong.getAndAdd(1);//成功处理数据加一 list.add(ent);//加入list集合 if(list.size()>=BATCH_COUNT){ batchInsertData();//数据入库处理 }
}catch(Exception e){ log.error("处理的数据为:{}", JsonUtil.toJson(data)); log.error("处理数据报错为:", e); }
//数据批处理 @Transactional(rollbackFor = Exception.class)//数据回滚,这里我就不解释了吧,面试的时候偶尔会问这个东西 public void batchInsertData() { //保存变更数据 if(list.size() != 0){ 业务逻辑里的service.saveBatch(list);//这个是mybatis自带的实体对象集合 } list.clear();//清空已经提交的数据 }
上述就是一个完整的导入文件并存入数据库
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。