使用Java将XLS转为XLSX格式

在Java中,将早期的Excel 97-2003格式文件(.xls)转换为现代的Excel 2007+格式(.xlsx)可以通过多种库实现。以下是使用Apache POI​(最常用的Java Excel操作库)的详细方法和代码示例。

图片[1]_使用Java将XLS转为XLSX格式_知途无界

一、为什么需要转换?

  • ​**.xls(HSSF)​​:Excel 97-2003格式,单工作表最大行数 ​65,536行**,最大列数 ​256列(IV列)​,文件体积较大且功能有限。
  • ​**.xlsx(XSSF)​​:Excel 2007+格式,基于XML压缩存储,单工作表最大行数 ​1,048,576行**,最大列数 ​16,384列(XFD列)​,支持更多功能和更大数据量。

当需要处理大数据量或兼容新版Excel功能时,将.xls转为.xlsx是常见需求。


二、所需依赖(Maven)

使用Apache POI的poi(处理.xls)和poi-ooxml(处理.xlsx)模块:

<dependencies>
    <!-- 处理XLS (Excel 97-2003) -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>5.2.4</version> <!-- 使用最新稳定版 -->
    </dependency>
    <!-- 处理XLSX (Excel 2007+) -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.4</version>
    </dependency>
</dependencies>

三、完整代码实现

以下代码通过POI读取.xls文件内容,并逐行逐单元格写入新的.xlsx文件:

import org.apache.poi.hssf.usermodel.HSSFWorkbook;  // 处理XLS
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;  // 处理XLSX

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class XlsToXlsxConverter {

    public static void main(String[] args) {
        String inputXlsPath = "input.xls";   // 输入的XLS文件路径
        String outputXlsxPath = "output.xlsx"; // 输出的XLSX文件路径

        try (FileInputStream fis = new FileInputStream(inputXlsPath);
             Workbook xlsWorkbook = new HSSFWorkbook(fis); // 读取XLS
             Workbook xlsxWorkbook = new XSSFWorkbook()) { // 创建XLSX

            // 获取XLS的第一个工作表(Sheet)
            Sheet xlsSheet = xlsWorkbook.getSheetAt(0);
            
            // 在XLSX中创建同名工作表
            Sheet xlsxSheet = xlsxWorkbook.createSheet(xlsSheet.getSheetName());

            // 遍历XLS的每一行
            for (int rowNum = 0; rowNum <= xlsSheet.getLastRowNum(); rowNum++) {
                Row xlsRow = xlsSheet.getRow(rowNum);
                if (xlsRow == null) continue; // 跳过空行

                // 在XLSX中创建对应行
                Row xlsxRow = xlsxSheet.createRow(rowNum);

                // 遍历当前行的每一单元格
                for (int cellNum = 0; cellNum < xlsRow.getLastCellNum(); cellNum++) {
                    Cell xlsCell = xlsRow.getCell(cellNum);
                    if (xlsCell == null) continue; // 跳过空单元格

                    // 在XLSX中创建对应单元格
                    Cell xlsxCell = xlsxRow.createCell(cellNum);

                    // 复制单元格样式
                    CellStyle newCellStyle = xlsxWorkbook.createCellStyle();
                    newCellStyle.cloneStyleFrom(xlsCell.getCellStyle());
                    xlsxCell.setCellStyle(newCellStyle);

                    // 复制单元格值(根据数据类型处理)
                    switch (xlsCell.getCellType()) {
                        case STRING:
                            xlsxCell.setCellValue(xlsCell.getStringCellValue());
                            break;
                        case NUMERIC:
                            if (DateUtil.isCellDateFormatted(xlsCell)) {
                                xlsxCell.setCellValue(xlsCell.getDateCellValue());
                            } else {
                                xlsxCell.setCellValue(xlsCell.getNumericCellValue());
                            }
                            break;
                        case BOOLEAN:
                            xlsxCell.setCellValue(xlsCell.getBooleanCellValue());
                            break;
                        case FORMULA:
                            xlsxCell.setCellFormula(xlsCell.getCellFormula());
                            break;
                        case BLANK:
                            xlsxCell.setBlank();
                            break;
                        case ERROR:
                            xlsxCell.setCellErrorValue(xlsCell.getErrorCellValue());
                            break;
                        default:
                            xlsxCell.setCellValue(""); // 未知类型默认空值
                    }
                }
            }

            // 将XLSX写入文件
            try (FileOutputStream fos = new FileOutputStream(outputXlsxPath)) {
                xlsxWorkbook.write(fos);
            }

            System.out.println("转换成功!文件已保存至: " + outputXlsxPath);

        } catch (IOException e) {
            System.err.println("转换失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

四、代码解析

  1. 读取XLS文件​:
    使用HSSFWorkbook(POI提供的XLS专用类)通过FileInputStream加载.xls文件。
  2. 创建XLSX文件​:
    使用XSSFWorkbook(POI提供的XLSX专用类)创建一个新的空白工作簿。
  3. 逐行逐单元格复制​:
    • 遍历XLS的每个工作表(示例中仅处理第一个工作表,可通过getSheetAt(index)getSheet(name)获取其他表)。
    • 对每一行和每一个单元格,创建对应的XLSX行和单元格,并复制样式​(如字体、颜色、边框等)。
    • 特别注意处理不同数据类型(文本、数字、日期、布尔值、公式、空值、错误值)。
  4. 写入XLSX文件​:
    通过FileOutputStream将生成的XLSX工作簿保存到指定路径。

五、注意事项

  1. 依赖版本兼容性​:
    确保使用的Apache POI版本支持你的Java环境(如Java 8+)。推荐使用最新稳定版(如5.2.4+)。
  2. 大文件处理优化​:
    若处理大型XLS文件(如超过几十万行),建议使用SXSSFWorkbook(流式写入XLSX,避免内存溢出),但本例中直接使用XSSFWorkbook已足够(因是从XLS转换,数据量通常可控)。
  3. 样式兼容性​:
    部分复杂样式(如条件格式、合并单元格的特殊效果)可能在转换后略有差异,建议转换后人工核对关键格式。
  4. 多工作表支持​:
    若XLS包含多个工作表,可通过循环遍历xlsWorkbook.getNumberOfSheets()xlsWorkbook.getSheetAt(i)处理所有表。
  5. 异常处理​:
    实际项目中应更细致地捕获异常(如文件不存在、格式错误等),并添加日志记录。

六、扩展:使用EasyExcel(阿里开源库,适合大数据量)

如果需要处理超大型Excel文件(如百万行级),推荐使用阿里开源的EasyExcel​(基于POI但优化了内存占用)。但EasyExcel主要面向读写优化,直接转换XLS到XLSX仍需依赖POI(因EasyExcel不直接支持读取.xls)。


总结

通过Apache POI库,Java开发者可以轻松实现.xls.xlsx的格式转换。核心步骤包括:用HSSFWorkbook读取旧格式文件,用XSSFWorkbook创建新格式文件,逐行逐单元格复制数据与样式,最后保存为新文件。此方法适用于大多数常规需求,且代码灵活可控。根据实际场景(如是否需要处理多表、大文件或复杂样式),可进一步优化代码逻辑。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞70 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容