Java上传Excel同时兼容2003和2007 解决read error和org.apache.poi.poifs.filesystem.OfficeXmlFileException异常

上传Excel部分代码块:

FileInputStream is = new FileInputStream(file);
//HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is); 
Workbook hssfWorkbook = null; 
try { 
    hssfWorkbook = new HSSFWorkbook(is); 
} catch (Exception ex) {
    // 解决read error异常
    is = new FileInputStream(file);
    hssfWorkbook = new XSSFWorkbook(is); 
} 
//HSSFWorkbook hssfWorkbook = new HSSFWorkbook(is);
List<String> list = new ArrayList<String>();
// 循环工作表Sheet
for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {
    //HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
    Sheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
    if (hssfSheet == null) {
        continue;
    }
    // 循环行Row
    for (int rowNum = 1; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
        //HSSFRow hssfRow = hssfSheet.getRow(rowNum);
        Row hssfRow = hssfSheet.getRow(rowNum);
        if (hssfRow == null) {
            continue;
        }
        //HSSFCell xh = hssfRow.getCell(0);
        Cell xh = hssfRow.getCell(0);
        if (xh == null) {
            continue;
        }
        list.add(xh.getStringCellValue());
    }
}

注掉的代码部分是只支持Excel2003的,这时候如果导入Excel2007的文件就会报如下异常:
org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)

如果只是支持Excel2003的话,需要导入的poi包只需要:
- dom4j-1.6.1.jar
- poi-3.8-20120326.jar
但是如果要同时支持Excel2003和Excel2007就得需要:

  • dom4j-1.6.1.jar
  • poi-3.8-20120326.jar
  • poi-ooxml-3.8-20120326.jar
  • poi-ooxml-schemas-3.8-20120326.jar
  • poi-scratchpad-3.8-20120326.jar
  • xmlbeans-2.3.0.jar

另外,发生如下异常:
java.io.IOException: Read error
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(Unknown Source)
……
是因为在hssfWorkbook = new HSSFWorkbook(is); 创建失败抛出异常后FileInputStream被关闭了,所以在创建XSSFWorkbook之前要再重新创建FileInputStream。

参考文章:
1.http://my.oschina.net/u/658145/blog/268112
2.http://blog.youkuaiyun.com/mmm333zzz/article/details/7962377
3.http://blog.youkuaiyun.com/sdfe63/article/details/20955209

### 关于 `org.apache.poi.poifs.filesystem.OfficeXmlFileException` 的原因及解决方法 `org.apache.poi.poifs.filesystem.OfficeXmlFileException` 异常通常出现在使用 Apache POI 库处理 Excel 文件时。该异常表明当前使用的代码或库版本与目标文件格式不匹配。具体来说,当尝试用 HSSF(用于处理 .xls 格式的 Excel 文件)来读取 Office 2007+ 的 XML 格式文件(.xlsx)时,会触发此异常[^1]。 #### 原因分析 1. **文件格式不匹配**:HSSF 是 Apache POI 中用于处理旧版 Excel 文件(.xls 格式)的模块。如果尝试用 HSSF 来读取 .xlsx 格式的文件,则会抛出此异常,因为 .xlsx 文件是基于 XML 的新格式,需要使用 XSSF 模块进行处理。 2. **依赖库缺失或版本问题**:在 Maven 项目中,如果未正确引入 `poi-ooxml` 依赖,或者引入的版本过低,也可能导致无法正确解析 .xlsx 文件。例如,`poi-ooxml` 提供了对 Office Open XML 格式的支持,而仅引入 `poi` 依赖则不足以处理 .xlsx 文件[^2]。 #### 解决方案 1. **选择正确的 POI 模块**: - 如果目标文件是 `.xls` 格式,使用 HSSF 模块。 - 如果目标文件是 `.xlsx` 格式,使用 XSSF 模块。 2. **确保正确的 Maven 依赖**: 在 Maven 项目中,需确保引入了 `poi-ooxml` 依赖以支持 .xlsx 文件的处理。以下是一个示例配置: ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.2.3</version> <!-- 推荐使用最新稳定版本 --> </dependency> ``` 3. **代码调整**: 需要根据文件类型动态选择合适的 POI 工具类。以下是一个示例代码片段,展示如何根据文件扩展名选择 HSSF 或 XSSF: ```java import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import java.io.File; import java.io.FileInputStream; public class ExcelReader { public static Workbook getWorkbook(String filePath) throws Exception { FileInputStream fis = new FileInputStream(new File(filePath)); return WorkbookFactory.create(fis); // 自动判断文件类型并创建对应的 Workbook 实例 } public static void main(String[] args) { try { Workbook workbook = getWorkbook("example.xlsx"); System.out.println("Workbook loaded successfully."); } catch (Exception e) { e.printStackTrace(); } } } ``` 上述代码使用了 `WorkbookFactory.create()` 方法,它可以自动识别文件格式并返回相应的 `Workbook` 实例,无需手动区分 HSSF XSSF。 4. **检查文件内容**: 确保目标文件未被损坏。如果文件本身存在问题(如部分内容丢失或格式错误),即使使用正确的工具类依赖库,也可能无法成功加载文件。 #### 注意事项 - 如果需要同时支持 `.xls` `.xlsx` 文件,推荐使用 `WorkbookFactory`,它能够自动检测文件格式并返回适当的 `Workbook` 实例。 - 确保使用的 Apache POI 版本足够新以支持所需功能。例如,`poi-ooxml` 的较新版本(如 5.x 系列)提供了更好的兼容性能。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值