大批量到处excel,防止内存溢出

2024-05-13 13:32

本文主要是介绍大批量到处excel,防止内存溢出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

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

导出成csv格式

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

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

1

2

3

4

5

6

7

8

9

10

<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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

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.以下是帮助类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

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);

        }

    }

 

}

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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

1

2

3

4

5

6

7

8

9

10

@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);

   }

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

这篇关于大批量到处excel,防止内存溢出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/985841

相关文章

C#借助Spire.XLS for .NET实现在Excel中添加文档属性

《C#借助Spire.XLSfor.NET实现在Excel中添加文档属性》在日常的数据处理和项目管理中,Excel文档扮演着举足轻重的角色,本文将深入探讨如何在C#中借助强大的第三方库Spire.... 目录为什么需要程序化添加Excel文档属性使用Spire.XLS for .NET库实现文档属性管理Sp

C#实现将Excel工作表拆分为多个窗格

《C#实现将Excel工作表拆分为多个窗格》在日常工作中,我们经常需要处理包含大量数据的Excel文件,本文将深入探讨如何在C#中利用强大的Spire.XLSfor.NET自动化实现Excel工作表的... 目录为什么需要拆分 Excel 窗格借助 Spire.XLS for .NET 实现冻结窗格(Fro

使用Python实现高效复制Excel行列与单元格

《使用Python实现高效复制Excel行列与单元格》在日常办公自动化或数据处理场景中,复制Excel中的单元格、行、列是高频需求,下面我们就来看看如何使用FreeSpire.XLSforPython... 目录一、环境准备:安装Free Spire.XLS for python二、核心实战:复制 Exce

pandas批量拆分与合并Excel文件的实现示例

《pandas批量拆分与合并Excel文件的实现示例》本文介绍了Pandas中基于整数位置的iloc和基于标签的loc方法进行数据索引和切片的操作,并将大Excel文件拆分合并,具有一定的参考价值,感... 目录一、Pandas 进行索引和切编程片的iloc、loc方法二、Pandas批量拆分与合并Exce

使用C#导出Excel数据并保存多种格式的完整示例

《使用C#导出Excel数据并保存多种格式的完整示例》在现代企业信息化管理中,Excel已经成为最常用的数据存储和分析工具,从员工信息表、销售数据报表到财务分析表,几乎所有部门都离不开Excel,本文... 目录引言1. 安装 Spire.XLS2. 创建工作簿和填充数据3. 保存为不同格式4. 效果展示5

Java轻松实现在Excel中插入、提取或删除文本框

《Java轻松实现在Excel中插入、提取或删除文本框》在日常的Java开发中,我们经常需要与Excel文件打交道,当涉及到Excel中的文本框时,许多开发者可能会感到棘手,下面我们就来看看如何使用J... 目录Java操作Excel文本框的实战指南1. 插入Excel文本框2. 提取Excel文本框内容3

Java JAR 启动内存参数配置指南(从基础设置到性能优化)

《JavaJAR启动内存参数配置指南(从基础设置到性能优化)》在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键,本文将系统讲解如何通过命令行参数、环境变量等方式... 目录一、核心内存参数详解1.1 堆内存配置1.2 元空间配置(MetASPace)1.3 线程栈配置1.

C#借助Spire.XLS for .NET实现Excel工作表自动化样式设置

《C#借助Spire.XLSfor.NET实现Excel工作表自动化样式设置》作为C#开发者,我们经常需要处理Excel文件,本文将深入探讨如何利用C#代码,借助强大的Spire.XLSfor.N... 目录为什么需要自动化工作表样式使用 Spire.XLS for .NET 实现工作表整体样式设置样式配置

使用C#实现Excel与DataTable的相互转换

《使用C#实现Excel与DataTable的相互转换》在软件开发中,Excel文件和DataTable是两种广泛使用的数据存储形式,本文将介绍如何通过C#实现Excel文件与Data... 目录安装必要的库从 Excel 导出数据到 DataTable从 DataTable 导入数据到 Excel处理 E

Python操作Excel的实用工具与库openpyxl/pandas的详细指南

《Python操作Excel的实用工具与库openpyxl/pandas的详细指南》在日常数据处理工作中,Excel是最常见的数据文件格式之一,本文将带你了解openpyxl和pandas的核心用法,... 目录一、openpyxl:原生 Excel 文件操作库1. 安装 openpyxl2. 创建 Exc