执行java代码将DB表数据导出到Excel工作表(.xlsx)时内存不足
我正在尝试将表数据从数据库导出到Excel工作表。由于数据量很大,我使用了XSSFWorkbook,以便将数据导出为xlsx文件。我使用了setFetchsize()以便更快地从数据库中提取数据。我这里有一个问题,虽然它很快,但它会消耗我的系统内存和CPU使用率。我用谷歌搜索了所有可能的答案。如果有人建议我继续下去,那将更有帮助 实现了一个建立DB连接的Java类,一旦建立了连接,表中的数据将被提取到resultset,以提高提取速度,我使用了setFetchSize(1000)方法。正好在80000条记录之后内存不足。也尝试使用setFetchSize(10000)执行java代码将DB表数据导出到Excel工作表(.xlsx)时内存不足,java,excel,jdbc,resultset,Java,Excel,Jdbc,Resultset,我正在尝试将表数据从数据库导出到Excel工作表。由于数据量很大,我使用了XSSFWorkbook,以便将数据导出为xlsx文件。我使用了setFetchsize()以便更快地从数据库中提取数据。我这里有一个问题,虽然它很快,但它会消耗我的系统内存和CPU使用率。我用谷歌搜索了所有可能的答案。如果有人建议我继续下去,那将更有帮助 实现了一个建立DB连接的Java类,一旦建立了连接,表中的数据将被提取到resultset,以提高提取速度,我使用了setFetchSize(1000)方法。正好在80
导入java.io.File;
导入java.io.FileNotFoundException;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.sql.Connection;
导入java.sql.DriverManager;
导入java.sql.ResultSet;
导入java.sql.SQLException;
导入java.sql.Statement;
导入java.util.ArrayList;
导入java.util.Date;
导入org.apache.poi.ss.usermodel.Cell;
导入org.apache.poi.xssf.usermodel.XSSFRow;
导入org.apache.poi.xssf.usermodel.xssfheet;
导入org.apache.poi.xssf.usermodel.xssf工作簿;
公共类XSSF_Excel_追加器{
私有静态连接getConnection(){
连接con=null;
String url=“连接字符串”;
试一试{
forName类(“驱动程序类”);
con=DriverManager.getConnection(url,“用户名”、“密码”);
}
catch(classnotfounde异常){
e、 printStackTrace();
System.out.println(“未找到驱动程序类”);
}
捕获(SQLE异常){
e、 printStackTrace();
System.out.println(“连接数据库时发生异常”);
}
返回con;
}
公共布尔getTableData(整数范围){
布尔标志=真;
ArrayList tableDataList=null;
int num=0;
Connection con=getConnection();
如果(con!=null){
试一试{
XSSFWorkbook工作簿=新XSSFWorkbook();
XSSFSheet sheet=workBook.createSheet(“*******”);
XSSFRow headingRow=sheet.createRow(0);
headingRow.createCell(0.setCellValue(“*******”);
headingRow.createCell(1).setCellValue(“*******”);
headingRow.createCell(2.setCellValue)(“**********”);
headingRow.createCell(3.setCellValue)(“*******”);
headingRow.createCell(4.setCellValue)(“*******”);
headingRow.createCell(5.setCellValue)(“*******”);
语句ps1=con.createStatement();
ResultSet ResultSet=ps1.executeQuery(“选择计数(*)从
表(名称);;
while(resultSet.next()){
num=Integer.parseInt(resultSet.getString(1));
}
System.out.println(“表中的行数”+num);
对于(int i=0;i 0){
int lastRow=sheet.getLastRowNum();
对于(对象[]对象:tableDataList){
XSSFRow row=sheet.createRow(++lastRow);
int colNum=0;
用于(对象字段:对象){
Cell Cell=row.createCell(colNum++);
if(字符串的字段实例){
cell.setCellValue((字符串)字段);
}else if(整型字段实例){
cell.setCellValue((整数)字段);
}
}
}
}
}
String file=“存储导出的xlsx工作簿的位置”;
FileOutputStream fos=新FileOutputStream(新文件(文件));
练习册。写作(fos);
fos.close();
}捕获(SQLE异常){
flag=false;
e、 printStackTrace();
System.out.println(“无法创建PreparedStatement”);
}
catch(filenotfounde异常){
e、 printStackTrace();
System.out.println(“未找到无效目录或文件”);
}捕获(IOE异常){
e、 printStackTrace();
System.out.println(“将.xlsx写入目录时出错”);
}
}
返回标志;
}
公共静态void main(字符串[]args){
日期d1=新日期();
试一试{
System.out.println(“主方法时间内:+d1”);
整数范围=10000;
XSSF_Excel_Appender exporter=新XSSF_Excel_Appender();
if(exporter.getTableData(范围)){
System.out.println(“成功导出”);
}
否则{
System.out.println(“发生了一些错误”);
}
}
捕获(例外情况除外){
例如printStackTrace();
}
日期d2=新日期();
System.out.println(“结束时间:+d2”);
long diff=d2.getTime()-d1.getTime();
System.out.println(“所花费的总时间(使用数组列表):
“+diff/(60*1000)%60+”分钟“+diff/1000%60+”秒“);
}
}
在获取80000条记录时,CPU使用率已达到100%。希望在不影响内存的情况下快速导出方法建议。您可以设置运行java的最大堆大小。使用命令行选项
-Xmx
JAVA_ARGS=“-Xmx1024m”
您可以设置运行java的最大堆大小。使用命令行选项
-Xmx
JAVA_ARGS=“-Xmx1024m”
简单的答案是使用64位JDK并分配更多内存。使用VisualVM分析代码。或者,更好的方法是使用IntelliJ Data Grip这样的工具来为您实现这一点。为什么要写代码?使用工具。您是否尝试过使用
sxsfWorkbook
?您使用的是哪个JDBC驱动程序?简单的答案是使用64位JDK并分配更多内存。使用VisualVM分析代码。或者,更好的方法是使用IntelliJ Data Grip这样的工具,它可以为
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class XSSF_Excel_Appender {
private static Connection getConnection(){
Connection con = null;
String url = "connection string";
try{
Class.forName("driver class");
con = DriverManager.getConnection(url,"username","password");
}
catch(ClassNotFoundException e){
e.printStackTrace();
System.out.println("Driver class not found.");
}
catch(SQLException e){
e.printStackTrace();
System.out.println("Exception occured while connecting DB");
}
return con;
}
public boolean getTableData(int range){
boolean flag = true;
ArrayList<Object[]> tableDataList = null;
int num = 0;
Connection con = getConnection();
if(con != null){
try{
XSSFWorkbook workBook = new XSSFWorkbook();
XSSFSheet sheet = workBook.createSheet("*******");
XSSFRow headingRow = sheet.createRow(0);
headingRow.createCell(0).setCellValue("*****");
headingRow.createCell(1).setCellValue("*******");
headingRow.createCell(2).setCellValue("*********");
headingRow.createCell(3).setCellValue("*****");
headingRow.createCell(4).setCellValue("******");
headingRow.createCell(5).setCellValue("*****");
Statement ps1=con.createStatement();
ResultSet resultSet = ps1.executeQuery("SELECT COUNT(*) from
table_name");
while(resultSet.next()) {
num = Integer.parseInt(resultSet.getString(1));
}
System.out.println("Number of rows in (table_name) "+num);
for(int i=0;i<100000;i+=range) {
Statement ps2 = con.createStatement();
ps2.setFetchSize(1000);
ResultSet result = ps2.executeQuery("SELECT ROWNUM as
S_NO,(TABLE_NAME).* FROM Table_name offset "+i+" rows
fetch next "+range+" rows only");
tableDataList = new ArrayList<Object[]>();
while(result.next()) {
Object[] objArray = new Object[6];
objArray[0] = (result.getString(1) == null ? "Null" :
result.getString(1));
objArray[1] = (result.getString(2) == null ? "Null" :
result.getString(2));
objArray[2] = (result.getString(3) == null ? "Null" :
result.getString(3));
objArray[3] = (result.getString(4) == null ? "Null" :
result.getString(4));
objArray[4] = (result.getString(5) == null ? "Null" :
result.getString(5));
objArray[5] = (result.getString(6) == null ? "Null" :
result.getString(6));
tableDataList.add(objArray);
}
if(tableDataList != null && tableDataList.size() > 0){
int lastRow=sheet.getLastRowNum();
for (Object[] objects : tableDataList) {
XSSFRow row = sheet.createRow(++lastRow);
int colNum = 0;
for (Object field : objects) {
Cell cell = row.createCell(colNum++);
if (field instanceof String) {
cell.setCellValue((String) field);
} else if (field instanceof Integer) {
cell.setCellValue((Integer) field);
}
}
}
}
}
String file = "Location to store the exported xlsx workbook";
FileOutputStream fos = new FileOutputStream(new File(file));
workBook.write(fos);
fos.close();
}catch(SQLException e){
flag = false;
e.printStackTrace();
System.out.println("Unable to create PreparedStatement");
}
catch(FileNotFoundException e){
e.printStackTrace();
System.out.println("Invalid directory or file not found");
}catch(IOException e){
e.printStackTrace();
System.out.println("Error while writing .xlsx to directory");
}
}
return flag;
}
public static void main(String[] args) {
Date d1 = new Date();
try {
System.out.println("Inside Main method time: "+d1);
int range = 10000;
XSSF_Excel_Appender exporter = new XSSF_Excel_Appender();
if(exporter.getTableData(range)) {
System.out.println("Successfully exported");
}
else{
System.out.println("Some error has occurred");
}
}
catch(Exception ex) {
ex.printStackTrace();
}
Date d2 = new Date();
System.out.println("End time : "+d2);
long diff = d2.getTime() - d1.getTime();
System.out.println("Total time taken (using Array List) :
"+diff/(60*1000)%60+" minutes,"+diff/1000%60+" seconds.");
}
}