我写了一个数据库导出到Excel表格的Java代码,但是导出速度很慢,有没有大神帮看一下

时间:2022-12-11 15:23:53
代码如下
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

    //将数据库的数据导出到Excel
public class Test {

/*****可修改部分start******/
//导出的表名
public static String tables="demo";
                //sql语句
public static String sqls="select top 500 * from (select dh.dh_org_id, dh.dh_carrier_id, dh.chengyunshangdanhao, dh.billid as dhbillid, dh.dh_dispatch_no, dh.dh_truck_license_no, dh_primary_driver, dh.dh_primary_tel, dh.peisongzurenyuan, dh.lianxidianhua, dh.cheliangleixing as dh_cheliangleixing, dh.dh_dispatch_datetime, DH_DEPART_DATETIme, dh.yujiwanchengshijian as dh_yujiwanchengshijian, dh.dh_start_area_id, dh.dh_end_area_id, dh.yunshufangshi_2 as dh_yunshufangshi, dh.yunzuofangshi, dh.DH_TRAILER_LICENSE_NO, dh.status as dhstatus, clh_consign_header_id, clh_logistics_no, clh_logistics_header_id, clh_consign_no, clh_consign_datetime , clh.billid as clhbillid, clh_cargo_load_no, clh.kehuyaoqiuwanchengshijian as clh_kehuyaoqiuwanchengshijian, clh_consigner_id, clh_consigner_no, clh_emergency_degree_id, clh_settle_method_id, clh.kehu as clh_kehu, clh.kehudanhao as clh_kehudanhao, clh_load_address, clh_load_area_id, clh_unload_area_id, CLH_UNLOAD_CONTACT, CLH_UNLOAD_UNIT_NAME, clh_unload_address, clh.tuopanshu as clh_tuopanshu, clh_total_packs, clh_total_cubage, clh_total_gross_weight, clh.zhuyaowuliaoleibie as clh_zhuyaowuliaoleibie, clh.status as clhstatus, clt.cltl_trace_datetime as trace_datetime, clt.cltl_location as location, clt.cltl_speed as speed, convert(varchar(50), CLH_DEPART_DATETIME) + '..到达..' +  (select name from cp_area a where a.id = clh_load_area_id) + '..正在....从.' +  (select name from cp_area a where a.id = clh_load_area_id) + ' .>>>.' + (select name from cp_area a where a.id = clh_unload_area_id) as trace_remark,  1 as shifoukejian,  '在途..CL' as info_flag from tm_dispatch_cargo_load_l dcll inner join tm_dispatch_h dh on dcll.billid = dh.billid   right outer join tm_cargo_load_h clh on dcll.dcll_cargo_load_header_id = clh.billid  inner join tm_cargo_load_trace_l clt on clh.billid=clt.billid where clh.status = 84  union all select dh.dh_org_id, dh.dh_carrier_id, dh.chengyunshangdanhao, dh.billid as dhbillid, dh.dh_dispatch_no, dh.dh_truck_license_no, dh_primary_driver, dh.dh_primary_tel, dh.peisongzurenyuan, dh.lianxidianhua, dh.cheliangleixing as dh_cheliangleixing, dh.dh_dispatch_datetime, DH_DEPART_DATETIme, dh.yujiwanchengshijian as dh_yujiwanchengshijian, dh.dh_start_area_id, dh.dh_end_area_id, dh.yunshufangshi_2 as dh_yunshufangshi, dh.yunzuofangshi, DH_TRAILER_LICENSE_NO, dh.status as dhstatus, clh_consign_header_id, clh_logistics_no, clh_logistics_header_id, clh_consign_no, clh_consign_datetime , clh.billid as clhbillid, clh_cargo_load_no, clh.kehuyaoqiuwanchengshijian as clh_kehuyaoqiuwanchengshijian, clh_consigner_id, clh_consigner_no, clh_emergency_degree_id, clh_settle_method_id, clh.kehu as clh_kehu, clh.kehudanhao as clh_kehudanhao, clh_load_address, clh_load_area_id, clh_unload_area_id, CLH_UNLOAD_CONTACT, CLH_UNLOAD_UNIT_NAME, clh_unload_address, clh.tuopanshu as clh_tuopanshu, clh_total_packs, clh_total_cubage, clh_total_gross_weight, clh.zhuyaowuliaoleibie as clh_zhuyaowuliaoleibie, clh.status as clhstatus, cls.dtl_trace_datetime , cls.dtl_location, cls.dtl_speed, convert(varchar(50), CLH_DEPART_DATETIME) + '..到达..' +  (select name from cp_area a where a.id = clh_load_area_id) + '..正在....从.' +  (select name from cp_area a where a.id = clh_load_area_id) + ' .>>>.' + (select name from cp_area a where a.id = clh_unload_area_id) as trace_remark,  1 as shifoukejian,  '在途..DH' as info_flag from tm_dispatch_cargo_load_l dcll inner join tm_dispatch_h dh on dcll.billid = dh.billid   right outer join tm_cargo_load_h clh on dcll.dcll_cargo_load_header_id = clh.billid  inner join tm_dispatch_trace_l cls on dcll.billid=cls.billid where not exists(select * from tm_cargo_load_trace_l a where a.billid = clh.billid)  and clh.status = 84  union all select dh.dh_org_id, dh.dh_carrier_id, dh.chengyunshangdanhao, dh.billid as dhbillid, dh.dh_dispatch_no, dh.dh_truck_license_no, dh_primary_driver, dh.dh_primary_tel, dh.peisongzurenyuan, dh.lianxidianhua, dh.cheliangleixing as dh_cheliangleixing, dh.dh_dispatch_datetime, DH_DEPART_DATETIme, dh.yujiwanchengshijian as dh_yujiwanchengshijian, dh.dh_start_area_id, dh.dh_end_area_id, dh.yunshufangshi_2 as dh_yunshufangshi, dh.yunzuofangshi, DH_TRAILER_LICENSE_NO, dh.status as dhstatus, clh_consign_header_id, clh_logistics_no, clh_logistics_header_id, clh_consign_no, clh_consign_datetime , clh.billid as clhbillid, clh_cargo_load_no, clh.kehuyaoqiuwanchengshijian as clh_kehuyaoqiuwanchengshijian, clh_consigner_id, clh_consigner_no, clh_emergency_degree_id, clh_settle_method_id, clh.kehu as clh_kehu, clh.kehudanhao as clh_kehudanhao, clh_load_address, clh_load_area_id, clh_unload_area_id, CLH_UNLOAD_CONTACT, CLH_UNLOAD_UNIT_NAME, clh_unload_address, clh.tuopanshu as clh_tuopanshu, clh_total_packs, clh_total_cubage, clh_total_gross_weight, clh.zhuyaowuliaoleibie as clh_zhuyaowuliaoleibie, clh.status as clhstatus, CLH_DEPART_DATETIME as trace_datetime ,  '途中...' as location,  0 as speed, convert(varchar(50), CLH_DEPART_DATETIME) + '..到达..' +  (select name from cp_area a where a.id = clh_load_area_id) + '..正在....从.' +  (select name from cp_area a where a.id = clh_load_area_id) + ' .>>>.' + (select name from cp_area a where a.id = clh_unload_area_id) as trace_remark,  1 as shifoukejian,  '在途..AL' as info_flag from tm_dispatch_cargo_load_l dcll   inner join tm_dispatch_h dh on dcll.billid = dh.billid   right outer join tm_cargo_load_h clh on dcll.dcll_cargo_load_header_id = clh.billid where not exists(select * from tm_cargo_load_trace_l a where a.billid = clh.billid) and   not exists(select * from tm_dispatch_trace_l a where a.billid = dcll.billid) and clh.status = 84)a";

//导出表的csv文件保存的地址
public static String outputFile="D:/beiye.xls";

//数据库
public static String url = "jdbc:sqlserver://127.0.0.1;database=boyolsys;";
public static String username = "sa";
public static String password = "111111";
/*****可修改部分     end******/

public static String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
public static Connection con = null;

public static void main(String[] args){
try {
Class.forName(driver);
con = DriverManager.getConnection(url,username,password);
} catch (ClassNotFoundException classE) {
classE.printStackTrace();
} catch (SQLException sqlE) {
sqlE.printStackTrace();
}
outPutTable();
}
/**
 * 功能描述:把数据库中的表导出,生成csv文件
 * @return
 * @ 2016-9-8
 */
public static void outPutTable(){
long a=System.currentTimeMillis();
PreparedStatement ps_struts = null;
ResultSet rs_struts = null;
try{
HSSFWorkbook workbook = new HSSFWorkbook();

String[] tempo ;
int rowNum=1;
try {
ps_struts=con.prepareStatement(sqls);
rs_struts = ps_struts.executeQuery();
ResultSetMetaData rsm = rs_struts.getMetaData();
HSSFSheet sheet = workbook.createSheet(tables);
int columnCount = rsm.getColumnCount();
try{
HSSFRow row1 = sheet.createRow(0);
for (int i = 1; i <=columnCount; i++) {
sheet.autoSizeColumn(i); 
String columnName=rsm.getColumnName(i); 
HSSFCell cell1 = row1.createCell(i-1);
cell1.setCellValue(columnName);
}
/*FileOutputStream fOut = new FileOutputStream(outputFile);
workbook.write(fOut);
fOut.flush();
fOut.close();*/
    }catch(Exception e) {
   System.out.println("已运行 outPutTable (): " + e );
    }
while(rs_struts.next()){
HSSFRow row = sheet.createRow(rowNum);
tempo = new String[columnCount];
for (int i = 0; i <columnCount; i++) {
HSSFCell cell = row.createCell(i);
sheet.autoSizeColumn(i); 
String columnName=rs_struts.getMetaData().getColumnName(i+1);                        
tempo[i]  = rs_struts.getString(columnName);
cell.setCellValue(tempo[i]);                        
}
tempo = null;
rowNum++;
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}

FileOutputStream fOut = new FileOutputStream(outputFile);
    workbook.write(fOut);
    fOut.flush();
    fOut.close();
    }catch(Exception e) {
   System.out.println("已运行 outPutTable (): " + e );
    }
System.out.println( "-----------------表开始导出完成!-------------------");
System.out.println("耗时:"+(System.currentTimeMillis()-a)/1000f+"秒");

}

12 个解决方案

#1


导出的数据量有多大,导出用时是多少,也就是说慢到什么程度?你想达到的速度是多少?描述下!因为jxl导出excel确实速度一般,但是一般的项目够用了。

#2


引用 1 楼 u013185616 的回复:
导出的数据量有多大,导出用时是多少,也就是说慢到什么程度?你想达到的速度是多少?描述下!因为jxl导出excel确实速度一般,但是一般的项目够用了。

非常慢,500行的数据,大概七八十列,导出就要5分钟,但是总数据有30万行。

#3


引用 2 楼 l334175100 的回复:
非常慢,500行的数据,大概七八十列,导出就要5分钟,但是总数据有30万行。


500行用5分钟,不太可能,再慢也不会那么慢,可以看看你的数据库的问题。

另外,30万行,7,80列,不要再用jxl或poi导出了,会疯掉的。

你看看这个文章,具体我也没操作过,希望能帮助你:http://blog.csdn.net/u011728105/article/details/47147225

#4


引用 3 楼 u013185616 的回复:
Quote: 引用 2 楼 l334175100 的回复:

非常慢,500行的数据,大概七八十列,导出就要5分钟,但是总数据有30万行。


500行用5分钟,不太可能,再慢也不会那么慢,可以看看你的数据库的问题。

另外,30万行,7,80列,不要再用jxl或poi导出了,会疯掉的。

你看看这个文章,具体我也没操作过,希望能帮助你:http://blog.csdn.net/u011728105/article/details/47147225

谢谢,我看看

#5


还有大神吗 我写了一个数据库导出到Excel表格的Java代码,但是导出速度很慢,有没有大神帮看一下

#6


30万数据为什么要自己写程序导出Excel呢,客户要这个功能吗
数据处理用PL/SQL等现成的工具就可以导成Excel

#7


个人觉得先写一个excel模板,然后再把查出来的数据写入模板中,效率可能会高些。

#8


package cn.com.hime.ImpI;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import cn.com.hime.model.Student;

import jxl.Workbook;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

public class excel {

/**
 * @param args
 */
public static void main(String[] args) {
//输出的excel文件工作表名 
String[] title = {"编号","姓名","简介"};//excel工作表的标题
//输出的excel文件名 
String worksheet = "student";
String targetfile = "c:/out.xls";
List<Student> list=new ArrayList<Student>();
Student st=new Student();
st.setId("1");
st.setNAME("李斯");
st.setDESCRIB("学生");
st.setId("8");
st.setNAME("李斯");
st.setDESCRIB("学生");
Student st1=new Student();
st1.setId("1");
st1.setNAME("李斯1");
st1.setDESCRIB("学生1");
Student st2=new Student();
st2.setId("2");
st2.setNAME("李斯2");
st2.setDESCRIB("学生2");
Student st3=new Student();
st3.setId("3");
st3.setNAME("李斯3");
st3.setDESCRIB("学生3");
Student st7=new Student();
st7.setId("7");
st7.setNAME("李斯7");
st7.setDESCRIB("学生7");
Student st4=new Student();
st4.setId("4");
st4.setNAME("李斯4");
st4.setDESCRIB("学生4");
Student st5=new Student();
st5.setId("5");
st5.setNAME("李斯5");
st5.setDESCRIB("学生5");
Student st6=new Student();
st6.setId("6");
st6.setNAME("李斯6");
st6.setDESCRIB("学生6");
list.add(st);
list.add(st1);
list.add(st2);
list.add(st3);
list.add(st4);
list.add(st5);
list.add(st6);
list.add(st7);
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
 System.out.println("时间:"+new Date());
 
 System.out.println("时间2:"+dateFormat.format(new Date()));
 String str="2016-06-26";
   try {
System.out.println(dateFormat.parse(str));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

 
//export(title,worksheet,targetfile,list);
}
public static void export(String [] title,String worksheet,String targetfile,List<Student> list){

WritableWorkbook workbook;
try {  
//创建可写入的Excel工作薄,运行生成的文件在tomcat/bin下   
//workbook = Workbook.createWorkbook(new File("output.xls")); 

System.out.println("begin");
OutputStream os=new FileOutputStream(targetfile);   
workbook=Workbook.createWorkbook(os); 
WritableSheet sheet = workbook.createSheet(worksheet, 0); 

jxl.write.Label label; 
int mm=0;
// 跟据head创建表头
for (int i=0; i<title.length; i++){  
//Label(列号,行号 ,内容 )   
label = new jxl.write.Label(i, 0, title[i]); 
sheet.addCell(label);    
}
if(list!=null){
// 循环插入数据
int sheetname1=1;//用于自动化创建名字
int record=0;//计算记录
int rownumb=1;
for (int j = 0; j < list.size();j++) {
rownumb++;
if(record%3==0){
rownumb=0;
sheet = workbook.createSheet(worksheet+sheetname1, 0);
// 跟据head创建表头
jxl.write.Label labe_1; 
for (int i=0; i<title.length; i++){  
//Label(列号,行号 ,内容 )   
labe_1 = new jxl.write.Label(i, 0, title[i]); 
sheet.addCell(labe_1);    
}
sheetname1++;
}
//添加数字    
//Iterator it=(Iterator) list.get(mm);
//for(int m=0; m<title.length; m++){
Student bts =(Student) list.get(j);
jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES,10,WritableFont.BOLD,true); 
jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf);    
jxl.write.Label labelCI = new jxl.write.Label(0,rownumb+1,bts.getId(),wcfF);
jxl.write.Label labelCN = new jxl.write.Label(1,rownumb+1,bts.getNAME(),wcfF); 
jxl.write.Label labelCD = new jxl.write.Label(2,rownumb+1,bts.getDESCRIB(),wcfF); 
sheet.addCell(labelCI); 
sheet.addCell(labelCN);
sheet.addCell(labelCD);

//}
record++;
}

}

//添加带有字型Formatting的对象   
/* jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES,10,WritableFont.BOLD,true); 

jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf);    
jxl.write.Label labelCF = new jxl.write.Label(4,4,"文本",wcfF);    
sheet.addCell(labelCF); */   
//添加带有字体颜色,带背景颜色 Formatting的对象   

/*jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL,10,WritableFont.BOLD,false,jxl.forma         t.UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.RED);    
jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc);    
wcfFC.setBackground(jxl.format.Colour.BLUE);   
jxl.write.Label labelCFC = new jxl.write.Label(1,5,"带颜色",wcfFC);    
sheet.addCell(labelCFC); */

//添加带有formatting的Number对象    
/*jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##");    
jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf);   
jxl.write.Number labelNF = new jxl.write.Number(1,1,3.1415926,wcfN);  
sheet.addCell(labelNF);  */  

//3.添加Boolean对象    
/*jxl.write.Boolean labelB = new jxl.write.Boolean(0,2,false);    
sheet.addCell(labelB);  */ 

//4.添加DateTime对象    
/*jxl.write.DateTime labelDT = new jxl.write.DateTime(0,3,new java.util.Date());    
sheet.addCell(labelDT);  */

//添加带有formatting的DateFormat对象   
/*jxl.write.DateFormat df = new jxl.write.DateFormat("ddMMyyyyhh:mm:ss");  
jxl.write.WritableCellFormat wcfDF = new jxl.write.WritableCellFormat(df); 
jxl.write.DateTime labelDTF = new jxl.write.DateTime(1,3,new java.util.Date(),wcfDF);   
sheet.addCell(labelDTF);  */
//设置边框   
/*jxl.write.WritableCellFormat wcsB = new jxl.write.WritableCellFormat();   
wcsB.setBorder(jxl.format.Border.ALL,jxl.format.BorderLineStyle.THICK);  
labelCFC = new jxl.write.Label(0,6,"边框设置",wcsB);    
sheet.addCell(labelCFC);  */ 
workbook.write();    
workbook.close(); 

}catch(Exception e){
e.printStackTrace();
}

System.out.println("end");   
Runtime r=Runtime.getRuntime();    
Process p=null;     
String cmd[]={"C:\\","out.xls"}; 

try {
p=r.exec(cmd);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("error executing: "+cmd[0]);    
}

}

}

楼主你可以看下这个代码分多个sheet到出数据测试过可以导出30万条数据。  希望可以帮助到

#9


你先看看是不是查询数据库哪块速度如何,如果可以的话,就是导出代码哪块调整了。。。
个人感觉可能你的查询比较慢。。你先观察哪块性能瓶颈才能根据他做调整。。
如果查询慢,要调整查询,并一次放在内存中。以便后继适应。。
如果导出慢,应该io问题,要调整io性能。

#10


首先排除是否是数据库查询原因,其次在看代码

#11


只能说个方向,你这是SQL过于复杂,SQL查询慢,请把SQL语句直接放在SQL server客户端执行看效果,并不是JAVA的问题

#12


主要有两个地方耗时比较长, 一是SQL取数据, 可以单独把SQL拿出来在命令行运行一下用时多少. 另一个就是autoSizeColumn, api描述说数据较大时耗时非常大, 建议在结果的时候调用一次.
我测试了一下65536条数据就算放在最后autoSizeColumn也根本200多秒. 所以就重新修改了一下, 不调用autoSizeColumn, 而是自己记录每一列最大的值, 最后只用计算最大的列值长度是多少即可, (PS. autoSizeColumn会遍历每一列的每行数据取最大的列长度). 
    /**
     * 功能描述:把数据库中的表导出,生成csv文件
     *
     * @return
     * @ 2016-9-8
     */
    public void outPutTable() {
        long a = System.currentTimeMillis();
        Connection con = null;
        PreparedStatement ps_struts = null;
        ResultSet rs_struts = null;
        int rowNum = 1;
        try {
            HSSFWorkbook workbook = new HSSFWorkbook();
            con = dataSource.getConnection();
            ps_struts = con.prepareStatement("select * from t_item limit 65535");
            rs_struts = ps_struts.executeQuery();
            ResultSetMetaData rsm = rs_struts.getMetaData();
            HSSFSheet sheet = workbook.createSheet("sheet1");
            int columnCount = rsm.getColumnCount();
            int[] cell_size = new int[columnCount];
            int[] max_row = new int[columnCount];
            HSSFRow row1 = sheet.createRow(0);
            for (int i = 1; i <= columnCount; i++) {
                String columnName = rsm.getColumnName(i);
                cell_size[i-1] = columnName.getBytes().length;
                max_row[i-1] = 0;
                HSSFCell cell1 = row1.createCell(i - 1);
                cell1.setCellValue(columnName);
            }

            while (rs_struts.next()) {
                HSSFRow row = sheet.createRow(rowNum);
                for (int i = 0; i < columnCount; i++) {
                    HSSFCell cell = row.createCell(i);
                    // 这三句非常耗时间, 尤其是autoSizeColumn不应该在这里调用
                    // 上面的列是按序取的, 下面的结果按序取就一一对应了没有必要先取name再根据name取值
//                    sheet.autoSizeColumn(i);
//                    String columnName=rs_struts.getMetaData().getColumnName(i+1);
//                    tempo[i]  = rs_struts.getString(columnName);
                    String value = rs_struts.getString(i + 1);
                    int byte_len = value.getBytes().length;
                    if (byte_len > cell_size[i]) {
                        cell_size[i] = byte_len;
                        max_row[i] = rowNum;
                    }
                    cell.setCellValue(value);
                }
                rowNum++;
            }

            resize(sheet, max_row);

            FileOutputStream fOut = new FileOutputStream("f:/temp/t_item.xls");
            workbook.write(fOut);
            fOut.flush();
            fOut.close();
        } catch (Exception e) {
            System.out.println("已运行 outPutTable (): " + e);
        } finally {
            if (rs_struts != null) {
                try {
                    rs_struts.close();
                } catch (SQLException e) {
                }
            }
            if (ps_struts != null) {
                try {
                    ps_struts.close();
                } catch (SQLException e) {
                }
            }
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException e) {
                }
            }
        }
        System.out.println("-----------------表开始导出完成!-------------------");
        System.out.println("共计" + (rowNum-1) +"行数据,耗时:" + (System.currentTimeMillis() - a) + "毫秒");
    }

    private static final char defaultChar = '0';
    private static final FontRenderContext fontRenderContext = new FontRenderContext(null, true, true);

    void resize(Sheet sheet, int[] max_row) {
        resize(sheet, false, max_row);
    }
    void resize(Sheet sheet, boolean useMergedCells, int[] max_row) {
        AttributedString str;
        TextLayout layout;

        Workbook wb = sheet.getWorkbook();
        DataFormatter formatter = new DataFormatter();
        Font defaultFont = wb.getFontAt((short) 0);

        str = new AttributedString(String.valueOf(defaultChar));
        copyAttributes(defaultFont, str, 0, 1);
        layout = new TextLayout(str.getIterator(), fontRenderContext);
        int defaultCharWidth = (int)layout.getAdvance();
        for (int i = 0; i < max_row.length; i++) {
            Cell cell = sheet.getRow(max_row[i]).getCell(i);
            double width = SheetUtil.getCellWidth(cell, defaultCharWidth, formatter, useMergedCells);
            if (width != -1) {
                width *= 256;
                int maxColumnWidth = 255 * 256;
                if (width > maxColumnWidth) {
                    width = maxColumnWidth;
                }
            }
            sheet.setColumnWidth(i, (int) width);
        }
    }

    private static void copyAttributes(Font font, AttributedString str, int startIdx, int endIdx) {
        str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx);
        str.addAttribute(TextAttribute.SIZE, (float)font.getFontHeightInPoints());
        if (font.getBoldweight() == Font.BOLDWEIGHT_BOLD) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx);
        if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx);
        if (font.getUnderline() == Font.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx);
    }

数据库50W记录. 本想测50W导出的, 但是excel的一个sheet最大行是65536, 除开title数据只有65535条.
mysql> select count(1) from t_item;
+----------+
| count(1) |
+----------+
|   500000 |
+----------+
1 row in set (1.50 sec)


SystemProfileValueSource] for class [cn.colvin.service.TestExportExcel]-----------------表开始导出完成!-------------------
共计65535行数据,耗时:11635毫秒

log信息, 65536条共计11秒左右. 当然还要考虑SQL的耗时, 所以你的耗时应该会更大. excel数据如下差不多120MB
我写了一个数据库导出到Excel表格的Java代码,但是导出速度很慢,有没有大神帮看一下
另外测试了一下500条数据基本都不会超过0.5秒

#1


导出的数据量有多大,导出用时是多少,也就是说慢到什么程度?你想达到的速度是多少?描述下!因为jxl导出excel确实速度一般,但是一般的项目够用了。

#2


引用 1 楼 u013185616 的回复:
导出的数据量有多大,导出用时是多少,也就是说慢到什么程度?你想达到的速度是多少?描述下!因为jxl导出excel确实速度一般,但是一般的项目够用了。

非常慢,500行的数据,大概七八十列,导出就要5分钟,但是总数据有30万行。

#3


引用 2 楼 l334175100 的回复:
非常慢,500行的数据,大概七八十列,导出就要5分钟,但是总数据有30万行。


500行用5分钟,不太可能,再慢也不会那么慢,可以看看你的数据库的问题。

另外,30万行,7,80列,不要再用jxl或poi导出了,会疯掉的。

你看看这个文章,具体我也没操作过,希望能帮助你:http://blog.csdn.net/u011728105/article/details/47147225

#4


引用 3 楼 u013185616 的回复:
Quote: 引用 2 楼 l334175100 的回复:

非常慢,500行的数据,大概七八十列,导出就要5分钟,但是总数据有30万行。


500行用5分钟,不太可能,再慢也不会那么慢,可以看看你的数据库的问题。

另外,30万行,7,80列,不要再用jxl或poi导出了,会疯掉的。

你看看这个文章,具体我也没操作过,希望能帮助你:http://blog.csdn.net/u011728105/article/details/47147225

谢谢,我看看

#5


还有大神吗 我写了一个数据库导出到Excel表格的Java代码,但是导出速度很慢,有没有大神帮看一下

#6


30万数据为什么要自己写程序导出Excel呢,客户要这个功能吗
数据处理用PL/SQL等现成的工具就可以导成Excel

#7


个人觉得先写一个excel模板,然后再把查出来的数据写入模板中,效率可能会高些。

#8


package cn.com.hime.ImpI;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import cn.com.hime.model.Student;

import jxl.Workbook;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

public class excel {

/**
 * @param args
 */
public static void main(String[] args) {
//输出的excel文件工作表名 
String[] title = {"编号","姓名","简介"};//excel工作表的标题
//输出的excel文件名 
String worksheet = "student";
String targetfile = "c:/out.xls";
List<Student> list=new ArrayList<Student>();
Student st=new Student();
st.setId("1");
st.setNAME("李斯");
st.setDESCRIB("学生");
st.setId("8");
st.setNAME("李斯");
st.setDESCRIB("学生");
Student st1=new Student();
st1.setId("1");
st1.setNAME("李斯1");
st1.setDESCRIB("学生1");
Student st2=new Student();
st2.setId("2");
st2.setNAME("李斯2");
st2.setDESCRIB("学生2");
Student st3=new Student();
st3.setId("3");
st3.setNAME("李斯3");
st3.setDESCRIB("学生3");
Student st7=new Student();
st7.setId("7");
st7.setNAME("李斯7");
st7.setDESCRIB("学生7");
Student st4=new Student();
st4.setId("4");
st4.setNAME("李斯4");
st4.setDESCRIB("学生4");
Student st5=new Student();
st5.setId("5");
st5.setNAME("李斯5");
st5.setDESCRIB("学生5");
Student st6=new Student();
st6.setId("6");
st6.setNAME("李斯6");
st6.setDESCRIB("学生6");
list.add(st);
list.add(st1);
list.add(st2);
list.add(st3);
list.add(st4);
list.add(st5);
list.add(st6);
list.add(st7);
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
 System.out.println("时间:"+new Date());
 
 System.out.println("时间2:"+dateFormat.format(new Date()));
 String str="2016-06-26";
   try {
System.out.println(dateFormat.parse(str));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

 
//export(title,worksheet,targetfile,list);
}
public static void export(String [] title,String worksheet,String targetfile,List<Student> list){

WritableWorkbook workbook;
try {  
//创建可写入的Excel工作薄,运行生成的文件在tomcat/bin下   
//workbook = Workbook.createWorkbook(new File("output.xls")); 

System.out.println("begin");
OutputStream os=new FileOutputStream(targetfile);   
workbook=Workbook.createWorkbook(os); 
WritableSheet sheet = workbook.createSheet(worksheet, 0); 

jxl.write.Label label; 
int mm=0;
// 跟据head创建表头
for (int i=0; i<title.length; i++){  
//Label(列号,行号 ,内容 )   
label = new jxl.write.Label(i, 0, title[i]); 
sheet.addCell(label);    
}
if(list!=null){
// 循环插入数据
int sheetname1=1;//用于自动化创建名字
int record=0;//计算记录
int rownumb=1;
for (int j = 0; j < list.size();j++) {
rownumb++;
if(record%3==0){
rownumb=0;
sheet = workbook.createSheet(worksheet+sheetname1, 0);
// 跟据head创建表头
jxl.write.Label labe_1; 
for (int i=0; i<title.length; i++){  
//Label(列号,行号 ,内容 )   
labe_1 = new jxl.write.Label(i, 0, title[i]); 
sheet.addCell(labe_1);    
}
sheetname1++;
}
//添加数字    
//Iterator it=(Iterator) list.get(mm);
//for(int m=0; m<title.length; m++){
Student bts =(Student) list.get(j);
jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES,10,WritableFont.BOLD,true); 
jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf);    
jxl.write.Label labelCI = new jxl.write.Label(0,rownumb+1,bts.getId(),wcfF);
jxl.write.Label labelCN = new jxl.write.Label(1,rownumb+1,bts.getNAME(),wcfF); 
jxl.write.Label labelCD = new jxl.write.Label(2,rownumb+1,bts.getDESCRIB(),wcfF); 
sheet.addCell(labelCI); 
sheet.addCell(labelCN);
sheet.addCell(labelCD);

//}
record++;
}

}

//添加带有字型Formatting的对象   
/* jxl.write.WritableFont wf = new jxl.write.WritableFont(WritableFont.TIMES,10,WritableFont.BOLD,true); 

jxl.write.WritableCellFormat wcfF = new jxl.write.WritableCellFormat(wf);    
jxl.write.Label labelCF = new jxl.write.Label(4,4,"文本",wcfF);    
sheet.addCell(labelCF); */   
//添加带有字体颜色,带背景颜色 Formatting的对象   

/*jxl.write.WritableFont wfc = new jxl.write.WritableFont(WritableFont.ARIAL,10,WritableFont.BOLD,false,jxl.forma         t.UnderlineStyle.NO_UNDERLINE,jxl.format.Colour.RED);    
jxl.write.WritableCellFormat wcfFC = new jxl.write.WritableCellFormat(wfc);    
wcfFC.setBackground(jxl.format.Colour.BLUE);   
jxl.write.Label labelCFC = new jxl.write.Label(1,5,"带颜色",wcfFC);    
sheet.addCell(labelCFC); */

//添加带有formatting的Number对象    
/*jxl.write.NumberFormat nf = new jxl.write.NumberFormat("#.##");    
jxl.write.WritableCellFormat wcfN = new jxl.write.WritableCellFormat(nf);   
jxl.write.Number labelNF = new jxl.write.Number(1,1,3.1415926,wcfN);  
sheet.addCell(labelNF);  */  

//3.添加Boolean对象    
/*jxl.write.Boolean labelB = new jxl.write.Boolean(0,2,false);    
sheet.addCell(labelB);  */ 

//4.添加DateTime对象    
/*jxl.write.DateTime labelDT = new jxl.write.DateTime(0,3,new java.util.Date());    
sheet.addCell(labelDT);  */

//添加带有formatting的DateFormat对象   
/*jxl.write.DateFormat df = new jxl.write.DateFormat("ddMMyyyyhh:mm:ss");  
jxl.write.WritableCellFormat wcfDF = new jxl.write.WritableCellFormat(df); 
jxl.write.DateTime labelDTF = new jxl.write.DateTime(1,3,new java.util.Date(),wcfDF);   
sheet.addCell(labelDTF);  */
//设置边框   
/*jxl.write.WritableCellFormat wcsB = new jxl.write.WritableCellFormat();   
wcsB.setBorder(jxl.format.Border.ALL,jxl.format.BorderLineStyle.THICK);  
labelCFC = new jxl.write.Label(0,6,"边框设置",wcsB);    
sheet.addCell(labelCFC);  */ 
workbook.write();    
workbook.close(); 

}catch(Exception e){
e.printStackTrace();
}

System.out.println("end");   
Runtime r=Runtime.getRuntime();    
Process p=null;     
String cmd[]={"C:\\","out.xls"}; 

try {
p=r.exec(cmd);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("error executing: "+cmd[0]);    
}

}

}

楼主你可以看下这个代码分多个sheet到出数据测试过可以导出30万条数据。  希望可以帮助到

#9


你先看看是不是查询数据库哪块速度如何,如果可以的话,就是导出代码哪块调整了。。。
个人感觉可能你的查询比较慢。。你先观察哪块性能瓶颈才能根据他做调整。。
如果查询慢,要调整查询,并一次放在内存中。以便后继适应。。
如果导出慢,应该io问题,要调整io性能。

#10


首先排除是否是数据库查询原因,其次在看代码

#11


只能说个方向,你这是SQL过于复杂,SQL查询慢,请把SQL语句直接放在SQL server客户端执行看效果,并不是JAVA的问题

#12


主要有两个地方耗时比较长, 一是SQL取数据, 可以单独把SQL拿出来在命令行运行一下用时多少. 另一个就是autoSizeColumn, api描述说数据较大时耗时非常大, 建议在结果的时候调用一次.
我测试了一下65536条数据就算放在最后autoSizeColumn也根本200多秒. 所以就重新修改了一下, 不调用autoSizeColumn, 而是自己记录每一列最大的值, 最后只用计算最大的列值长度是多少即可, (PS. autoSizeColumn会遍历每一列的每行数据取最大的列长度). 
    /**
     * 功能描述:把数据库中的表导出,生成csv文件
     *
     * @return
     * @ 2016-9-8
     */
    public void outPutTable() {
        long a = System.currentTimeMillis();
        Connection con = null;
        PreparedStatement ps_struts = null;
        ResultSet rs_struts = null;
        int rowNum = 1;
        try {
            HSSFWorkbook workbook = new HSSFWorkbook();
            con = dataSource.getConnection();
            ps_struts = con.prepareStatement("select * from t_item limit 65535");
            rs_struts = ps_struts.executeQuery();
            ResultSetMetaData rsm = rs_struts.getMetaData();
            HSSFSheet sheet = workbook.createSheet("sheet1");
            int columnCount = rsm.getColumnCount();
            int[] cell_size = new int[columnCount];
            int[] max_row = new int[columnCount];
            HSSFRow row1 = sheet.createRow(0);
            for (int i = 1; i <= columnCount; i++) {
                String columnName = rsm.getColumnName(i);
                cell_size[i-1] = columnName.getBytes().length;
                max_row[i-1] = 0;
                HSSFCell cell1 = row1.createCell(i - 1);
                cell1.setCellValue(columnName);
            }

            while (rs_struts.next()) {
                HSSFRow row = sheet.createRow(rowNum);
                for (int i = 0; i < columnCount; i++) {
                    HSSFCell cell = row.createCell(i);
                    // 这三句非常耗时间, 尤其是autoSizeColumn不应该在这里调用
                    // 上面的列是按序取的, 下面的结果按序取就一一对应了没有必要先取name再根据name取值
//                    sheet.autoSizeColumn(i);
//                    String columnName=rs_struts.getMetaData().getColumnName(i+1);
//                    tempo[i]  = rs_struts.getString(columnName);
                    String value = rs_struts.getString(i + 1);
                    int byte_len = value.getBytes().length;
                    if (byte_len > cell_size[i]) {
                        cell_size[i] = byte_len;
                        max_row[i] = rowNum;
                    }
                    cell.setCellValue(value);
                }
                rowNum++;
            }

            resize(sheet, max_row);

            FileOutputStream fOut = new FileOutputStream("f:/temp/t_item.xls");
            workbook.write(fOut);
            fOut.flush();
            fOut.close();
        } catch (Exception e) {
            System.out.println("已运行 outPutTable (): " + e);
        } finally {
            if (rs_struts != null) {
                try {
                    rs_struts.close();
                } catch (SQLException e) {
                }
            }
            if (ps_struts != null) {
                try {
                    ps_struts.close();
                } catch (SQLException e) {
                }
            }
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException e) {
                }
            }
        }
        System.out.println("-----------------表开始导出完成!-------------------");
        System.out.println("共计" + (rowNum-1) +"行数据,耗时:" + (System.currentTimeMillis() - a) + "毫秒");
    }

    private static final char defaultChar = '0';
    private static final FontRenderContext fontRenderContext = new FontRenderContext(null, true, true);

    void resize(Sheet sheet, int[] max_row) {
        resize(sheet, false, max_row);
    }
    void resize(Sheet sheet, boolean useMergedCells, int[] max_row) {
        AttributedString str;
        TextLayout layout;

        Workbook wb = sheet.getWorkbook();
        DataFormatter formatter = new DataFormatter();
        Font defaultFont = wb.getFontAt((short) 0);

        str = new AttributedString(String.valueOf(defaultChar));
        copyAttributes(defaultFont, str, 0, 1);
        layout = new TextLayout(str.getIterator(), fontRenderContext);
        int defaultCharWidth = (int)layout.getAdvance();
        for (int i = 0; i < max_row.length; i++) {
            Cell cell = sheet.getRow(max_row[i]).getCell(i);
            double width = SheetUtil.getCellWidth(cell, defaultCharWidth, formatter, useMergedCells);
            if (width != -1) {
                width *= 256;
                int maxColumnWidth = 255 * 256;
                if (width > maxColumnWidth) {
                    width = maxColumnWidth;
                }
            }
            sheet.setColumnWidth(i, (int) width);
        }
    }

    private static void copyAttributes(Font font, AttributedString str, int startIdx, int endIdx) {
        str.addAttribute(TextAttribute.FAMILY, font.getFontName(), startIdx, endIdx);
        str.addAttribute(TextAttribute.SIZE, (float)font.getFontHeightInPoints());
        if (font.getBoldweight() == Font.BOLDWEIGHT_BOLD) str.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, startIdx, endIdx);
        if (font.getItalic() ) str.addAttribute(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE, startIdx, endIdx);
        if (font.getUnderline() == Font.U_SINGLE ) str.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, startIdx, endIdx);
    }

数据库50W记录. 本想测50W导出的, 但是excel的一个sheet最大行是65536, 除开title数据只有65535条.
mysql> select count(1) from t_item;
+----------+
| count(1) |
+----------+
|   500000 |
+----------+
1 row in set (1.50 sec)


SystemProfileValueSource] for class [cn.colvin.service.TestExportExcel]-----------------表开始导出完成!-------------------
共计65535行数据,耗时:11635毫秒

log信息, 65536条共计11秒左右. 当然还要考虑SQL的耗时, 所以你的耗时应该会更大. excel数据如下差不多120MB
我写了一个数据库导出到Excel表格的Java代码,但是导出速度很慢,有没有大神帮看一下
另外测试了一下500条数据基本都不会超过0.5秒