java读取zip压缩文件并将数据写入到数据库

本文介绍了如何通过Spring MVC接收上传文件,重点阐述了使用ZipInputStream解析CSV文件并转换为对象的过程,包括数据校验和对象组装。涉及步骤包括文件流操作、CSV读取和字段映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一步:获取到上传的文件
在这里插入图片描述

@RequestMapping(value = "/xxx",produces = {"application/json;charset=UTF-8"})
    public Response import(MultipartFile file) throws Exception {}

第二步:获取文件流

//InputStream=file.getInputStream()
public static Pair<Integer,Map<String,List<Object>>> importDataV2(InputStream in,List<String> readFileName){
        Map<String,List<Object>> map = new HashMap<>();
        //总数据条数
        int count = 0;
        ZipInputStream zin = new ZipInputStream(in);
        ZipEntry ze;
        try {
            //读取一个文件
            while((ze = zin.getNextEntry()) != null){
                //为了防止用户导入时选择了错误的文件影响其他表的数据,做一层过滤
                if(!readFileName.contains(ze.getName())){
                    log.warn("导入文件与接口不符,文件名:{}",ze.getName());
                    continue;
                }

                if(ze.isDirectory()){
                    //为空的文件夹什么都不做
                }else{
                    BufferedReader br = new BufferedReader(new InputStreamReader(zin, StandardCharsets.UTF_8));
                    List<Object> list = new ArrayList<>();
                    int cnt = readCsvFileV2(br, ze.getName(),list);
                    count+=cnt;
                    //list里面就是组装好的对象list了
                    map.put(ze.getName(),list);
                }
            }
            return Pair.of(count,map);
        }catch (HsjryException e){
            throw e;
        }catch (Exception e){
            e.printStackTrace();
            log.error(e,"importDataError");
        }finally {
            try{
                zin.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return null;
    }

第三步:读取每一行数据,并转化为对象

  1. 根据文件名判断对数据进行组装为对象
private static int readCsvFileV2(BufferedReader br, String name,List<Object> list) {
        int count = 0;
        try {
            // 创建 CSV Reader 对象, 参数说明(读取的文件路径,分隔符,编码格式)
            CsvReader csvReader = new CsvReader(br);
            // 跳过表头
            csvReader.readHeaders();
            // 读取除表头外的内容,读取一行
            while (csvReader.readRecord()) {
                // 读取一整行
                String line = csvReader.getRawRecord();
                //解密
                line = Objects.equals(PropertiesConfig.needEncrypt,Boolean.TRUE) ? deciphering(line) : line;
                count++;
                //只切割双引号外面的逗号
                String[] split = line.split(",(?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)",-1);
                String newVersion = VersionUtil.getNewVersion(null);
                String newTechnologyVersion = VersionUtil.getNewTechnologyVersion(newVersion);
                long longId = FtSequenceTool.nextLongId();
                switch (name){
                    case FEATURES_COM_FILE_NAME:
                        buildFeaturesCom(longId, newVersion, newTechnologyVersion, split,list);
                        break;
                    default:
                        break;
                }
            }
        } catch (HsjryException e) {
            throw e;
        } catch (Exception e) {
            //某一个文件出错,仅打印日志
            log.error(e,"读取文件{}出错",name);
        }
        return count;
    }
  1. 这里是一些默认属性的设置

在这里插入图片描述
3.将文件中的数据通过反射设置到对象上面

/**
     * 对 object 进行属性设置
     * @param object
     * @param data
     * @param fields
     */
    public static void buildFiled(Object object, String[] data, String[] fields) {

            for (int i = 0; i < fields.length; i++)  {
                try {
                    Field field = object.getClass().getDeclaredField(fields[i]);
                    field.setAccessible(true);
                    Class<?> type = field.getType();
                    String value = data[i];
                    if(NOT_NULL_FIELD.contains(field.getName()) && value==null){
                        throw new HsjryException("500","该列不允许为空");
                    }

                    if(value!=null && !"null".equals(value.replace("\"", "").trim())){
                        if(Objects.equals(type,String.class)){
                            if(value.length()>=2){
                                if(value.indexOf("\"")==0){
                                    //去掉第一个 "
                                    value = value.substring(1,value.length());
                                }
                                if(value.lastIndexOf("\"")==(value.length()-1)){
                                    //去掉最后一个 "
                                    value = value.substring(0,value.length()-1);
                                }
                                //把两个双引号换成一个双引号
                                value = value.replaceAll("\"\"","\"");
                            }

                            field.set(object,value.trim());
                        }else if(Objects.equals(type,Long.class) && !StringUtils.isEmpty(value)){
                            field.set(object,Long.parseLong(value.trim()));
                        }else if(Objects.equals(type,Integer.class) && !StringUtils.isEmpty(value)){
                            field.set(object,Integer.parseInt(value.trim()));
                        }else if(Objects.equals(type,java.util.Date.class)){
                            Date parse = format.parse(value);
                            field.set(object,parse);
                        }else if(Objects.equals(type,BigDecimal.class) && !StringUtils.isEmpty(value)){
                            field.set(object,new BigDecimal(value.trim()));
                        }else if(Objects.equals(type,Double.class) && !StringUtils.isEmpty(value)){
                            field.set(object,Double.parseDouble(value.trim()));
                        }else{
                            log.warn("未匹配到数据类型 类名:{},属性名:{},类型:{}",object.getClass().getSimpleName(),field.getName(),type.getSimpleName());
                        }
                    }
                }catch (HsjryException e){
                    log.error(e,"不允许为空的列为空{}",object.getClass().getSimpleName());
                    throw e;
                }catch (Exception e){
                    //一行数据失败,仅打印日志,不作任何处理
                    log.error(e,"组装数据行失败{}",object.getClass().getSimpleName());
                }
            }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值