zoukankan      html  css  js  c++  java
  • JAVA导出数据到excel中大数据量的解决方法

    最近在做项目功能时 ,发现有20万以上的数据。要求导出时直接导出成压缩包。原来的逻辑是使用poi导出到excel,他是操作对象集合然后将结果写到excel中。

    使用poi等导出时,没有考虑数据量的问题,大数据量无法满足,有个几千行jvm就哭了。更别提几万行几百万行数据了。

    经过一天的研究发现一种不会消耗过多内存的方法:

    导出成csv格式

    大数据量的导出成csv格式分为以下几步:

    1.首先引入需要的jar包 一下是我maven的配置方式

    	<dependency>
    			<groupId>org.mvel</groupId>
    			<artifactId>mvel2</artifactId>
    			<version>2.2.8.Final</version>
    		</dependency>
    		<dependency>
    			<groupId>net.sourceforge.javacsv</groupId>
    			<artifactId>javacsv</artifactId>
    			<version>2.0</version>
    		</dependency>
    

     2.以下是具体的执行代码,我是用的是jdbcTemplate

    public class DownloadVehicleRepair extends AbstractJob {
    
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        @Override
        protected void executeBusiness(Long aLong) {
            System.out.println("开始执行!!!!!!!!!!");
            final String fileName = "车辆维修清单.csv";//压缩包里面的文件
            final String[] header = {"序号", "第三方机构代码", "机构名称", "分公司", "合作机构", "单位类别", "主品牌", "品牌名称",
                    "被投诉", "涉及欺诈", "黑名单", "审核状态", "维护时间", "维护人员代码"};
            final String sql = "您需要执行sql”;
    
            jdbcTemplate.execute(new PreparedStatementCreator() {
                @Override
                public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                    PreparedStatement pstmt = connection.prepareStatement(sql);
                    return pstmt;
                }
            }, new PreparedStatementCallback<Integer>() {
                @Override
                public Integer doInPreparedStatement(PreparedStatement preparedStatement) throws SQLException, DataAccessException {
                    ResultSet rs = preparedStatement.executeQuery();
                    try {
                        CsvUtil.writeCsv(RuntimeEnvironmentUtil.getValue(SysConstent.code,SysConstent.path) + "\VehicleRepairDetail.zip",
                                fileName, header, rs);//RuntimeEnvironmentUtil.getValue()是为了获取你导出到服务器的路径
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return 0;
                }
            });
            System.out.println("导出完成!!!!!!!!!!!");
    
        }
    }
    

     3.以下是帮助类

    public class CsvUtil {
        // 编码类型
        public static final Charset CHARSET = Charset.forName("GBK");
    
        // 分隔符
        public static final char DELIMITER = ',';
    
        // 文件后缀
        public static final String SUFFIX = ".csv";
    
    
        public static void writeCsv(OutputStream out, String[] header, ResultSet rs)
                throws IOException, SQLException {
            CsvWriter writer = null;
            try {
                writer = new CsvWriter(out, CsvUtil.DELIMITER, CsvUtil.CHARSET);
                writeCsv(writer, header, rs);
            } finally {
                if (writer != null)
                    writer.close();
            }
        }
    
        public static void writeCsv(CsvWriter writer, String[] header, ResultSet rs)
                throws IOException, SQLException {
            if (header != null)
                writer.writeRecord(header);
            ResultSetMetaData md = rs.getMetaData();
            int columnCount = md.getColumnCount();
            while (rs.next()) {
                for (int i = 1; i <= columnCount; i++)
                    writer.write(rs.getString(i));
                writer.endRecord();
            }
        }
    
        public static void writeCsv(File file, String[] header, ResultSet rs)
                throws IOException, SQLException {
            BufferedOutputStream out = null;
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(file);
                out = new BufferedOutputStream(fileOutputStream);
                writeCsv(out, header, rs);
            } finally {
                if (out != null) {
                    out.flush();
                    out.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
            }
        }
    
        public static void writeCsv(String csvFilePath, String[] header,
                                    ResultSet rs) throws IOException, SQLException {
            writeCsv(new File(csvFilePath), header, rs);
        }
    
        public static void writeCsv(String zipFilePath, String csvName, String[] header, ResultSet rs)
                throws IOException, SQLException {
            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
            ZipOutputStream zos = null;
            try {
                fos = new FileOutputStream(zipFilePath);
                bos = new BufferedOutputStream(fos);
                zos = new ZipOutputStream(bos);
                zos.putNextEntry(new ZipEntry(csvName));
                writeCsv(zos, header, rs);
            } finally {
                StreamUtil.flush(zos);
                StreamUtil.close(zos);
                //StreamUtil.flush(bos);
                StreamUtil.close(bos);
                //StreamUtil.flush(fos);
                StreamUtil.close(fos);
            }
        }
    
    }
    
    public class StreamUtil {
        public static void flush(Flushable flushable) {
            if (flushable != null) {
                try {
                    flushable.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        public static void close(Closeable closeable){
            if(closeable!=null){
                try {
                    closeable.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

     4.下面是下载时的action

     @RequestMapping(value = "/downloadVehicleRepair", method = RequestMethod.POST)
        public ResponseEntity<byte[]> download() throws IOException {
            String path = RuntimeEnvironmentUtil.getValue(SysConstent.code,SysConstent.path)+"\VehicleRepairDetail.zip";
            File file = new File(path);
            HttpHeaders headers = new HttpHeaders();
            String fileName = new String("车辆维修清单.zip".getBytes("UTF-8"), "iso-8859-1");//为了解决中文名称乱码问题
            headers.setContentDispositionFormData("attachment", fileName);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
        }
    

     总结:以上只是关键代码。使用时只需要稍加改变就可以运行。

  • 相关阅读:
    vue-cli构建项目 npm run build后应该怎么运行在本地查看效果
    解析JSON数组
    Lambda
    keytool不是内部或外部命令
    XML布局
    HTML5本地存储IndexedDB基础使用
    Vue 2.0基础
    cs231n__3. LostFunction
    cs231n__2. K-nearest Neighbors
    week_Last
  • 原文地址:https://www.cnblogs.com/baizhanshi/p/5916801.html
Copyright © 2011-2022 走看看