springboot excell poi 千万级 导入导出

本文探讨了处理千万级别数据导入导出时遇到的内存溢出问题,提出了两种解决方案,重点介绍了第一种方案——通过临时文件分批导入数据库。在4GB内存环境下,该方法能有效处理千万级数据,且使用SAX解析XML以减少内存占用。步骤包括将文件存放到本地,分批读取,使用SAX解析工具类,并针对上传文件大小进行设置。
摘要由CSDN通过智能技术生成

项目涉及千万级别数据导入导出,目前网上导入导出很多,如果使用poi导入很多到十万级数据内存溢出,根据电脑内存有很大关系,甚至有些电脑导入七万就会内存溢出。
目前对于excel的大文件导入导出,有两种方案
第一,将文件先复制到本地临时路径下然后分批导入解析最后批次导入数据库
第二,采用sheet分页
本文采用第一种方案:因为我们的内存不是无限大 所以我们只能利用硬盘空间进行存储,list,map最多存储百万级数据,因为java垃圾回收机制不是可预料的 所以导入时我们需要优化我们的代码进行手动释放堆内存空间,导入在4g运行内存情况下可导入千万级以上 ,速度超快
其中解析xml时我们使用sax解析
本文sax已经解决excel版本差距 所有都可以导入,但是sax解析中列数需要自己调整
1.首先导入时我们需要将导入的文件临时存放于本地 存放本地可以一次1000行的读取可根据自己需求修改

@PostMapping(value = "/excelIn", consumes = "multipart/*", headers = "content-type=multipart/form-data")
public String addBlacklist(
        @RequestParam("file") MultipartFile multipartFile, HttpServletRequest request
) {
    //判断上传内容是否符合要求
    String fileName = multipartFile.getOriginalFilename();
    if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
        return "上传的文件格式不正确";
    }

    String files = saveFile(multipartFile, request);
    int result = 0;
    try {
        result =  testService.addBlackLists(files);
    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        File file = new File(files);
        System.gc();
        boolean delSuccess = file.delete();
        if(delSuccess){
            System.out.println("删除文件成功");
        }else{
            System.out.println("删除文件失败");
        }
    }
    return String.valueOf(result);
}

private String saveFile(MultipartFile multipartFile, HttpServletRequest request) {
    String path;
    String fileName = multipartFile.getOriginalFilename();
    // 判断文件类型
    //String realPath = request.getSession().getServletContext().getRealPath("/");
    String trueFileName = fileName;
    // 设置存放Excel文件的路径
    path = "e:/" + trueFileName;
    File file = new File(path);
    if (file.exists() && file.isFile()) {
        file.delete();
    }
    try {
        multipartFile.transferTo(new File(path));
    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }

    return path;
}

2.进行解析处理保存数据库

@Transactional
public int addBlackLists(String file) throws ExecutionException, InterruptedException {
    try {
        BigExcelReader bigExcelReader = new BigExcelReader(file) {

            @Override
            public void outputAllRow(List<String[]> lists) {
                List<List<Object>> lists1 = new LinkedList<>();


                //执行保存
                for(String[] row : lists){
                Map<String, Object> map = new HashMap<String, Object>();
                //map.put("", row);
                    List<Object> list2 = new ArrayList<>();
                    System.out.print("[");
                    for(String cell : row){
                        System.out.print(cell+",");
                        list2.add(cell);
                    }

                    lists1.add(list2);
                    //list2= new ArrayList<Object>();

                    System.out.println("]");
                }
                saveAll(lists1);
            }
        };
        // 执行解析
        bigExcelReader.parse();
        //File files = new File(file);

    } catch (Exception e) {
       throw new RuntimeException(e);
    }
    return 1;

}
@Override
public void saveAll(List<List<Object>> lists) {
    if(lists.size() > 0){
        String uuidotherid = null;
       Map<String, Object> uuidmap = new HashMap<>();
        uuidmap.put("uuidotherid",null);
        for(int i = 2 ;i < lists.size() ;i++){

            List<Object> list &#
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值