java通过CSV文本格式来导出千万级大数据

1、由于业务发展,当前页面导出只支持Excel导出数据时间过长已经不能满足系统需要,需要采用导出文本格式的方式来实现业务需求。

JAVA导出文本、mvn打包拒绝访问

NOT all named parameters have been set

java.lang.object无法转换成java.lang.string

2、java导出csv格式方法:

传入参数可以参照自己系统导出Excel的参数

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"));
outPutStream= response.getOutputStream();

List<HashMap<String,Object>> data = dpservice.getCSVDatalist(tableName, wheresql);

exportResultCSV(data,titleLine.split(","),colmLine.split(","),tableName,outPutStream);

    /**
     * 导出CSV数据方法
     * @param data         list集合
     * @param titleLine    表头字符串
     * @param colmLine     SQL列名,用于对应HashMap格式的key来获取值
     * @param tableName    表名
     * @param outPutStream 输出流
     * @throws IOException
     */
    public exportResultCSV(List<HashMap<String,Object>> data, String[] titleLine, String[] colmLine,String[] tableName, OutPutStream outPutStream) throws IOException{
        StringBuffer expStr = new StringBuffer();
        try {
            //csv文件是逗号分隔,除第一个外,每次写入一个单元格数据后需要输入逗号
            for(String title : titleLine){
                expStr.append(title).append(",");
            }
            //写完文件头后换行
            expStr.append("\n");
            //写数据
            for(HashMap<String,Object> map : data){
                //for (String key : map.keySet()) {
                //String val = map.get(key) != null ? map.get(key).toString() : "";
                //expStr.append(val).append(",");
                
                //由于HashMap集合里面存储数据属于无序存储,上面的方法属于直接获取,会导致导出的列错位,如下写法规避
                for (int j=0,j<colmLine.length;j++) {
                    String val = map.get(colmLine[j].toUppercase()) != null ? map.get(colmLine[j].toUppercase()).toString() : ""; 
                    //'\t'是为了导出格式为文本,避免长串数字变E+科学计数法
                    expStr.append(val).append("\t").append(","); 
                }
                //写完一行换行
                expStr.append("\n");
                }
        outPutStream.write(expStr.toString().getBytes("GBK"));
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            // 关闭
            if(outPutStream != null){
                outPutStream.close();
            }
        }
    }

由于上面的导出是放入的字符串,导致导出数据过大的时候会导致java内存溢出,java.lang.OutOfMemoryError :GC ....,所以需要对查询的数据进行分页导出,在mysql中拼接sql时多加个limit pagebeg,pageend的参数设置,内存溢出问题于是解决,新的问题是outPutStream= response.getOutputStream();方式直接浏览器下载只能生成同一个文件,也就是说你的sql结果集被你分成A1.csv,A2.csv,A3.csv,A4.csv时,导出来只有A1.csv,其他数据下载不下来了,由于response.getOutputStream()只响应一次页面,后续response的setHeader数据不会再改变了,不管你循环多少次都是第一份,所以需要将outPutStream= response.getOutputStream();改成outPutStream= new FileOutPutStream("下载路径+文件名+后缀");,这样就可以多份下载了,但是只能下载到你项目部署的服务器,项目部署动态路径如下获取this.getServletContext().getRealPath("/"),如此你就能下载到服务器了。

然后再从服务器通过浏览器将文件下载到到你的个人电脑,通过如下命令即可下载

IOUtils.copy(new FileInputStream("路径+文件名+后缀"),outPutStream) 这样就可以将原先的文件合成一个直接下载到本地了

import org.apache.commons.compress.utils.IOUtils; 用完后记得对IOUtils做close

3、java在拼接sql时,通过传入map参数来实现变量替换(传入方式=:),参数已经传入,直接报错NOT all named parameters have been set ,此错误是由于参数未被解析,需要通过如下代码先行转换:

/**
 * 解析替换具名参数
 * @param sql     要执行的SQL
 * @param paramap 参数map
 * @return        替换后的SQL
 */
public String findbySql(String sql, Map<String, object> paramap) {
 
        while (sql.indexOf(":") >= 0) {
            int x_liu = sql.indexOf(":");
            int y_liu = sql.substring(x_liu).indexOf(" ");
            int e_liu = sql.length();
            if (y_liu >= 0) {
                e_liu = x_liu + y_liu;
            }
            String key_liu = sql.substring(x_liu + 1, e_liu);
            String value = (String)paramap.get(key_liu);  //需要转换下,object无法默认转成string
            if (null != value && !"null".equals(value)) {
                value = "'" + value + "'";
            }
            sql = sql.substring(0, x_liu) + value + sql.substring(e_liu);
        }
        return sql;
    }

另外java.lang.object无法转换成java.lang.string的错误可以参照上面(String)paramap.get(key_liu)的写法。

4、mvn通过命令mvn clean package进行代码打包编译时出现/target/目录“拒绝访问”的错误,这时候需要重启电脑才能对此目录中的文件进行操作,具体原因为文件只有可读权限,需要增加文件夹所有用户(Everyone)所有的控制权限,增加文件加该用户权限自行百度(直接文件夹属性-》安全),不然经常需要重启电脑麻烦的一逼。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中处理千万级数据导出CSV可以使用以下步骤: 1. 读取数据:首先,需要从数据源(例如数据库)获取千万级数据。可以使用Java数据库连接技术(如JDBC)来连接到数据库,然后执行查询语句获取数据。如果数据存储在其他形式的文件中,比如文本文件,可以使用Java的文件读取类(如BufferedReader)来读取数据。 2. 创建CSV文件:接下来,需要创建一个CSV文件,以便将数据导出到其中。可以使用Java的文件操作类(如FileWriter)来创建和写入CSV文件。 3. 数据转换和写入CSV:对于每个数据条目,需要将其转换为CSV格式并写入到CSV文件中。通常,CSV文件中的每行代表一个数据记录,每个字段由逗号分隔。可以使用Java的字符串处理和分割方法来将数据转换为CSV格式。 4. 分批处理:由于要处理的数据量很大,可能会导致内存问题。为了解决这个问题,可以将数据分成较小的批次进行处理,然后将每个批次写入CSV文件。可以使用Java的集合框架(如List)来存储每个批次的数据。 5. 错误处理:在处理大量数据时,可能会遇到各种错误,如数据库连接错误、数据格式错误等。为了确保导出过程的稳定性和可靠性,需要在代码中添加适当的错误处理机制,如异常捕获和日志记录。 6. 导出完成:最后,当所有数据都成功导出CSV文件后,需要关闭文件和数据库连接以释放资源。 总而言之,使用Java处理千万级数据导出CSV需要读取数据、创建CSV文件、数据转换和写入、分批处理、错误处理和导出完成等步骤。在处理大量数据时,需要注意内存控制和错误处理,以确保导出过程的成功。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值