工程需要导出百万条数据到excel,但是大概在6W条数据的时候就崩掉了,请各位大神帮忙下,提个可行性方法,
最好能有代码例子。

解决方案 »

  1.   

    xls吧
    用的什么操作excel?POI?
    试试分sheet来导
      

  2.   

    我们以前导出大批量数据到excel中的时候,分页查询用流输出,循环导入到excel中,知道没有数据。
    不过导入到excel要注意一个问题,excel的一个sheet最多能放65536行数据,在导出的时候要注意分sheet
      

  3.   

    1.xls  一个sheet有行数限制 最多是 65536, 所以如果你一定要用xls的话 那当行数超过这个限制的时候你需要分sheet
    2.xlsx 也是有限制的 好像是150万左右
    3.如果你的数据不会超150万建议导出到csv 然后用可以用excel 2007+打开
      

  4.   


    更正:xlsx的行数上限是 1048576
      

  5.   

    内存溢出怎么解决,虽然有sheet,但是jxl的write只能执行一次,也就是说,只能在最后才可以write.
    但是内存没办法存放那么多数据。
      

  6.   

    先查询出满足条件的总数据条数
    在每次查询出6w分别写入sheet
      

  7.   

       这么大的数据 如果没有其他的业务转化(java介入),就直接使用数据库能提供的方式来解决
       如果需要用java来介入的,可以使用JDBC批量处理
      

  8.   

    怎么分别写入,write只能执行一次,执行之后就失去效果了,所以虽然每查询6W写入sheet,但是数据还是放在缓存里面啊,
      

  9.   

    我写个8-9W分页什么的,轻轻松松的,但是40-50W就connect time out  了
      

  10.   

    跟什么连接超时了? 你实再要导成XLS格式的,只能分批执行。 数据太大内在溢出的话,可以导成多个文件。就不存在write完不好操作的问题。要是实再要导成一个文件多个sheet中的话。那每6w数据写一次。完了。再打开它,操作它的下一个sheet。
      

  11.   

    在6w的時候,什麽崩潰了?outofmemory?
      

  12.   


    public class AssociatorExcelOrWordAction extends QueryRestrictedAction<UserInfo> {    private List<UserInfo> associatorLi = new ArrayList<UserInfo>();
        public String execute() throws Exception { HttpServletResponse response = ServletActionContext.getResponse();


    OutputStream os = new FileOutputStream("F:\\ceshi.xls" );
            String un = getParam("un");
            String ph = getParam("ph");
            String downtype = getParam("downtype");
            String email = getParam("email");
            String minDate = getParam("minDate");
            String maxDate = getParam("maxDate");
            
           List<String[]> data = null; // 导出数据 List<String> title = new ArrayList<String>(); // 导出EXCEL 标题        QueryUserEvt queryEvt = new QueryUserEvt();        if (null != un && !"".equals(un)) {
                queryEvt.setNickname(un);
            }
            if (null != ph && !"".equals(ph)) {
                queryEvt.setPhoneNumber(ph);
            }
            if(null != email && !"".equals(email)){
             queryEvt.setEmail(email);
            }
    if (null != minDate && !"".equals(minDate)) {
    queryEvt.setMinCreateDate(DateUtil.getZoneHour(DateUtil.stringConvertDate(DateUtil.SHORT_FORMAT_PATTERN, minDate)));
    }
    if (null != maxDate && !"".equals(maxDate)) {
    queryEvt.setMaxCreateDate(DateUtil.getZoneHour(DateUtil.stringConvertDate(DateUtil.SHORT_FORMAT_PATTERN, maxDate)));
    }
            queryEvt.setQueryType(QueryType.QUERY_NUM.getValue());
            int count = ServiceFactory.getUserService().queryUser(queryEvt).getRecordSum();
            
    title.add("用户ID");
    title.add("昵称");
    title.add("手机号码");
    title.add("邮箱");
    title.add("注册时间");
         int  length = count/30000;
         if(count%30000>0){
         length++;
         }
         int  num = 0;
    WritableWorkbook book = Workbook.createWorkbook(os);// 生成Excel文件
    Label label = null;
         for (int i = 0; i <length; i++) {
             data = ServiceFactory.getUserService().queryExportUser(queryEvt,i*30000+1,(i+1)*30000);
             if (data == null || data.size() == 0) {
              return "download";
             }else{
             if (os != null) {
             WritableSheet ws = null;
             try {
             if (title == null || title.size() == 0) {
             return "download";
             }
             ws = book.createSheet("会员记录"+num, num);
                         num++;
             // 添加标题
             for (int j = 0; j < title.size(); j++) {
             label = new Label(j, 0, title.get(j),
             getHeaderCellStyle());
             ws.addCell(label);
             if (j == 5) {
             ws.setColumnView(j, 70);
             } else {
             ws.setColumnView(j, 20);
             }         }         // 添加excel数值
             int flag = 1;
             for (String[] temp : data) {
             for (int j = 0; j < temp.length; j++) {
             label = new Label(j, flag, temp[j]);
             ws.addCell(label);
             }
             flag++;
             }
             os.flush();
    } catch (IOException e) {
    e.printStackTrace();
    } catch (RowsExceededException e) {
    e.printStackTrace();
    } catch (WriteException e) {
    e.printStackTrace();
    }
    }else{
    return "download";
    }
             }
             //exportExcel(os, data, title,num);
         }
    book.write();
    book.close();
    os.close();
    return "download";
        }
    private  WritableCellFormat getHeaderCellStyle() { /*
     * WritableFont.createFont("宋体"):设置字体为宋体 10:设置字体大小
     * WritableFont.BOLD:设置字体加粗(BOLD:加粗 NO_BOLD:不加粗) false:设置非斜体
     * UnderlineStyle.NO_UNDERLINE:没有下划线
     */
    WritableFont font = new WritableFont(WritableFont.createFont("宋体"), 11,
    WritableFont.BOLD, false, UnderlineStyle.NO_UNDERLINE); WritableCellFormat headerFormat = new WritableCellFormat(
    NumberFormats.TEXT);
    try {
    // 添加字体设置
    headerFormat.setFont(font);
    // 设置单元格背景色:表头为黑色
    headerFormat.setBackground(Colour.YELLOW);
    // 设置表头表格边框样式
    // 整个表格线为粗线、黑色
    headerFormat.setBorder(Border.ALL, BorderLineStyle.THICK,
    Colour.BLACK);
    // 表头内容水平居中显示
    headerFormat.setAlignment(Alignment.CENTRE);
    } catch (WriteException e) {
    e.printStackTrace();
    }
    return headerFormat;
    }



    public InputStream getInputStream() throws Exception{
    return new FileInputStream(new File("F:\\ceshi.xls"));
    }

        public List<UserInfo> getAssociatorLi() {
            return associatorLi;
        }
        public void setAssociatorLi(List<UserInfo> associatorLi) {
            this.associatorLi = associatorLi;
        }
    }
    求解
      

  13.   

    操作excel能否定位到具体的某一行?是否可以定位第1到第10w然后定位第10w零1到20w行以此类推分成多段 分批导入 例如 第一个方法(){
     读1到10w
     然后插入数据库

         第二个方法()(){
     读10w零1到20w
     然后插入数据库

      

  14.   

    03版的也就是以xls结尾的最多是65536行数据,07版xlsx是1048576。
    这也就是为什么你导出到6w多的时候会报错了。
    所以你需要分开导出。
    怎么分开,有两类方法。
    1.按照类别来,比如月份、日期、部门等分类,但是也会出现一个月份超出65536的情况。
    2.就按照行数来,超出65536的就用下一个sheet来导出。这个在函数中很好实现的,一个for搞定。
    所以,楼主,就不需要纠结了。
      

  15.   

    03版的excle确实是有数量限制的,要是放到多个文件中能行不
      

  16.   


    请看代码,我已经分开多个sheet导了,但是数据量超过20W的时候还是会出错