CSV文件生成太慢

时间:2016-05-31 07:54:05

标签: java performance csv servlets

您好我正在使用以下代码使用java servlet生成CSV文件,但是生成一个没有的CSV文件需要40分钟。行3000.是否有任何其他优化的代码可以加快我的CSV生成速度1或2分钟。 我的代码在这里:

protected void getCSVReportGererated(HttpServletRequest req, HttpServletResponse res) throws IOException{   
        ResultSet rs = null;
        String reportSQL = getReportSQL();
        PreparedStatement ps = null;
        Connection con = DriverManager.getConnection("jdbc:derby://localhost:1527/testDb","username", "password");
        try{
            ps = conn.prepareStatement(reportSQL);
            ps.execute();
            rs = ps.getResultSet();
            res.setContentType("text/csv");
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy-HHMM");
            Date dt = new Date();
            String reportName = "my_report"+sdf.format(dt)+".csv";
            res.setHeader("Content-disposition", "attachment; " + "filename=" + reportName);
            ArrayList<String> rows = new ArrayList<String>();
            rows.add("col1,col2,col3,col4,col5,col6,col7,col8,col9,col10");
            rows.add("\n");
            String row = null;
            while(rs.next()){
                row = String.format("%04d", Integer.parseInt(rs.getString(1)))+","+String.format("%05d", Integer.parseInt(rs.getString(2)))+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7)+","+rs.getString(8)+","+rs.getString(9)+","+rs.getString(10);
                rows.add(row);
                rows.add("\n");
            }
                Iterator<String> iter = rows.iterator();
                while (iter.hasNext()){
                    String outputString = (String) iter.next();
                    res.getOutputStream().print(outputString);
                }
                res.getOutputStream().flush();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            try {
                if (ps != null)
                    ps.close();
                if (conn != null)
                    conn.close();
                if(rs != null)
                    rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }       
        }
}

3 个答案:

答案 0 :(得分:1)

你正在做太多事情。这里至少有3个不相关的问题:

  1. 从数据库中读取
  2. 转换为CSV
  3. 将该CSV提供给HTTP端点
  4. 我分别开发和测试这三个方面,并确定需要这么长时间的内容。您的代码可能不是最有效的,但它看起来不会花费40分钟。

    除非您的数据库报告非常庞大,否则它应该分成许多较小的报告。

    无论如何,我使用MVC框架(Spring MVC / Spring Boot是一个好的开始)并重写类似于this answer的代码

答案 1 :(得分:0)

尝试打印System.currentTimeInMillis()以了解db查询,第一个while循环或第二个while循环是否花费了时间。

您也可以只使用一个循环,并避免在所有打印时直接使用行列表到输出流。

答案 2 :(得分:0)

尝试更改:

protected void getCSVReportGererated(HttpServletRequest req, HttpServletResponse res) throws IOException{   
        ResultSet rs = null;
        String reportSQL = getReportSQL();
        PreparedStatement ps = null;
        Connection con = DriverManager.getConnection("jdbc:derby://localhost:1527/testDb","username", "password");
        try{
            ps = conn.prepareStatement(reportSQL);
            ps.execute();
            rs = ps.getResultSet();
            res.setContentType("text/csv");
            SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy-HHMM");
            Date dt = new Date();
            String reportName = "my_report"+sdf.format(dt)+".csv";
            res.setHeader("Content-disposition", "attachment; " + "filename=" + reportName);
            OutputStream stream=res.getOutputStream();         
            stream.println("col1,col2,col3,col4,col5,col6,col7,col8,col9,col10");

            String row = null;
            while(rs.next()){
                row = String.format("%04d",rs.getInt(1)))+","+String.format("%05d", rs.getInt(2))+","+rs.getString(3)+","+rs.getString(4)+","+rs.getString(5)+","+rs.getString(6)+","+rs.getString(7)+","+rs.getString(8)+","+rs.getString(9)+","+rs.getString(10);
                stream.println(row);                
            }
            stream.flush();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
            try {
                if (ps != null)
                    ps.close();
                if (conn != null)
                    conn.close();
                if(rs != null)
                    rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }       
        }
}