小石头
Excellence in any department can be attained only by the labor of a lifetime; it is not to be purchased at a lesser price.
posts - 91,comments - 22,trackbacks - 0

      以前公司在做下载数据的时候,主要是用以下这种方式:

      response.setContentType("APPLICATION/OCTET-STREAM");

      response.setHeader("Content-Disposition", "attachment; filename=\""+ Chinese.toPage(fileName) + "\"");


      但这有个不好的就是它只能打开一个EXCEL的一个工作簿,如果数据量非常大的话,后面的数据会丢失,根据这个BUG,我重新做了一个动态生成EXCEL工作薄的例子,以方便后面对此应用的改造。

 首先从数据库里取数据的时候,不知道行,列,这样就需要一个动作,把RS转换成一个VECTOR,此对象里每一行也是一个VECTOR
  public static Vector ResultSetToVector(ResultSet rs) {
    try {
      Vector rows = new Vector();
      ResultSetMetaData rsmd = rs.getMetaData();
      Vector columnHeads = new Vector();

      for (int i = 1; i <= rsmd.getColumnCount(); i++) {
        columnHeads.addElement(rsmd.getColumnName(i));
      }

      Vector currentRow;
      while(rs.next()){
        currentRow = new Vector();
        for (int i = 1; i <= rsmd.getColumnCount(); i++) {
          currentRow.addElement(Chinese.fromDatabase(rs.getString(i)));
        }
        rows.addElement(currentRow);
      }
      return rows;
    }
    catch (Exception err) {
      Log.printError(err, "", "", log);
      return null;
    }
    finally{
      try {
        if(rs!=null){
          rs.close();
          rs = null;
        }
      }
      catch (Exception ex) {
      }
    }

 再通过写一个方法,把VECTOR的值放到EXCEL里去。
   ResultSetMetaData rmeta = rs.getMetaData();
   int numColumns = rmeta.getColumnCount();//取多少行
   String fileNametemp = "c:\\"+fileName;
   fileNametemp = fileNametemp.substring(0,fileNametemp.lastIndexOf("."))+CTime.getTime(12)+".xls";
   
   java.io.File file = new java.io.File(fileNametemp);
   if (file.exists()) {
    file.delete();
   }
   String rows_temp = request.getParameter("rows");//页面传过来的每个SHEET可以存放的条数
   if (rows_temp == null){
    rows_temp = "20000";// 一个表单默认20000行。
   }
   int count_rows = Integer.parseInt(rows_temp);
   WritableWorkbook wb = Workbook.createWorkbook(file);
     
    Vector v_Rs = RsToVector.ResultSetToVector(rs);// 把RS的值转换成VECTOR
   boolean fg = true;    
    if (v_Rs != null) {
    int a = v_Rs.size();    
    int sheet_count = a / count_rows;    
    if (sheet_count >0){//大于0,则需要多个SHEET
     for (int i = 0;i<sheet_count;i++){
      Vector temp_v = new Vector();
      for (int b = i* count_rows ;b<(i+1) * count_rows ;b++){
       
       temp_v.add(v_Rs.get(b));
      }      
      writeExcel(wb,"sheet"+i,temp_v,numColumns,sheet_count);//EXCEL对象、单元薄名、数据、行数、第几个单元薄      
     }    
     
     if (sheet_count * count_rows < a){//不是正好,还有剩余
      Vector temp_vv = new Vector();
      for (int c = sheet_count* count_rows ;c<a ;c++){       
       temp_vv.add(v_Rs.get(c));
      }
      writeExcel(wb,"sheet"+(sheet_count+1),temp_vv,numColumns,sheet_count+1);//EXCEL对象、单元薄名、数据、行数、第几个单元薄 
     }
    }else{
     writeExcel(wb,"sheet"+sheet_count,v_Rs,numColumns,0);//EXCEL对象、单元薄名、数据、行数、第几个单元薄 
    }
    fg = true;
   }else{
    fg = false;
   }
   wb.write();
   wb.close();
   String msgs = "";
   PrintWriter out = response.getWriter();
   if (fg){
    msgs = "保存的文件名是"+fileNametemp;
    msgs = Chinese.toPage(msgs);    
   }else{
    msgs = Chinese.toPage("没有数据导出!");    
   }
   int seg = msgs.indexOf(":");
   msgs = msgs.substring(0,seg)+":\\"+msgs.substring(seg+1,msgs.length());
   out.println("<script>alert('"+msgs+"');window.close();</script>");


   
写EXCLE的方法
   /**
     * 写Excel文件
     * @param filepath String
     * @param sheetname String  工作簿名称
     * @param list Vector   内容
     * @param colum int     列数
     * @return boolean
     */
 private boolean writeExcel(WritableWorkbook wb ,String sheetname,
   Vector list, int colum,int count) {
  String temp = "";
  String[] s;
  int i = 0;
  try {
   if (list == null) {
    return false;
   }
   
   WritableSheet ws = wb.createSheet(sheetname, count);
   if (colum == 1) {
    while (i != list.size() && list.size() > 0) {
     temp = (String) list.get(i);
     Label labelC = new Label(i, 0, temp);
     ws.addCell(labelC);
     i++;
    }
   } else {
    while (i != list.size() && list.size() > 0) {
     //s = (String[]) list.get(i);
     Vector tm = (Vector) list.get(i);
     if (tm == null) {
      continue;
     } else {
      int kk = tm.size();
      for (int j = 0; j < kk; j++) {
       temp = (String)tm.get(j);
       Label labelC = new Label(j, i, temp);
       ws.addCell(labelC);
      }
     }
     i++;
    }
   }
  } catch (Exception ex) {
   Log.printError(ex, "写excel文件错误", "", "writeexcel.log");
   return false;
  }
  return true;
 }



以上方法也有一个问题,就是当程序写100000条数据以后,速度会慢下来,我看了WritableWorkbook 的构造方法的时候,可以生成一个OUTPUTSTREAM对象的,我想可以用这个来做,速度可能会上去,但具体也没有试,如何有哪位哥们试过了,把性能跟兄弟分享一下!谢谢了!

转自 : http://www.blogjava.net/wujiaqian/archive/2006/12/08/86269.html

posted on 2007-01-08 15:35 小石头 阅读(518) 评论(0)  编辑  收藏 所属分类: 转载区我的java学习

只有注册用户登录后才能发表评论。


网站导航: