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

如何阻止HSSFWorkbook在Excel文件中嵌入系统用户名?

解决Apache POI生成XLS文件时携带系统用户名的问题

问题场景

使用Apache POI 5.2.0生成XLS文件时,通过strings工具检查发现文件中包含系统用户名(如christoffer.gamrath),即使清空文档摘要信息(作者、最后修改者等)也无法去除,导致不同机器生成的文件不一致。

原始生成代码:

void writeExcelFile() {
    var workbook = new HSSFWorkbook();
    byte[] bytes;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
        workbook.write(bos);
        bytes = bos.toByteArray();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    try {
        Files.write(Path.of("foo.xls"), bytes);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

strings工具输出示例:

$ strings foo.xls
christoffer.gamrath                                                                                          B
Arial1
Arial1
Arial1
Arial
"$"#,##0_);("$"#,##0)
"$"#,##0_);[Red]("$"#,##0)
"$"#,##0.00_);("$"#,##0.00)
"$"#,##0.00_);[Red]("$"#,##0.00)
_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)
_(* #,##0_);_(* (#,##0);_(* "-"_);_(@_)
_("$"* #,##0.00_);_("$"* (#,##0.00);_("$"* "-"??_);_(@_)
_(* #,##0.00_);_(* (#,##0.00);_(* "-"??_);_(@_)
Sheet1

问题原因

Apache POI的HSSF实现中,默认单元格样式会自动将系统用户名(取自System.getProperty("user.name"))作为样式的所有者存储,这部分信息不属于文档摘要属性,因此仅清空摘要信息无法去除。

解决方案

遍历工作簿中所有单元格样式,清空样式的所有者信息;同时保持清空文档摘要信息的操作,确保文件元数据干净。

修改后的代码:

void writeExcelFileWithoutUsername() {
    var workbook = new HSSFWorkbook();
    
    // 遍历所有单元格样式,清空所有者信息
    for (int i = 0; i < workbook.getNumCellStyles(); i++) {
        HSSFCellStyle style = workbook.getCellStyleAt(i);
        style.setOwner("");
    }
    
    // 清空文档摘要信息
    workbook.createInformationProperties();
    SummaryInformation summaryInfo = workbook.getSummaryInformation();
    if (summaryInfo != null) {
        summaryInfo.setAuthor("");
        summaryInfo.setLastAuthor("");
        summaryInfo.setTitle("");
        summaryInfo.setSubject("");
        summaryInfo.setKeywords("");
        summaryInfo.setComments("");
    }
    DocumentSummaryInformation docSummaryInfo = workbook.getDocumentSummaryInformation();
    if (docSummaryInfo != null) {
        docSummaryInfo.setCompany("");
        docSummaryInfo.setManager("");
    }
    
    byte[] bytes;
    // 使用try-with-resources自动关闭流
    try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
        workbook.write(bos);
        bytes = bos.toByteArray();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    
    try {
        Files.write(Path.of("foo_clean.xls"), bytes);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

注意事项

如果后续代码中创建新的单元格样式,需要在创建后立即调用style.setOwner(""),避免新样式再次携带系统用户名:

HSSFCellStyle newStyle = workbook.createCellStyle();
newStyle.setOwner("");
// 其他样式配置...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 06:07:45