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

使用Apache POI提取Excel文本类附件存在额外数据无法正常打开如何解决

问题根因

你直接调用ObjectData.getObjectData()获取到的是完整的OLE对象数据,包含了OLE结构化存储的封装头信息,不是原始的附件文件内容。exe、png这类格式对文件开头的冗余数据容错性较强,所以可以正常打开,而txt、pdf等格式要求文件内容严格匹配格式规范,多余的头部数据就会导致文件损坏无法打开。

正确实现代码

需要借助POI的OLE解析能力提取原始文件内容,修改后的代码如下:

import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.commons.io.IOUtils;
import java.io.ByteArrayInputStream;
import java.io.InputStream;

// 原有逻辑保留到判断ObjectData的分支
if (next instanceof ObjectData) {
    ObjectData o = (ObjectData) next;
    byte[] objectData = o.getObjectData();
    byte[] rawFileContent = null;
    
    // 解析OLE结构化存储提取原始文件
    try (ByteArrayInputStream bis = new ByteArrayInputStream(objectData);
         POIFSFileSystem poifs = new POIFSFileSystem(bis)) {
        
        // OLE对象中存储原始文件内容的节点通常为"CONTENTS"
        DirectoryEntry root = poifs.getRoot();
        if (root.hasEntry("CONTENTS")) {
            DocumentEntry entry = (DocumentEntry) root.getEntry("CONTENTS");
            try (InputStream entryIs = poifs.createDocumentInputStream(entry)) {
                rawFileContent = IOUtils.toByteArray(entryIs);
            }
        } else {
            // 特殊OLE对象无CONTENTS节点时直接用原始数据兜底
            rawFileContent = objectData;
        }
    } catch (Exception e) {
        // 非OLE格式的嵌入对象直接使用原始数据
        rawFileContent = objectData;
    }
    
    IOUtil.write(rawFileContent, outputPath);
} else if (next instanceof Picture) {
    // 图片提取逻辑无需修改,Picture.getData()返回的就是原始图片二进制内容
    Picture o = (Picture) next;
    IOUtil.write(o.getData(), outputPath);
}
注意事项
  • 需要额外引入poi-scratchpad依赖处理OLE结构,版本需和你当前使用的POI核心版本保持一致
  • 部分老旧Excel文件的OLE节点名可能存在差异,若CONTENTS节点不存在可自行遍历root下的子节点匹配对应文件内容
  • 可通过ObjectData.getFileName()获取原始文件名后缀,避免输出文件格式不匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:06:03