如何使用Java将XLSX文件转换为CSV

2025/04/07

1. 概述

XLSX是Microsoft Excel创建的一种流行的电子表格格式,以能够存储公式和图表等复杂数据结构而闻名。相比之下,CSV(逗号分隔值)是一种更简单的格式,通常用于应用程序之间的数据交换。

将XLSX文件转换为CSV格式可使数据更易于访问,从而简化数据处理、集成和分析

在本教程中,我们将学习如何使用Java将XLSX文件转换为CSV。我们将使用Apache POI读取XLSX文件,并使用Apache Commons CSV和OpenCSV将数据写入CSV文件。

2. 读取XLSX文件

为了处理XLSX文件,我们将使用Apache POI,这是一个专为处理Microsoft Office文档而设计的强大Java库。Apache POI为读取和写入Excel文件提供了广泛的支持,使其成为我们转换任务的绝佳选择。

2.1 POI依赖

首先,我们需要将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文件,它返回一个包含整个Excel工作簿的Workbook对象,并允许我们访问其工作表和数据。

我们还使用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)从工作簿中检索第一个工作表,然后遍历XLSX文件的每一行和列。

对于工作表中的每个单元格,我们使用DataFormatter将其值转换为格式化的字符串。这些格式化的值存储在字符串数组中,表示来自XLSX文件的一行数据。

最后,我们将每个rowData数组添加到名为data的List<String[]>中,其中包含从XLSX文件中提取的所有行数据。

3. 使用Apache Commons CSV写入CSV文件

要用Java写入CSV文件,我们将使用Apache Commons CSV,它提供了一个用于读取和写入CSV文件的简单高效的API。

3.1 依赖

要使用Apache Commons CSV,我们需要将依赖添加到pom.xml中:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.11.0</version>
</dependency>

这将包括处理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确保所有资源得到妥善管理。

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,我们需要将依赖添加到pom.xml中:

<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.8</version>
</dependency>

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文件

现在,我们将调整之前的XLSX到CSV的转换逻辑以使用OpenCSV:

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转换

最后,让我们创建一个单元测试来检查我们的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. 总结

使用Apache POI读取并使用Apache Commons CSV或OpenCSV写入,可以高效地将XLSX文件转换为Java中的CSV格式。

这两个CSV库都提供了强大的工具来处理和将不同类型的数据类型写入CSV。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章