java大数据量导出csv文件并压缩

java大数据量导出csv文件并压缩

java使用POI大数据量导出excel一般会存在以下几个问题:

  • 一次从数据库查询出这么大数据,查询缓慢
  • 查询数据量过大时会内存溢出
    解决方案:分页查询数据,比如一次查询5w数据,生成多个excel文件
  • 大数据量生成excel文件过慢
    解决方案:生成excel改为生成csv文件

本文主要 介绍java 导出csv文件

  • csv文件导出工具类
package com.yss.datamiddle.util;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @description:
 * @author: Hld
 * @create: 2021/11/16 17:11
 * @update: 2021/11/16 17:11
 */
public class CsvUtils {


    /**
     * 导出csv文件
     * @param titles    导出文件列头
     * @param list      具体导出数据
     * @param fileName  文件名称
     * @param response
     * @throws IOException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static void exportCsv(List<String> titles, List<Map<String,Object>> list, String fileName, HttpServletResponse response) throws IOException, IllegalArgumentException, IllegalAccessException{
        StringBuffer expStr = new StringBuffer();
        OutputStream o = null;
        try {
            //csv文件是逗号分隔,除第一个外,每次写入一个单元格数据后需要输入逗号
            for(String title : titles){
                expStr.append(title).append(",");
            }
            //写完文件头后换行
            expStr.append("\n");
            //写内容
            for(Map<String,Object> map : list){
                for (String key : map.keySet()) {
                    String val = map.get(key) != null ? map.get(key).toString() : "";
                    expStr.append(val).append(",");
                }
                //写完一行换行
                expStr.append("\n");
            }
            response.setContentType("application/download;charset=UTF-8");
            response.setContentType("Content-type:application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("Content-disposition","attachment;filename="+ java.net.URLEncoder.encode(fileName, "UTF-8"));
            o = response.getOutputStream();
            o.write(expStr.toString().getBytes("GBK"));
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            // 关闭
            if(o != null){
                o.close();
            }
        }
    }

    /**
     * 导出csv压缩文件
     * @param titles    导出文件列头
     * @param list      具体导出数据
     * @param fileName  压缩文件名称 例:aa.zip
     * @param response
     * @throws IOException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static String exportCsvZip(List<String> titles, List<Map<String,Object>> list, String fileName, HttpServletResponse response) throws IOException, IllegalArgumentException, IllegalAccessException{
        StringBuffer expStr = new StringBuffer();
        ZipOutputStream zos = null;
        OutputStream o = null;
        try {
            //csv文件是逗号分隔,除第一个外,每次写入一个单元格数据后需要输入逗号
            for(String title : titles){
                expStr.append(title).append(",");
            }
            //写完文件头后换行
            expStr.append("\n");
            //写内容
            for(Map<String,Object> map : list){
                for (String key : map.keySet()) {
                    String val = map.get(key) != null ? map.get(key).toString() : "";
                    expStr.append(val).append(",");
                }
                //写完一行换行
                expStr.append("\n");
            }
            response.setContentType("application/download;charset=UTF-8");
            response.setContentType("Content-type:application/vnd.ms-excel;charset=UTF-8");
            response.setHeader("Content-disposition","attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));

            o = response.getOutputStream();
            zos =  new ZipOutputStream(new BufferedOutputStream(o));
            zos.putNextEntry(new ZipEntry(fileName.replace("zip","csv")));//创建压缩文件内的文件
            zos.write(expStr.toString().getBytes("GBK"));
            zos.closeEntry();
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            if(zos != null){
                zos.close();
            }
            if(o != null){
                o.close();
            }
        }
        return "0";
    }
}

  • 调用示例
    @ApiOperation(value="导出csv文件")
    @PostMapping("/v1/exportCsv")
    public void exportCsv(HttpServletResponse response) throws IOException, IllegalAccessException {
        //模拟获取测试数据
        List<Map<String, Object>> datas = getDatas();
        // 导出文件列头
        List<String> titles = Arrays.asList("第一列title", "第二列title", "第三列title", "第四列title", "第五列title");
        // 导出csv文件
        CsvUtils.exportCsv(titles,datas,"test.csv",response);
        // 导出csv压缩文件
        CsvUtils.exportCsvZip(titles,datas,"test.zip",response);
       
    }
    
    public List<Map<String,Object>> getDatas(){
        List<Map<String,Object>> datas = new ArrayList<>();
        for (int i = 0; i < 10000; i++){
            Map<String,Object> map = new HashMap<>();
            map.put("a1","a1"+i);
            map.put("b2","b2"+i);
            map.put("c3","c3"+i);
            map.put("d4","d4"+i);
            map.put("e5","e5"+i);
            datas.add(map);
        }
        return datas;
    }

亲测导出40w数据到csv耗时3s左右

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
有多种方法可以在Java导出数据CSV文件中。以下是一些常用的方法: 1. 使用Apache Commons CSV库 Apache Commons CSV是一个开源的Java库,它提供了一组简单易用的API来读写CSV文件。您可以使用它来导出数据CSV文件中。 以下是一个示例代码片段,演示如何使用Apache Commons CSV数据导出CSV文件中: ``` public void exportToCsv(List<MyData> dataList, String fileName) throws IOException { CSVFormat csvFormat = CSVFormat.DEFAULT.withHeader("Column 1", "Column 2", "Column 3"); try (CSVPrinter csvPrinter = new CSVPrinter(new FileWriter(fileName), csvFormat)) { for (MyData data : dataList) { csvPrinter.printRecord(data.getColumn1(), data.getColumn2(), data.getColumn3()); } } } ``` 2. 使用Java 8的Stream API Java 8引入了Stream API,它提供了一种简单、快速的方式来处理集合数据。您可以使用它来导出数据CSV文件中。 以下是一个示例代码片段,演示如何使用Java 8的Stream API将数据导出CSV文件中: ``` public void exportToCsv(List<MyData> dataList, String fileName) throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) { writer.write("Column 1,Column 2,Column 3\n"); dataList.stream() .map(data -> String.format("%s,%s,%s", data.getColumn1(), data.getColumn2(), data.getColumn3())) .forEach(line -> { try { writer.write(line + "\n"); } catch (IOException e) { e.printStackTrace(); } }); } } ``` 3. 使用OpenCSV库 OpenCSV是另一个流行的开源Java库,它提供了一组API来读写CSV文件。您可以使用它来导出数据CSV文件中。 以下是一个示例代码片段,演示如何使用OpenCSV数据导出CSV文件中: ``` public void exportToCsv(List<MyData> dataList, String fileName) throws IOException { try (CSVWriter writer = new CSVWriter(new FileWriter(fileName))) { writer.writeNext(new String[]{"Column 1", "Column 2", "Column 3"}); for (MyData data : dataList) { writer.writeNext(new String[]{data.getColumn1(), data.getColumn2(), data.getColumn3()}); } } } ``` 无论您选择哪种方法,都应该注意处理可能出现的异常,例如IOException。此外,您还应该选择适当的CSV格式(例如CSVFormat.DEFAULT或CSVFormat.EXCEL),以确保导出数据格式正确。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值