Java 使用ApachePOI和JDBC将大型结果集写入.xlsx文件
我正试图在一个.xlsx文件中写入一个最大行数可达200万的结果集。 为了克服堆空间或内存错误,我决定在每次调用中从表中获取一些有限的记录集,并将它们附加到文件中。 这些有限的记录集都是由rownum排序的。每次调用表时,我都会提取50K条记录,最后从表中提取所有记录并将其附加到.xlsx文件中。 目前我只在每张纸上放60万张唱片。我目前的逻辑如下 但是下面的逻辑需要花费大量时间来创建.xlsx文件。有什么办法可以缩短时间吗?? 在创建第二张图纸后,它也会失败Java 使用ApachePOI和JDBC将大型结果集写入.xlsx文件,java,oracle,jakarta-ee,apache-poi,fileoutputstream,Java,Oracle,Jakarta Ee,Apache Poi,Fileoutputstream,我正试图在一个.xlsx文件中写入一个最大行数可达200万的结果集。 为了克服堆空间或内存错误,我决定在每次调用中从表中获取一些有限的记录集,并将它们附加到文件中。 这些有限的记录集都是由rownum排序的。每次调用表时,我都会提取50K条记录,最后从表中提取所有记录并将其附加到.xlsx文件中。 目前我只在每张纸上放60万张唱片。我目前的逻辑如下 但是下面的逻辑需要花费大量时间来创建.xlsx文件。有什么办法可以缩短时间吗?? 在创建第二张图纸后,它也会失败 String query=
String query="select count(*) from employee";
String actquery="";
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
conn = DriverManager.getConnection(jdbcURL,user,passwd);
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
stmt.setFetchSize(1000);
int rowcounter;
int increaseCount=50000;
int jdbclimit=50000;//jdbc
int excelrowlimit=600000;
int excellimit=600000;
int rownumStartCnt=0;
int rownumEndCnt=0;
if(rs.next()){
outStream = new FileOutputStream("D:\\Test.xlsx",true);
int count=rs.getInt(1);
System.out.println("Total records"+count);
if(count>0)
{
int sheets= count/excelrowlimit;
if(count%excelrowlimit>0){
sheets = sheets+1;
}
for(int scount=1;scount<=sheets;scount++){
sheet = workbook.createSheet("GapHistory-"+scount);
rowcounter=1;
System.out.println("Sheet:"+scount);
System.out.println("limit is "+jdbclimit);
while(rowcounter<excelrowlimit)
{
rownumStartCnt=rownumEndCnt+1;
rownumEndCnt=jdbclimit;
jdbclimit=jdbclimit+increaseCount;
if(rownumEndCnt>excellimit){
rownumEndCnt=excellimit;
}
if(rownumStartCnt>count){
break;
}
PreparedStatement stmt2 = null;
ResultSet rs2 =null;
ResultSetMetaData rsmd=null;
actquery=actquery+"SELECT * FROM (SELECT t.*, ROW_NUMBER() OVER (ORDER BY employee_number) rnum FROM employee t) WHERE rnum BETWEEN ? and ?";
stmt2 = conn.prepareStatement(actquery);
stmt2.setInt(1,rownumStartCnt);
stmt2.setInt(2,rownumEndCnt);
rs2 = stmt2.executeQuery();
System.out.println("Start row-->"+rownumStartCnt+"End row--->"+rownumEndCnt);
rsmd = rs2.getMetaData();
stmt2.setFetchSize(1000);
rs2.setFetchDirection(ResultSet.FETCH_FORWARD);
while(rs2.next())
{
if(rowcounter==1)
{
row = sheet.createRow(rowcounter);
for(int i=1;i<=68;i++)
{
cell = row.createCell(i);
cell.setCellValue(rsmd.getColumnName(i));
}
}
rowcounter++;
for(int i=1;i<=68;i++)
{
if(i==1)
{
row = sheet.createRow(rowcounter);
}
cell = row.createCell(i);
cell.setCellValue(rs2.getString(i));
}
}
actquery="";
}
excellimit = excellimit+excelrowlimit;// Got rid with exception after adding this line
}
}
}
这意味着您正在打开许多结果集,而没有关闭任何结果集。最终您会耗尽驱动程序资源。完成后,必须关闭每个结果集
顺便说一句,XLSX的最大行数为2^20,即1048576。不能在XLSX工作表中存储200万行 请正确格式化您的代码。您正在向陌生人寻求帮助,您至少可以让代码可读。谢谢您的回复。是的,我知道xlsx的局限性。这就是为什么当我得到一个大于600000的记录时,我要创建一个新的工作表。基本上,我试图在每张excel表格中只放入600000条记录。更多的错误是由于没有正确遵循逻辑。查看输出日志,您会知道。我现在已经删除了异常。但需要帮助,以尽量减少生成.xlsx文件的时间。请在您的帖子和1格式的代码正确;更新叙述以反映当前情况,即删除关于例外情况的部分。编辑文章并添加必要的评论。现在我想减少创建excel的时间。请引导我。是否有任何选项可以在从resultset获取第一组记录后立即写入文件,而不是立即写入文件。
java.sql.SQLException: ORA-01000: maximum open cursors exceeded