1. 概述
XLSX 不用多说,是微软Excel文件格式,能够存储复杂的数据结构(如公式和图表)。相比之下,CSV使用逗号分隔,是一种简单的格式,通常用于应用程序之间的数据交换。
将 XLSX 文件转换为 CSV 格式简化了数据处理、集成和分析,使数据更易于访问。
本文,我们将学习如何在 Java 中将 XLSX 文件转换为 CSV 文件。我们将使用 Apache POI 来读取 XLSX 文件,并使用 Apache Commons CSV 和 OpenCSV 将数据写入 CSV 文件。
2. 读取 XLSX 文件
为了处理 XLSX 文件,我们将使用 Apache POI,这是一个强大的 Java 库,专为处理 Microsoft Office 文档而设计。Apache POI 为读取和写入 Excel 文件提供了广泛的支持,使其成为我们转换任务的绝佳选择。
2.1. Maven 依赖
首先,我们需要将 Apache POI依赖 添加到我们的 pom.xml:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.5</version>
</dependency>
该依赖包括了处理 XLSX 文件和处理各种数据结构所需的库。
2.2. 使用 POI 打开 XLSX 文件
为了打开和读取 XLSX 文件,我们将创建一个使用 Apache POI 的 XSSFWorkbook 类的方法。我们可以使用这个类来读取 XLSX 文件并访问其内容:
public static Workbook openWorkbook(String filePath) throws IOException {
try (FileInputStream fis = new FileInputStream(filePath)) {
return WorkbookFactory.create(fis);
}
}
使用 FileInputStream 读取 XLSX 文件流。然后通过 WorkbookFactory.create() 方法从输入流创建 Workbook 对象,内部处理文件格式和初始化。
2.3. 遍历行和列
打开 XLSX 文件后,我们开始遍历行和列:
public static List<String[]> iterateAndPrepareData(String filePath) throws IOException {
Workbook workbook = openWorkbook(filePath);
Sheet sheet = workbook.getSheetAt(0);
List<String[]> data = new ArrayList<>();
DataFormatter formatter = new DataFormatter();
for (Row row : sheet) {
String[] rowData = new String[row.getLastCellNum()];
for (int cn = 0; cn < row.getLastCellNum(); cn++) {
Cell cell = row.getCell(cn);
rowData[cn] = cell == null ? "" : formatter.formatCellValue(cell);
}
data.add(rowData);
}
workbook.close();
return data;
}
我们首先使用 getSheetAt(0) 从工作簿中获取第一个sheet,然后遍历 XLSX 文件的每一行和每一列。
对于工作表中的每个单元格,我们使用 DataFormatter 将其值转换为格式化的字符串。这些格式化的值存储在一个 String 数组中,代表 XLSX 文件中的一行数据。
最后,我们将每个 rowData 数组添加到 data list 中,它包含从 XLSX 文件中提取的所有行数据。
3. 使用 Apache Commons CSV 写入 CSV 文件
完成Excel的读取后,下面我介绍如何使用 Apache Commons CSV 库,实现 CSV 文件的写入操作。
3.1. Maven 依赖
要使用 Apache Commons CSV,我们需要在 pom.xml 中添加 Apache Commons CSV依赖,其包含处理 CSV 文件操作所需的库。
3.2. 创建 CSV 文件
接下来,我们创建一个方法,使用 Apache Commons CSV 将数据写入 CSV 文件:
public class CommonsCSVWriter {
public static void writeCSV(List<String[]> data, String filePath) throws IOException {
try (FileWriter fw = new FileWriter(filePath);
CSVPrinter csvPrinter = new CSVPrinter(fw, CSVFormat.DEFAULT)) {
for (String[] row : data) {
csvPrinter.printRecord((Object[]) row);
}
csvPrinter.flush();
}
}
}
在 CommonsCSVWriter.writeCSV() 方法中,我们使用 Apache Commons CSV 将数据写入 CSV 文件。
我们为指定的文件路径创建一个 FileWriter,并初始化一个 CSVPrinter 来处理写入过程。
该方法遍历数据列表中的每一行,并使用 csvPrinter.printRecord() 将每一行写入 CSV 文件。它确保在写入完成后通过 csvPrinter.flush() 和 csvPrinter.close() 关闭 CSVPrinter,从而正确管理资源。
3.3. 遍历工作簿并写入 CSV 文件
让我们将读取 XLSX 文件和写入 CSV 文件结合起来:
public class ConvertToCSV {
public static void convertWithCommonsCSV(String xlsxFilePath, String csvFilePath) throws IOException {
List<String[]> data = XLSXReader.iterateAndPrepareData(xlsxFilePath);
CommonsCSVWriter.writeCSV(data, csvFilePath);
}
}
在 convert(String xlsxFilePath, String csvFilePath) 方法中,我们首先使用前面提到的 XLSXReader.iterateAndPrepareData() 方法从指定的 XLSX 文件中提取数据。
然后,我们将提取的数据传递给 CommonsCSVWriter.writeCSV() 方法,使用 Apache Commons CSV 将其写入指定位置的 CSV 文件。
4. 使用 OpenCSV 写入 CSV 文件
OpenCSV 是另一个流行的 Java 库,用于处理 CSV 文件。它提供了简单的 API 来读取和写入 CSV 文件。让我们尝试将其作为 Apache Commons CSV 的替代方案。
4.1. 依赖
要使用 OpenCSV,我们需要将 Maven依赖 添加到我们的 pom.xml:
4.2. 创建 CSV 文件
接下来,让我们创建一个方法,使用 OpenCSV 将数据写入 CSV 文件:
public static void writeCSV(List<String[]> data, String filePath) throws IOException {
try (FileWriter fw = new FileWriter(filePath);
CSVWriter csvWriter = new CSVWriter(fw,
CSVWriter.DEFAULT_SEPARATOR,
CSVWriter.NO_QUOTE_CHARACTER,
CSVWriter.DEFAULT_ESCAPE_CHARACTER,
CSVWriter.DEFAULT_LINE_END)) {
for (String[] row : data) {
csvWriter.writeNext(row);
}
}
}
在 OpenCSVWriter.writeCSV() 方法中,我们使用 OpenCSV 将数据写入 CSV 文件。
我们为指定的路径创建一个 FileWriter,并使用禁用字段引号和默认分隔符和行结束符的配置初始化 CSVWriter。
该方法遍历提供的数据列表,使用 csvWriter.writeNext() 将每一行写入文件。
try-with-resources 语句确保 FileWriter 和 CSVWriter 的正确关闭,高效管理资源并防止泄漏。
4.3. 遍历工作簿并写入 CSV 文件
public class ConvertToCSV {
public static void convertWithOpenCSV(String xlsxFilePath, String csvFilePath) throws IOException {
List<String[]> data = XLSXReader.iterateAndPrepareData(xlsxFilePath);
OpenCSVWriter.writeCSV(data, csvFilePath);
}
}
5. 测试
最后,让我们创建一个单元测试来检查我们的 CSV 转换。该测试将使用一个示例 XLSX 文件并验证生成的 CSV 内容:
class ConvertToCSVUnitTest {
private static final String XLSX_FILE_INPUT = "src/test/resources/xlsxToCsv_input.xlsx";
private static final String CSV_FILE_OUTPUT = "src/test/resources/xlsxToCsv_output.csv";
@Test
void givenXlsxFile_whenUsingCommonsCSV_thenGetValuesAsList() throws IOException {
ConvertToCSV.convertWithCommonsCSV(XLSX_FILE_INPUT, CSV_FILE_OUTPUT);
List<String> lines = Files.readAllLines(Paths.get(CSV_FILE_OUTPUT));
assertEquals("1,Dulce,Abril,Female,United States,32,15/10/2017,1562", lines.get(1));
assertEquals("2,Mara,Hashimoto,Female,Great Britain,25,16/08/2016,1582", lines.get(2));
}
@Test
void givenXlsxFile_whenUsingOpenCSV_thenGetValuesAsList() throws IOException {
ConvertToCSV.convertWithOpenCSV(XLSX_FILE_INPUT, CSV_FILE_OUTPUT);
List<String> lines = Files.readAllLines(Paths.get(CSV_FILE_OUTPUT));
assertEquals("1,Dulce,Abril,Female,United States,32,15/10/2017,1562", lines.get(1));
assertEquals("2,Mara,Hashimoto,Female,Great Britain,25,16/08/2016,1582", lines.get(2));
}
}
在这个单元测试中,我们验证了由 Apache Commons CSV 和 OpenCSV 生成的 CSV 文件是否包含预期的值。我们使用一个示例 XLSX 文件,并检查生成的 CSV 文件中的特定行,以确保转换的准确性。
以下是输入的 XLSX 文件示例 (xlsxToCsv_input.xlsx):
以下是转换后的 CSV 文件 (xlsxToCsv_output.csv):
6. 结论
在 Java 中将 XLSX 文件转换为 CSV 格式可以通过使用 Apache POI 读取和使用 Apache Commons CSV 或 OpenCSV 写入来高效地实现。
两种 CSV 库都提供了强大的工具来处理和写入不同的数据类型到 CSV。
最好,文中源代码在 GitHub 上。