Spark 2.2使用spark-excel加载Excel时列名类型异常求助
解决Spark-Excel读取数值类型列名时的异常问题
我之前也碰到过一模一样的问题,这个报错的根源很明确:com.crealytics.spark.excel包在开启useHeader=true和inferSchema=true时,会默认尝试把表头单元格按字符串类型读取,但如果你的Excel表头单元格是数值格式(比如纯数字列名,单元格类型设为数值),POI底层库就会抛出Cannot get a STRING value from a NUMERIC cell的类型不匹配异常。
下面给你几个实用的解决办法:
1. 手动指定Schema(最推荐)
关闭自动推断Schema的功能,自己定义StructType来指定列名和对应的数据类型,这样Spark就不会去解析表头单元格的类型,直接用你定义的字符串列名:
import org.apache.spark.sql.types._ // 根据你的Excel实际列结构定义Schema,列名统一用字符串格式 val customSchema = StructType(Array( StructField("1001", StringType, nullable = true), StructField("2002", IntegerType, nullable = true), StructField("3003", DoubleType, nullable = true) // 按实际列数和数据类型补充 )) val excelDF = spark.read .format("com.crealytics.spark.excel") .option("useHeader", "true") .option("treatEmptyValuesAsNulls", "true") .option("inferSchema", "false") // 必须关闭自动推断 .option("addColorColumns", "False") .option("sheetName", sheetName) .schema(customSchema) // 绑定自定义Schema .load(filePath)
2. 将表头行作为数据读取后手动处理
如果无法提前确定Schema结构,可以先把表头当成普通数据行读取,再提取第一行作为列名,最后过滤掉表头行:
// 先不启用表头模式,读取所有行 val tempDF = spark.read .format("com.crealytics.spark.excel") .option("useHeader", "false") .option("treatEmptyValuesAsNulls", "true") .option("inferSchema", "true") .option("addColorColumns", "False") .option("sheetName", sheetName) .load(filePath) // 提取第一行作为列名,自动将数值类型的单元格转为字符串 val headerRow = tempDF.first() val columnNames = headerRow.toSeq.map(_.toString) // 重命名列并过滤掉表头行 val excelDF = tempDF .toDF(columnNames: _*) .filter(row => !row.equals(headerRow))
注意:这种方式下inferSchema会基于表头行推断数据类型,可能和实际数据的类型不符,后续可能需要手动转换列类型。
3. 批量修改Excel表头格式(适合文件数量少的场景)
如果待处理的Excel文件数量不多,可以批量把表头单元格的格式设置为文本类型,这样spark-excel就能正常读取字符串类型的列名,这也是你已经验证有效的方法。
内容的提问来源于stack exchange,提问作者nilesh1212
相关产品推荐
相关产品推荐

