要在 Java 中查询 SQL Server 数据并将结果生成 Excel 文件并导出,你可以使用以下步骤和库:
1. JDBC 连接到 SQL Server:
• 使用 JDBC 驱动程序连接到 SQL Server 数据库。
2. Apache POI 库:
• 使用 Apache POI 库来创建和操作 Excel 文件。
步骤详解
1. 添加依赖
首先,在你的项目中添加所需的依赖项。如果你使用的是 Maven,可以在 pom.xml 中添加以下依赖:
<!-- JDBC Driver for SQL Server -->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>9.4.0.jre8</version>
</dependency>
<!-- Apache POI for Excel -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
如果你使用的是 Gradle,可以在 build.gradle 中添加以下依赖:
dependencies {
implementation 'com.microsoft.sqlserver:mssql-jdbc:9.4.0.jre8'
implementation 'org.apache.poi:poi-ooxml:5.2.3'
}
2. 编写 Java 代码(数据量较少)
以下是一个完整的 Java 示例代码,展示如何连接到 SQL Server 数据库,查询数据,并将结果生成 Excel 文件并导出(数据量较少)。
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 org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class SqlServerToExcel {
// 数据库连接信息
private static final String URL = "jdbc:sqlserver://localhost:1433;databaseName=YourDatabaseName";
private static final String USER = "yourUsername";
private static final String PASSWORD = "yourPassword";
// SQL 查询语句
private static final String QUERY = "SELECT * FROM YourTableName";
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Data");
try {
// 1. 连接到数据库
connection = DriverManager.getConnection(URL, USER, PASSWORD);
statement = connection.createStatement();
resultSet = statement.executeQuery(QUERY);
// 2. 获取元数据
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
// 3. 创建标题行
Row headerRow = sheet.createRow(0);
for (int i = 1; i <= columnCount; i++) {
Cell cell = headerRow.createCell(i - 1);
cell.setCellValue(metaData.getColumnName(i));
}
// 4. 填充数据行
int rowNum = 1;
while (resultSet.next()) {
Row row = sheet.createRow(rowNum++);
for (int i = 1; i <= columnCount; i++) {
Cell cell = row.createCell(i - 1);
Object value = resultSet.getObject(i);
if (value instanceof Number) {
cell.setCellValue(((Number) value).doubleValue());
} else {
cell.setCellValue(value.toString());
}
}
}
// 5. 自动调整列宽
for (int i = 0; i < columnCount; i++) {
sheet.autoSizeColumn(i);
}
// 6. 写入文件
try (FileOutputStream fileOut = new FileOutputStream("data.xlsx")) {
workbook.write(fileOut);
}
System.out.println("Excel 文件已生成: data.xlsx");
} catch (SQLException | IOException e) {
e.printStackTrace();
} finally {
// 关闭资源
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
if (workbook != null) workbook.close();
} catch (SQLException | IOException e) {
e.printStackTrace();
}
}
}
}
3. 编写 Java 代码(数据量较大)
导出百万级别的数据时,性能和内存管理变得尤为重要。以下是优化后的代码,旨在提高效率并减少内存占用。主要优化点包括:
1. 分页查询: 使用分页查询来避免一次性加载大量数据到内存中。
2. 流式写入: 使用 Apache POI 的 SXSSF(Streaming Usermodel API)来处理大数据量,SXSSF 是专门设计用于处理大数据量的流式 API。
3. 批量写入: 减少 I/O 操作次数,提高写入效率。
4. 资源管理: 更好的资源管理和释放。
以下是优化后的代码示例:
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
public class SqlServerToExcelOptimized {
// 数据库连接信息
private static final String URL = "jdbc:sqlserver://localhost:1433;databaseName=YourDatabaseName";
private static final String USER = "yourUsername";
private static final String PASSWORD = "yourPassword";
// SQL 查询语句(带分页)
private static final String QUERY = "SELECT * FROM YourTableName ORDER BY SomeColumn OFFSET ? ROWS FETCH NEXT ? ROWS ONLY";
// 分页大小
private static final int PAGE_SIZE = 10000;
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
SXSSFWorkbook workbook = new SXSSFWorkbook(100); // 保留100行在内存中,其余行写入临时文件
Sheet sheet = workbook.createSheet("Data");
try {
// 1. 连接到数据库
connection = DriverManager.getConnection(URL, USER, PASSWORD);
// 2. 创建标题行
preparedStatement = connection.prepareStatement("SELECT TOP 1 * FROM YourTableName");
resultSet = preparedStatement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
Row headerRow = sheet.createRow(0);
for (int i = 1; i <= columnCount; i++) {
Cell cell = headerRow.createCell(i - 1);
cell.setCellValue(metaData.getColumnName(i));
}
// 3. 分页查询并填充数据
int offset = 0;
int totalRows = 0;
do {
preparedStatement = connection.prepareStatement(QUERY);
preparedStatement.setInt(1, offset);
preparedStatement.setInt(2, PAGE_SIZE);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
Row row = sheet.createRow(++totalRows);
for (int i = 1; i <= columnCount; i++) {
Cell cell = row.createCell(i - 1);
Object value = resultSet.getObject(i);
if (value instanceof Number) {
cell.setCellValue(((Number) value).doubleValue());
} else {
cell.setCellValue(value == null ? "" : value.toString());
}
}
}
offset += PAGE_SIZE;
} while (resultSet.getRow() > 0);
// 4. 写入文件
try (FileOutputStream fileOut = new FileOutputStream("data_large.xlsx")) {
workbook.write(fileOut);
}
System.out.println("Excel 文件已生成: data_large.xlsx");
} catch (SQLException | IOException e) {
e.printStackTrace();
} finally {
// 清理临时文件
workbook.dispose();
// 关闭资源
try {
if (resultSet != null) resultSet.close();
if (preparedStatement != null) preparedStatement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
4.代码说明
1. 分页查询:
• 使用 OFFSET ... FETCH NEXT ... ROWS ONLY 进行分页查询,每次查询 PAGE_SIZE 条记录。
• offset 用于指定查询的起始位置,PAGE_SIZE 用于指定每页的记录数。
2. SXSSFWorkbook:
• 使用 SXSSFWorkbook 来处理大数据量。SXSSFWorkbook 是 Apache POI 提供的一个流式 API,适用于处理大数据量的情况。
• new SXSSFWorkbook(100) 表示保留 100 行在内存中,其余行写入临时文件,以减少内存占用。
3. 标题行:
• 使用 SELECT TOP 1 * FROM YourTableName 查询一条记录来获取列信息,并创建标题行。
4. 分页循环:
• 使用 do-while 循环进行分页查询,直到没有更多记录为止。
• 每次查询 PAGE_SIZE 条记录,并将其写入 Excel 文件。
5. 写入文件:
• 使用 FileOutputStream 将工作簿写入文件 data_large.xlsx。
6. 资源管理:
• 在 finally 块中关闭所有打开的资源,包括 ResultSet, PreparedStatement, Connection,并调用 workbook.dispose() 清理临时文件。
运行代码确保你的项目中包含了上述依赖项,然后运行 SqlServerToExcelOptimized 类的 main 方法。运行后,会在项目的根目录下生成一个名为 data_large.xlsx 的 Excel 文件,其中包含从 SQL Server 查询到的数据