You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache POI生成Excel文件无效且缺失表头问题求助

Apache POI生成Excel踩坑:表头缺失+文件无效

问题场景

用Apache POI生成Excel时碰到俩问题:

  1. 生成的文件看不到表头
  2. 文件打开提示无效,用文本编辑器查看是CSV格式内容

用到的代码

// write file
@Override
public File writeFile(final List<Place> places) {

    final File file = new File(filePath);
    
    try (XSSFWorkbook workbook = new XSSFWorkbook()) {
        XSSFSheet sheet = workbook.createSheet();
        createHeaderRow(sheet);
        int rowCount = 1;
        for (Place aBook : places) {
            XSSFRow row = sheet.createRow(++rowCount);
            writeBook(aBook, row);
        }
        writeWorkbook(file, workbook);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return file;
}

private void writeWorkbook(final File file, Workbook workbook) {
    try (FileOutputStream outputStream = new FileOutputStream(file.getAbsolutePath())) {
        workbook.write(outputStream);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void writeBook(Place place, XSSFRow row) {
    Cell cell = row.createCell(1);
    cell.setCellValue(place.getName());

    cell = row.createCell(2);
    cell.setCellValue(place.getPhone());

    cell = row.createCell(3);
    cell.setCellValue(place.getFormattedAddress());

    cell = row.createCell(4);
    cell.setCellValue(place.getUserRatingsTotal());

    cell = row.createCell(5);
    cell.setCellValue(place.getRating());

    cell = row.createCell(6);
    cell.setCellValue(place.getWebsite());

}

private void createHeaderRow(XSSFSheet sheet) {

    CellStyle cellStyle = sheet.getWorkbook().createCellStyle();
    Font font = sheet.getWorkbook().createFont();
    font.setBold(true);
    font.setFontHeightInPoints((short) 16);
    cellStyle.setFont(font);

    XSSFRow row = sheet.createRow(0);

    XSSFCell cellName = row.createCell(1);
    cellName.setCellStyle(cellStyle);
    cellName.setCellValue("Name");

    XSSFCell cellPhone = row.createCell(2);
    cellPhone.setCellStyle(cellStyle);
    cellPhone.setCellValue("Phone Number");

    XSSFCell cellAddress = row.createCell(3);
    cellAddress.setCellStyle(cellStyle);
    cellAddress.setCellValue("Address");

    XSSFCell cellRatings = row.createCell(4);
    cellRatings.setCellStyle(cellStyle);
    cellRatings.setCellValue("Number of Ratings");

    XSSFCell cellRating = row.createCell(5);
    cellRating.setCellStyle(cellStyle);
    cellRating.setCellValue("Overall Rating");

    XSSFCell cellWebsite = row.createCell(6);
    cellWebsite.setCellStyle(cellStyle);
    cellWebsite.setCellValue("Wesbite");
}

文件异常表现

  • 打开Excel时提示“文件无效”
  • 用Notepad++打开文件,内容为CSV格式:
'Advocate';'8888881888';'';'CbIJVVWlK60EDTkRVr1M5nyrY_U';'address';'134';'4.9'

问题解决

1. 表头缺失的原因及修复

表头看不到的核心原因是POI生成的XLSX文件根本没写入成功,你看到的是旧的CSV文件内容,自然看不到表头。另外代码里还有个小细节:表头和数据的单元格都是从列索引1开始创建,列0会是空的,但这不会导致表头消失,只是多了一列空白。

修复步骤:

  • 修正数据行的起始索引,避免空出行1:
// 行0是表头,第一行数据从行1开始
int rowCount = 1;
for (Place place : places) {
    XSSFRow row = sheet.createRow(rowCount++); // 用后置递增,避免跳过行1
    writeBook(place, row);
}
  • 完善异常处理,不要只打印异常,抛出异常让调用方感知写入失败,避免返回无效文件。

2. 文件无效的原因及修复

文件无效且显示为CSV内容,说明POI的XLSX写入操作失败,目标文件保留了之前的内容,或者有其他代码在操作同一个文件路径。具体排查和修复:

  • 清理旧文件:生成新文件前先删除旧文件,避免旧内容干扰:
final File file = new File(filePath);
if (file.exists()) {
    file.delete();
}
  • 优化写入逻辑:强制刷入数据到磁盘,并抛出异常提示失败:
private void writeWorkbook(final File file, Workbook workbook) {
    try (FileOutputStream outputStream = new FileOutputStream(file.getAbsolutePath())) {
        workbook.write(outputStream);
        outputStream.flush(); // 强制把数据刷入磁盘
    } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException("写入Excel文件失败", e);
    }
}
  • 检查文件后缀:确保filePath的后缀是.xlsx,因为XSSFWorkbook生成的是XLSX格式,后缀不对会导致打开提示无效。
  • 排查其他写入逻辑:确认代码中有没有其他地方向同一个文件路径写入CSV内容,覆盖了POI生成的XLSX。

内容的提问来源于stack exchange,提问作者Abhishek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 18:39:42