Excel是二进制格式,必须用字节流(如InputStream)解析,字符流(如FileReader)会因解码失败导致乱码或异常;Apache POI等库均要求字节流输入,字符流仅在导出CSV等转换场景中后续使用。

Java 解析 Excel 文件时,字节流负责底层数据读取,字符流基本不参与——因为 Excel(.xls/.xlsx)是二进制格式文件,不是纯文本,不能用 FileReader、BufferedReader 等字符流直接处理。
为什么不能用字符流解析 Excel
Excel 文件内部包含大量结构化二进制数据(如单元格样式、公式、字体、合并区域等),并非按字符编码(如 UTF-8)组织的文本。若强行用 FileReader 读取 .xlsx 文件,会因字节解码失败导致乱码、异常或数据截断。字符流只适合处理纯文本(如 .csv、.txt、.xml 源码),而 Excel 是封装好的二进制容器。
字节流在 Excel 解析中的核心作用
所有主流 Excel 处理库(Apache POI、jxl)都要求传入 InputStream(字节输入流)作为数据源,原因正是 Excel 本质是字节序列:
- 使用
FileInputStream从磁盘读取原始字节 - 使用
ByteArrayInputStream从内存字节数组(如上传的byte[])构建流 - 使用
ServletInputStream或OkHttpClient响应体等网络字节流直接解析,避免落盘
实际代码中字节流的典型用法
以 Apache POI 为例,创建 Workbook 必须基于字节流:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
立即学习“Java免费学习笔记(深入)”;
// ✅ 正确:用 FileInputStream(字节流)加载 .xlsx
try (FileInputStream fis = new FileInputStream("data.xlsx");
Workbook wb = new XSSFWorkbook(fis)) {
Sheet sheet = wb.getSheetAt(0);
// ... 解析逻辑
}
若你拿到的是字符串路径,不要转成 String 再读——而是直接构造 FileInputStream;若你拿到的是上传的 MultipartFile(Spring),调用其 getInputStream() 方法,它返回的也是标准 InputStream。
字符流可能间接出现的场景
仅在以下边缘环节可能涉及字符处理,但仍由字节流驱动:
- 读取 Excel 中的字符串单元格值时,POI 内部将二进制存储的 Unicode 字符还原为 Java
String(自动完成编码转换,无需手动用 InputStreamReader) - 导出为 CSV 时,可先用 POI 解析 Excel,再用
OutputStreamWriter(字符流)写入 UTF-8 编码的 CSV 文本——这是输出阶段的“转换”,非 Excel 解析本身 - 日志或调试中打印单元格内容,本质是 String 的 toString(),与流类型无关
不复杂但容易忽略:Excel 解析这件事,从头到尾都是字节流的事。选对流类型,才能让 POI 正确识别文件头、解压 OPC 容器、定位 XL/worksheets/sheet1.xml 等内部结构。

















