Databricks中PySpark读Excel遇POI数组超限,如何用Python调整?
解决PySpark读取Excel时的POI RecordFormatException问题
问题背景
读取14MB Excel文件时触发以下错误:
org.apache.poi.util.RecordFormatException: Tried to allocate an array of length 100,335,238, but the maximum length for this record type is 100,000,000.
使用环境:
- Databricks Runtime 15.4 LTS
- spark-excel包版本:
com.crealytics:spark-excel_2.12:3.5.1_0.20.4 - 读取代码:
spark.read.format("com.crealytics.spark.excel") \ .option("header", "true") \ .schema(input_schema) \ .load(path) \ .display()
错误根源是Apache POI默认限制字节数组最大长度为1亿,文件中存在超出该限制的内部记录(即使文件总大小仅14MB)。
解决方案
1. 在PySpark中调用JVM的IOUtils调整上限
PySpark可通过py4j直接调用JVM中的IOUtils类修改POI的字节数组上限,需在读取Excel前执行:
from py4j.java_gateway import java_import # 获取当前Spark上下文的JVM实例 jvm = spark.sparkContext._jvm # 导入Apache POI的IOUtils类 java_import(jvm, "org.apache.poi.util.IOUtils") # 设置字节数组最大长度为2亿(可根据实际需求调整) jvm.IOUtils.setByteArrayMaxOverride(200000000)
注意:Databricks Runtime 15.4 LTS自带的POI版本与指定的spark-excel包兼容,无需额外调整依赖。
2. 调整spark-excel读取选项优化内存占用
通过分块读取限制内存中的行数,避免一次性加载过大的记录:
spark.read.format("com.crealytics.spark.excel") \ .option("header", "true") \ .option("maxRowsInMemory", 10000) # 每次加载1万行到内存 .schema(input_schema) \ .load(path) \ .display()
若错误由单个超大单元格导致,建议先检查并预处理Excel文件,拆分或清理包含异常大量内容的单元格。
3. 转换文件格式后读取
若上述方法无效,可先将Excel转换为CSV再读取(适合小文件场景):
import pandas as pd # 用pandas读取Excel文件 pdf = pd.read_excel(path, header=0, dtype={col.name: col.dataType.simpleString() for col in input_schema.fields}) # 转换为Spark DataFrame df = spark.createDataFrame(pdf) df.display()
内容的提问来源于stack exchange,提问作者the_economist
相关产品推荐
相关产品推荐

