数据库导出CSV格式,并压缩成ZIP的形式导出

来源:互联网 发布:基金组合 知乎 编辑:程序博客网 时间:2024/06/05 14:27

因为Excel导出会导致内存溢出,所以以CSV格式导出。

以下实现的功能:从数据读取数,以CSV格式导出,并压缩成ZIP,让用户下载。下面是一次导出的文件是6万条,超过6万条的,自动生成第二个文件。这个是客户的要求,一次导出一个文件其实更方便。曾经尝试过,下载百万千万条数据生成CSV格式,是不会内存溢出的。

不足之处有两个地方,CSV格式下载到本地,用户提出,一定要可以自己选路径,那没办法,本来都已经下载到本地了,只好再压缩一遍让客户自己选了。

第二,本模块不是通用的。做了一个通用的模块,但是因为每次取多少个字段不确定,只是在while里加for循环来实现,所以效率几何倍数的递减。

实现之前要导入两三个jar文件:ant.jar,commons-compress-1.3.jar,opencsv-1.8.jar。


示例下载地址:


[java] view plaincopy
  1. import java.io.File;  
  2. import java.io.FileInputStream;  
  3. import java.io.FileWriter;  
  4. import java.io.IOException;  
  5. import java.sql.CallableStatement;  
  6. import java.sql.Connection;  
  7. import java.sql.PreparedStatement;  
  8. import java.sql.ResultSet;  
  9. import java.sql.SQLException;  
  10. import java.util.ArrayList;  
  11. import java.util.List;  
  12. import javax.servlet.http.HttpServletResponse;  
  13. import org.apache.tools.zip.ZipEntry;  
  14. import org.apache.tools.zip.ZipOutputStream;  
  15. import oracle.jdbc.OracleTypes;  
  16. import au.com.bytecode.opencsv.CSVWriter;  
  17.   
  18.   
  19. /** 
  20.  * @title  
  21.  * @description Action 
  22.  * @copyright Copyright (c) 2012 
  23.  * @author painarthur 
  24.  * @version 1.0 
  25.  */  
  26.   
  27. public class Ncp_fhyDAO {  
  28.   
  29. public void exportCsv(HttpServletResponse response,int resultCountAll,String path,String csvExportIllustrate,  
  30.         int page, int pageSize,String p_cswjg_dm,String p_csssq  
  31.         ,String p_cHymx_dm,String p_cHY_Level,String p_cPX_ZD,String p_cPX_SJ)   
  32.             throws DataAccessException {  
  33.     JDBCDataSource jDBCDataSource = JDBCDataSource.getJDBCDataSource();  
  34.     PreparedStatement preparedStatement = null;  
  35.     ResultSet result = null;  
  36.     Connection conn = null;  
  37.     File tempFile = null;  
  38.     CSVWriter writer = null;  
  39.     ZipOutputStream zos = null;  
  40.     FileInputStream fis = null;  
  41.     int t1 = (int) System.currentTimeMillis();  
  42.     try {  
  43.         conn = jDBCDataSource.getConnection();  
  44.         CallableStatement proc = conn  
  45.                 .prepareCall("{call sjcq.BP_**_FHY_HS(?,?,?,?,?,?,?)}");  
  46.         proc.setString(1, p_csssq);  
  47.         proc.setString(2, p_cswjg_dm);  
  48.         proc.setString(3, p_cHymx_dm);  
  49.         proc.setString(4, p_cHY_Level);  
  50.         proc.setString(5, p_cPX_ZD);  
  51.         proc.setString(6, p_cPX_SJ);  
  52.         proc.registerOutParameter(7, OracleTypes.VARCHAR);  
  53.         proc.execute();  
  54.         String queryStr = proc.getString(7); //存储过程输出SQL语句  
  55.         preparedStatement = conn.prepareStatement(queryStr);  
  56.         result = preparedStatement.executeQuery(queryStr);    
  57.           
  58.         String fileName = "农产品**查询";  
  59.         String fileExtension = ".csv";  
  60.         int bs = -1;//倍数  
  61.         int exportMax = 60000;  //一次导出6万条数据  
  62.         int temp = 1;  
  63.         String executeStr = "";  
  64.         String fullName = "";  
  65.         //FileWriter w = null;  
  66.         //if(resultCountAll/exportMax>=1){  
  67.             bs = resultCountAll/exportMax;  
  68.         //}  
  69.         while(bs>=0){  
  70.             String [] includeHeaders = {"行业代码","行业名称","户数"};  //定义导出CSV文件头文件  
  71.             if(resultCountAll>=(exportMax*temp)){  //一次导出6万条数据,多出的部分,生成第二个6万条数据文件  
  72.                 executeStr = "SELECT *  FROM (select rownum myNum,TempAA.* FROM (" + queryStr + ")TempAA ) where myNum>="  
  73.                             + (temp-1)*exportMax + " and TempAA.myNum<=" + exportMax*temp;  
  74.                 tempFile = new File(path+fileName+temp+fileExtension);  
  75.                 fullName = path+fileName+temp+fileExtension;   //指定导出的文件目录  
  76.             }else if(resultCountAll%exportMax!=0){  //剩下的不足6万条的导出最后一个文件  
  77.                 executeStr = "SELECT *  FROM (select rownum myNum,TempAA.* FROM (" + queryStr + ")TempAA ) where myNum>="  
  78.                     + (temp-1)*exportMax + " and myNum<=" + resultCountAll;  
  79.                 fullName = path+fileName+temp+fileExtension;    
  80.             }  
  81.             preparedStatement = conn.prepareStatement(executeStr);  
  82.             result = preparedStatement.executeQuery(executeStr);     
  83.             writer = new CSVWriter(new FileWriter(fullName));   //new一个CSV文件  
  84.             writer.writeNext(includeHeaders);  
  85.             while (result.next()) {  
  86.                 String[] data = new String[]{  
  87.                         StringUtil.isoToGbk(result.getString("HY_DM")),//行业代码  
  88.                          StringUtil.isoToGbk(result.getString("HY_MC")),//行业名称  
  89.                          StringUtil.isoToGbk(result.getString("HS"))//户数  
  90.                 };  
  91.                 writer.writeNext(data);  
  92.             }  
  93.             writer.flush();  
  94.             writer.close();  
  95.             if (result != null) {  
  96.                 result.close();  
  97.                 result = null;  
  98.             }  
  99.             if (preparedStatement != null) {  
  100.                 preparedStatement.close();  
  101.                 preparedStatement = null;  
  102.             }  
  103.             bs-=1;  
  104.             temp+=1;  
  105.         }  
  106.         tempFile = null;  
  107.                //如果不以压缩包的形式导出,下面的代码就完全没有必要要了。上面的部分,系统会以CSV格式导出到本地。  
  108.                 response.setContentType("application/zip");  
  109.         response.reset();  
  110.         response.setCharacterEncoding("GBK");  
  111.         response.setHeader("Content-Disposition","attachment; filename=" + new String(fileName.getBytes("GBK"),"ISO8859-1")+".zip" );  
  112.         //文件压缩  
  113.         int leng=0;  
  114.         zos = new ZipOutputStream(response.getOutputStream());     
  115.         File delFile = null;  
  116.         for(int i = temp-1;i>0;i--){  
  117.             fis = new FileInputStream(path+fileName+ i + ".csv");  
  118.             ZipEntry z1 = new ZipEntry(fileName+i+".csv");  
  119.             zos.setComment(csvExportIllustrate);  
  120.             zos.putNextEntry(z1);  
  121.             byte[] b = new byte[1024];  
  122.             while((leng = fis.read(b))!=-1){  
  123.                 zos.write(b,0,leng);  
  124.             }  
  125.             zos.setEncoding("GBK");  
  126.             fis.close();  
  127.         }  
  128.         zos.close();  
  129.         //文件删除  
  130.         for(int i = temp-1;i>0;i--){  
  131.             delFile = new File(path+fileName+ i + ".csv");  
  132.             delFile.delete();  
  133.         }  
  134.     } catch (Exception e) {  
  135.         throw new DataAccessException(e);  
  136.     } finally {  
  137.         // 释放资源  
  138.         try {  
  139.             if(zos!=null){  
  140.                 try {  
  141.                     zos.close();  
  142.                 } catch (IOException e) {  
  143.                     e.printStackTrace();  
  144.                 }  
  145.                 zos = null;  
  146.             }  
  147.             if(fis!=null){  
  148.                 try {  
  149.                     fis.close();  
  150.                 } catch (IOException e) {  
  151.                     e.printStackTrace();  
  152.                 }  
  153.                 fis = null;  
  154.             }  
  155.               
  156.             if(writer!=null){  
  157.                 try {  
  158.                     writer.close();  
  159.                 } catch (IOException e) {  
  160.                     e.printStackTrace();  
  161.                 }  
  162.                 writer = null;  
  163.             }  
  164.             if (result != null) {  
  165.                 result.close();  
  166.                 result = null;  
  167.             }  
  168.             if (preparedStatement != null) {  
  169.                 preparedStatement.close();  
  170.                 preparedStatement = null;  
  171.             }  
  172.         } catch (SQLException e1) {  
  173.             throw new DataAccessException(e1);  
  174.         }  
  175.     }  
  176. }  
  177.   
  178. }  


以下是通用的,如果有更好的实现方法或功能,请提出建议。

[java] view plaincopy
  1. import java.io.File;  
  2. import java.io.FileInputStream;  
  3. import java.io.FileWriter;  
  4. import java.io.IOException;  
  5. import java.sql.CallableStatement;  
  6. import java.sql.Connection;  
  7. import java.sql.PreparedStatement;  
  8. import java.sql.ResultSet;  
  9. import java.sql.SQLException;  
  10. import java.util.ArrayList;  
  11. import java.util.List;  
  12. import java.util.zip.ZipEntry;  
  13. import java.util.zip.ZipOutputStream;  
  14. import javax.servlet.http.HttpServletResponse;  
  15. import oracle.jdbc.OracleTypes;  
  16. import au.com.bytecode.opencsv.CSVWriter;  
  17.   
  18.   
  19. public class ExportCsvToZip {  
  20.     private String zipSm = "超过6万条数据后,以CSV格式导出。";//导出zip文件说明  
  21.     /* 
  22.      * add by li_dyue 
  23.      * date: 20120324 
  24.      * function:compose csv files and export zip 
  25.      *  
  26.      *  csvFileName 暂时生成的csv文件名称 
  27.      *  exportZipName 要导出的zip文件名称 
  28.      *  includeHeaders csv文件的列表的第一列,例如:纳税人识别号、纳税人名称、税务机关等 
  29.      *  dataPO 给csv文件赋值的PO们 
  30.      *  querysql 需要查询的sql语句 
  31.      *  exportMax 定义一次最多导出多少条csv文件 
  32.      *  resultNumber 一共需要导出多少条记录 
  33.      *   
  34.      *  文件给生成到本地,查出一条就往文件里写一条, 
  35.      *  如果要把这些数据都放到内存中再压缩,那么在大数据量的时候,一定会发生内存溢出问题。 
  36.      *   
  37.      */  
  38.       
  39.     public void exportZip(HttpServletResponse response, String csvFileName, String exportZipName,  
  40.             String[] includeHeaders, String[] dataPO, String querysql, int resultNumber)  
  41.             throws DataAccessException {  
  42.           
  43.         JDBCDataSource jDBCDataSource = JDBCDataSource.getJDBCDataSource();  
  44.         List rs_list = new ArrayList();  
  45.         PageListData pageListData = new PageListData();  
  46.         PreparedStatement preparedStatement = null;  
  47.         ResultSet result = null;  
  48.         Connection conn = null;  
  49.         File tempFile = null;  
  50.         CSVWriter writer = null;  
  51.         ZipOutputStream zos = null;  
  52.         FileInputStream fis = null;  
  53.         //path: 先在服务器上生成csv文件的路径  
  54.         StringBuffer path = new StringBuffer();  
  55.         path.append("c:/lee/");  
  56.         String fileExtension = ".csv";  
  57.         String c = "";  
  58.         int countAll = 0;  
  59.         int bs = -1;//倍数  
  60.         int exportMax = 60000;  
  61.         int temp = 1;  
  62.         String executeStr = "";  
  63.         StringBuffer bf = new StringBuffer();  
  64.         int t1 = (int) System.currentTimeMillis();  
  65.         String[] data = new String[dataPO.length];  
  66.         try {  
  67.             conn = jDBCDataSource.getConnection();  
  68.               
  69.             countAll = resultNumber;  
  70.             if(countAll/exportMax>=1){  
  71.                 bs = countAll/exportMax;  
  72.             }  
  73.             while(bs>=0){  
  74.                 if(countAll>=(exportMax*temp)){  
  75.                     executeStr = "SELECT *  FROM (select rownum myNum,TempAA.* FROM (" + querysql + ")TempAA ) where myNum>="  
  76.                                 + (temp-1)*exportMax + " and myNum<=" + exportMax*temp;  
  77.                     preparedStatement = conn.prepareStatement(executeStr);  
  78.                     result = preparedStatement.executeQuery(executeStr);  
  79.                     tempFile = new File(path+csvFileName+temp+fileExtension);  
  80.                     System.out.println("csvFileName:"+csvFileName+temp+fileExtension);  
  81.                     writer = new CSVWriter(new FileWriter(tempFile));  
  82.                     writer.writeNext(includeHeaders);  
  83.                                           
  84.                     while (result.next()) {  
  85.                         //String[] data = new String[dataPO.length];  
  86.                                                 //!!!  此处的for循环,严重影响了导出的效率,暂无好的解决方案  
  87.                                                 for(int i=0;i<dataPO.length;i++){  
  88.                             data[i] =  StringUtil.isoToGbk(result.getString(dataPO[i]));  
  89.                         }  
  90.                         writer.writeNext(data);  
  91.                     }  
  92.                     writer.close();  
  93.                     if (result != null) {  
  94.                         result.close();  
  95.                         result = null;  
  96.                     }  
  97.                     if (preparedStatement != null) {  
  98.                         preparedStatement.close();  
  99.                         preparedStatement = null;  
  100.                     }  
  101.                 }else if(countAll%exportMax!=0){  
  102.                     executeStr = "SELECT *  FROM (select rownum myNum,aa.* FROM (" + querysql + ")aa ) where myNum>="  
  103.                     + (temp-1)*exportMax + " and myNum<=" + countAll;  
  104.                     preparedStatement = conn.prepareStatement(executeStr);  
  105.                     result = preparedStatement.executeQuery(executeStr);  
  106.                     tempFile = new File(path+csvFileName+temp+fileExtension);  
  107.                     System.out.println("csvFileName:"+csvFileName+temp+fileExtension);  
  108.                     writer = new CSVWriter(new FileWriter(tempFile));  
  109.                     writer.writeNext(includeHeaders);  
  110.                     while (result.next()) {  
  111.                           
  112.                         for(int i=0;i<dataPO.length;i++){  
  113.                             data[i] =  StringUtil.isoToGbk(result.getString(dataPO[i]));  
  114.                         }  
  115.                         writer.writeNext(data);  
  116.                     }  
  117.                     writer.close();  
  118.                     if (result != null) {  
  119.                         result.close();  
  120.                         result = null;  
  121.                     }  
  122.                     if (preparedStatement != null) {  
  123.                         preparedStatement.close();  
  124.                         preparedStatement = null;  
  125.                     }  
  126.                 }  
  127.                 bs-=1;  
  128.                 temp+=1;  
  129.             }  
  130.             int t2 = (int) System.currentTimeMillis();  
  131.             System.out.println((t2-t1)/3600);  
  132.               
  133.             File file = new File("c:/lee/c.zip");  
  134.             String outputFile = csvFileName+temp + ".csv";  
  135.               
  136.             response.setContentType("application/zip");  
  137.             response.reset();  
  138.             exportZipName = "aa";  
  139.             response.setHeader("Content-Disposition",  
  140.                     "attachment; filename=\"" + "c.zip" + "\"" );  
  141.             response.setCharacterEncoding("UTF-8");  
  142.             int leng=0;  
  143.             zos = new ZipOutputStream(response.getOutputStream());     
  144.   
  145.             for(int i = temp-1;i>0;i--){  
  146.                 //System.out.println("=:"+path+csvFileName+i+fileExtension);  
  147.                 fis = new FileInputStream(path+csvFileName+i+fileExtension);  
  148.                 ZipEntry z1 = new ZipEntry(csvFileName+temp+fileExtension);  
  149.                 zos.putNextEntry(z1);  
  150.                 byte[] b = new byte[1024];  
  151.                 while((leng = fis.read(b))!=-1){  
  152.                     zos.write(b,0,leng);  
  153.                 }  
  154.             }  
  155.             zos.close();  
  156.             fis.close();  
  157.               
  158.         } catch (Exception e) {  
  159.             throw new DataAccessException(e);  
  160.         } finally {  
  161.             // 释放资源  
  162.             try {  
  163.                 if(response.getOutputStream() != null)  
  164.                     response.getOutputStream().close();  
  165.             } catch (IOException e2) {  
  166.                 e2.printStackTrace();  
  167.             }  
  168.             try {  
  169.                 if(zos!=null){  
  170.                     try {  
  171.                         zos.close();  
  172.                     } catch (IOException e) {  
  173.                         e.printStackTrace();  
  174.                     }  
  175.                     zos = null;  
  176.                 }  
  177.                 if(fis!=null){  
  178.                     try {  
  179.                         fis.close();  
  180.                     } catch (IOException e) {  
  181.                         e.printStackTrace();  
  182.                     }  
  183.                     fis = null;  
  184.                 }  
  185.                   
  186.                 if(writer!=null){  
  187.                     try {  
  188.                         writer.close();  
  189.                     } catch (IOException e) {  
  190.                         e.printStackTrace();  
  191.                     }  
  192.                     writer = null;  
  193.                 }  
  194.                 if (result != null) {  
  195.                     result.close();  
  196.                     result = null;  
  197.                 }  
  198.                 if (preparedStatement != null) {  
  199.                     preparedStatement.close();  
  200.                     preparedStatement = null;  
  201.                 }  
  202.                   
  203.             } catch (SQLException e1) {  
  204.                 throw new DataAccessException(e1);  
  205.             }  
  206.         }  
  207.       
  208.           
  209.     }  
  210.     public void deleteCsvFiles(String path,String fileName){  
  211.           
  212.     }  
  213.       
  214.     //如果导出内容小于6000条,那么导出excel格式;如果导出内容大于6000条,那么导出cvs格式,然后再压缩。  
  215.     public boolean ExportToExcel(int resultCountAll){  
  216.         boolean exportExcel = false;  
  217.         if(resultCountAll<6000){  
  218.             exportExcel = true;  
  219.         }  
  220.         return exportExcel;  
  221.     }  
  222.     public String getZipSm() {  
  223.         return zipSm;  
  224.     }  
  225.     public void setZipSm(String zipSm) {  
  226.         this.zipSm = zipSm;  
  227.     }  
  228. }  
0 0
原创粉丝点击