📜  阅读 excel spark (1)

📅  最后修改于: 2023-12-03 15:12:47.926000             🧑  作者: Mango

阅读 Excel Spark

Apache Spark是一个开源的分布式计算框架,它提供了一种基于内存的计算模型,可以处理大规模数据并且速度非常快。而在数据处理中,Excel是一个非常常见的数据格式。所以本篇文章将会介绍如何在Spark中阅读Excel。

Excel文件

在Java中,我们可以使用Apache POI库来处理Excel文档。POI库有一个子项目POI-OOXML,它可以处理扩展名为.xlsx的Excel文件。(如果是扩展名为.xls的Excel文件,则需要使用POI的另一个子项目POI-HSSF)。

关于POI库的使用,可以查看相应的官方文档。

以DataFrame的形式读取Excel

Spark可以将Excel中的数据读取为DataFrame。要让Spark读取Excel文件,首先需要将Excel文件加载到Hadoop文件系统中。

在本地使用Spark时,可以使用如下的代码将Excel文件加载到Hadoop文件系统中:

import org.apache.hadoop.fs.{FileSystem, Path}
val srcPath = new Path("file:///path/to/excel/file.xlsx")
val dstPath = new Path("hdfs:///path/to/excel/file.xlsx")
val fileSystem = FileSystem.get(spark.sparkContext.hadoopConfiguration)
fileSystem.copyFromLocalFile(srcPath, dstPath)

这里将Excel文件从本地文件系统复制到Hadoop文件系统中,以便Spark能够读取它。

接下来,使用Spark的read方法和Excel数据源连接器来读取Excel文件:

val df = spark.read
  .format("com.crealytics.spark.excel")
  .option("header", "true")
  .option("inferSchema", "true")
  .load("hdfs:///path/to/excel/file.xlsx")

这里的com.crealytics.spark.excel是Excel数据源连接器的类名,Spark会根据这个类去读取Excel文件。在读取Excel文件时,需要设置选项headertrue,表示Excel文件的第一行包含表头信息。还需要设置选项inferSchematrue,表示Spark会根据数据内容自动推断每一列的数据类型。

最后使用show方法展示DataFrame中的数据:

df.show()
以RDD的形式读取Excel

读取Excel文件的另一个方法是将Excel文件读取到RDD中。在Spark中,我们可以使用Hadoop的ExcelRecordReader来读取Excel文件,并将读取的每一行封装成一个类似于DataFrame中的Row的对象。

这里给出一个读取Excel文件到RDD的示例代码:

import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.FileSystem
import org.apache.hadoop.fs.Path
import org.apache.hadoop.io.LongWritable
import org.apache.hadoop.io.Text
import org.apache.hadoop.mapred.TextInputFormat
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.Row
val filePath = "hdfs:///path/to/excel/file.xlsx"
val fileSystem = FileSystem.get(sc.hadoopConfiguration)
val inputStream = fileSystem.open(new Path(filePath))
val workbook = new XSSFWorkbook(inputStream)
val sheet = workbook.getSheetAt(0)
val conf = new Configuration(sc.hadoopConfiguration)
conf.set(TextInputFormat.INPUT_DIR, filePath)
val rawData = sc.hadoopRDD(conf, classOf[TextInputFormat],
  classOf[LongWritable], classOf[Text], 1)
val header = sheet.getRow(0).toArray.map(_.toString)
val rows = rawData.map(x => x._2.toString.split(","))
  .filter(row => row.length == header.length)
  .map(row => Row.fromSeq(row))
val schema = StructType(header.map(fieldName => StructField(fieldName, StringType, true)))
val rdd = spark.sqlContext.createDataFrame(rows, schema).rdd

这里的代码比较长,但思路比较简单。首先读取Excel文件中的数据所在的Sheet,并将其转换为RDD。由于Excel文件中的每一行都会被转换为一条文本,所以我们需要将文本再转换为一个个单元格,最后组成一行数据。

这里的header表示Excel文件的表头,rows表示Excel文件的数据。接下来,我们使用Spark的StructTypeStructField类定义Schema,使用createDataFrame方法将RDD转换为DataFrame。

总结

在Spark中,阅读Excel文件有两种方法:一种是将Excel文件转换为DataFrame,另一种是将Excel文件转换为RDD。在两种方法中,将Excel文件加载到Hadoop文件系统中是必要的步骤。对于某些不支持Java的语言,我们还可以使用Python或R来读取Excel文件。