如何从 Scala Spark 中的 Excel (xls,xlsx) 文件构造数据框?

Posted

技术标签:

【中文标题】如何从 Scala Spark 中的 Excel (xls,xlsx) 文件构造数据框?【英文标题】:How to construct Dataframe from a Excel (xls,xlsx) file in Scala Spark? 【发布时间】:2017-05-26 08:13:08 【问题描述】:

我有一个包含多个工作表的大型Excel(xlsx and xls) 文件,我需要将其转换为RDDDataframe,以便以后可以将其加入其他dataframe。我正在考虑使用Apache POI 并将其另存为CSV,然后在dataframe 中读取csv。但是,如果有任何库或 API 可以在此过程中提供帮助,那将很容易。非常感谢任何帮助。

【问题讨论】:

通过步骤***.com/a/47721326/2112382检查这个答案以供新手使用 【参考方案1】:

解决您的问题的方法是在您的项目中使用Spark Excel 依赖项。

Spark Excel 具有灵活的options 可供使用。

我已经测试了从excel 读取的以下代码并将其转换为dataframe 并且它运行完美

def readExcel(file: String): DataFrame = sqlContext.read
    .format("com.crealytics.spark.excel")
    .option("location", file)
    .option("useHeader", "true")
    .option("treatEmptyValuesAsNulls", "true")
    .option("inferSchema", "true")
    .option("addColorColumns", "False")
    .load()

val data = readExcel("path to your excel file")

data.show(false)

如果您的 Excel 工作表有多个工作表,您可以将 sheetname 指定为 option

.option("sheetName", "Sheet2")

希望对你有帮助

【讨论】:

如果未指定 sheetName,它会处理所有选项卡吗? 我使用了spark.read.format("com.crealytics.spark.excel").option("location","/home/mylocation/myfile.xlsx").load(),但得到了java.lang.IllegalArgumentException: Parameter "path" is missing in options. @Regressor 尝试不使用位置并使用github.com/crealytics/spark-excel中提到的加载路径 'sheetName' 不再起作用。你必须使用'dataAddress' - github.com/crealytics/spark-excel/issues/118【参考方案2】:

这里是 readwrite 示例,用于读取和写入 excel 具有全套选项。..

来源spark-excel from crealytics

Scala API Spark 2.0+:

从 Excel 文件创建 DataFrame

    import org.apache.spark.sql._

val spark: SparkSession = ???
val df = spark.read
         .format("com.crealytics.spark.excel")
        .option("sheetName", "Daily") // Required
        .option("useHeader", "true") // Required
        .option("treatEmptyValuesAsNulls", "false") // Optional, default: true
        .option("inferSchema", "false") // Optional, default: false
        .option("addColorColumns", "true") // Optional, default: false
        .option("startColumn", 0) // Optional, default: 0
        .option("endColumn", 99) // Optional, default: Int.MaxValue
        .option("timestampFormat", "MM-dd-yyyy HH:mm:ss") // Optional, default: yyyy-mm-dd hh:mm:ss[.fffffffff]
        .option("maxRowsInMemory", 20) // Optional, default None. If set, uses a streaming reader which can help with big files
        .option("excerptSize", 10) // Optional, default: 10. If set and if schema inferred, number of rows to infer schema from
        .schema(myCustomSchema) // Optional, default: Either inferred schema, or all columns are Strings
        .load("Worktime.xlsx")

将 DataFrame 写入 Excel 文件

    df.write
      .format("com.crealytics.spark.excel")
      .option("sheetName", "Daily")
      .option("useHeader", "true")
      .option("dateFormat", "yy-mmm-d") // Optional, default: yy-m-d h:mm
      .option("timestampFormat", "mm-dd-yyyy hh:mm:ss") // Optional, default: yyyy-mm-dd hh:mm:ss.000
      .mode("overwrite")
      .save("Worktime2.xlsx")

注意:您也可以使用它们的名称来代替 sheet1 或 sheet2.. 在上面给出的示例中,Daily 是工作表名称。

如果你想从 spark shell 中使用它...

可以使用--packages 命令行选项将此包添加到 Spark。例如,在启动 spark shell 时包含它:

    $SPARK_HOME/bin/spark-shell --packages com.crealytics:spark-excel_2.11:0.13.1

需要添加依赖项(如果是 maven 等...):
groupId: com.crealytics
artifactId: spark-excel_2.11
version: 0.13.1

Further reading : See my article (How to do Simple reporting with Excel sheets using Apache Spark, Scala ?) of how to write in to excel file after an aggregations in to many excel sheets

提示:这是非常有用的方法,尤其是对于写作 maven 测试用例,您可以在其中将带有示例数据的 excel 工作表放在 excel 中 src/main/resources 文件夹,您可以在单元测试用例(scala/java)中访问它们,这会从 excel 表中创建 DataFrame[s]...

您可以考虑的另一个选项是 spark-hadoopoffice-ds

HadoopOffice 库的 Spark 数据源。这个 Spark 数据源 假设至少 Spark 2.0.1。但是,HadoopOffice 库可以 也可以直接从 Spark 1.x 使用。目前这个数据源 支持以下格式的 HadoopOffice 库:

Excel 数据源格式:org.zuinnote.spark.office.Excel 正在加载和 保存旧 Excel (.xls) 和新 Excel (.xlsx) 此数据源是 在Spark-packages.org 和Maven Central 上可用。

【讨论】:

我使用了spark.read.format("com.crealytics.spark.excel").option("location","/home/mylocation/myfile.xlsx").load(),但得到了java.lang.IllegalArgumentException: Parameter "path" is missing in options.【参考方案3】:

或者,您可以使用 HadoopOffice 库 (https://github.com/ZuInnoTe/hadoopoffice/wiki),它还支持加密的 Excel 文档和链接的工作簿,以及其他功能。当然也支持 Spark。

【讨论】:

大家好,我们可以使用上面的方法将数据写入Excel工作表中的多个选项卡吗?。 我假设您的意思是 Excel 工作簿中的多个工作表。是的,它可以写入多张纸。基本上,您定义了一个 SpreadSheetCellDAO,它指定了 formattedValue、Comment、Formula、Address 和 Sheet。但是,为了为您提供更多支持,我需要更多地了解您的用例。随时提供信息作为 Github 问题:github.com/ZuInnoTe/hadoopoffice/issues 我有一列包含带双引号的值,例如:“xxxxx,yyy,zzz”。因此,该值不被视为单列,如果我看到数据框,而不是一列,它显示为 3 列 这很奇怪。没有基于逗号或双引号拆分该列的逻辑。您能否与 Apache POI 人员核实一下:poi.apache.org/help/index.html?能否请您验证它确实只是一列并提供示例文件?【参考方案4】:

我用的是com.crealytics.spark.excel-0.11版本的jar,用spark-Java创建的,在scala中也是一样的,只需要将javaSparkContext改为SparkContext即可。

tempTable = new SQLContext(javaSparkContxt).read()
    .format("com.crealytics.spark.excel") 
    .option("sheetName", "sheet1")
    .option("useHeader", "false") // Required 
    .option("treatEmptyValuesAsNulls","false") // Optional, default: true 
    .option("inferSchema", "false") //Optional, default: false 
    .option("addColorColumns", "false") //Required
    .option("timestampFormat", "MM-dd-yyyy HH:mm:ss") // Optional, default: yyyy-mm-dd hh:mm:ss[.fffffffff] .schema(schema)
    .schema(schema)
    .load("hdfs://localhost:8020/user/tester/my.xlsx");

【讨论】:

【参考方案5】:

希望这会有所帮助。

val df_excel= spark.read.
                   format("com.crealytics.spark.excel").
                   option("useHeader", "true").
                   option("treatEmptyValuesAsNulls", "false").
                   option("inferSchema", "false"). 
                   option("addColorColumns", "false").load(file_path)

display(df_excel)

【讨论】:

以上是关于如何从 Scala Spark 中的 Excel (xls,xlsx) 文件构造数据框?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 SPARK SCALA 中的 XML 模式中获取列名?

如何从 Scala 中的 DataFrame 在 Spark 中创建分布式稀疏矩阵

如何从代码外部提供spark / scala中的模式

如何从 SocketTCP 获取数据以保存到 Spark Scala 中的数据帧?

如何在 Spark Scala 中的 Schema RDD [从案例类中创建] 中查找重复项以及相应的重复计数?

Scala - 如何在 Spark 的 map 函数中实现 Try