有没有办法使用Dataflow读取存储在GCS存储桶中的Excel文件?
我还想知道我们是否可以使用Dataflow访问GCS中对象的元数据。如果是,那么如何?
答案 0 :(得分:2)
CSV文件通常用于从excel读取文件。这些文件可以逐行拆分和读取,因此非常适合数据流。您可以使用TextIO.Read拉入文件的每一行,然后将它们解析为CSV行。
如果你想使用不同的二进制excel格式,那么我相信你需要读入整个文件并使用库来解析它。如果可以的话,我建议使用CSV文件。
至于阅读GCS元数据。我不认为您可以使用TextIO执行此操作,但您可以直接调用GCS API来访问元数据。如果你只是在程序开始时为一些文件执行此操作,那么它将起作用并且不会太昂贵。如果您需要阅读这样的许多文件,那么您将为每个文件添加额外的RPC。
小心不要多次读取同一个文件,我建议一次读取每个文件的元数据,然后将元数据写入侧输入。然后在您的一个ParDo中,您可以访问每个文件的侧输入。
有用的链接: ETL & Parsing CSV files in Cloud Dataflow
https://cloud.google.com/dataflow/java-sdk/JavaDoc/com/google/cloud/dataflow/sdk/io/TextIO.Read
答案 1 :(得分:1)
您应该能够使用GCS API读取GCS文件的元数据。但是你需要文件名。您可以通过对包含文件名的PCollection<string>
列表执行ParDo或其他转换来执行此操作。
我们没有excel文件的默认读者。您可以使用文本输入来解析CSV文件:(ETL & Parsing CSV files in Cloud Dataflow)
我对excel知之甚少,以及文件格式的存储方式。如果要一次处理一个文件,可以使用PCollection<string>
个文件。然后使用一些库一次解析excel文件。
如果可以将excel文件拆分为易于部署的部分,我建议您查看此文档(https://beam.apache.org/documentation/io/authoring-overview/)。 (如果您仍在使用Dataflow SDK,它应该是类似的。)在读取之前可能需要拆分成更小的块,以便从管道中获得更多的并行化。在这种情况下,您可以使用IOChannelFactory从文件中读取。
答案 2 :(得分:0)
private static final int BUFFER_SIZE = 64 * 1024;
private static void printBlob(com.google.cloud.storage.Storage storage, String bucketName, String blobPath) throws IOException, InvalidFormatException {
try (ReadChannel reader = ((com.google.cloud.storage.Storage) storage).reader(bucketName, blobPath)) {
InputStream inputStream = Channels.newInputStream(reader);
Workbook wb = WorkbookFactory.create(inputStream);
StringBuffer data = new StringBuffer();
for(int i=0;i<wb.getNumberOfSheets();i++) {
String fName = wb.getSheetAt(i).getSheetName();
File outputFile = new File("D:\\excel\\"+fName+".csv");
FileOutputStream fos = new FileOutputStream(outputFile);
XSSFSheet sheet = (XSSFSheet) wb.getSheetAt(i);
Iterator<Row> rowIterator = sheet.iterator();
data.delete(0, data.length());
while (rowIterator.hasNext())
{
// Get Each Row
Row row = rowIterator.next();
data.append('\n');
// Iterating through Each column of Each Row
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext())
{
Cell cell = cellIterator.next();
// Checking the cell format
switch (cell.getCellType())
{
case Cell.CELL_TYPE_NUMERIC:
data.append(cell.getNumericCellValue() + ",");
break;
case Cell.CELL_TYPE_STRING:
data.append(cell.getStringCellValue() + ",");
break;
case Cell.CELL_TYPE_BOOLEAN:
data.append(cell.getBooleanCellValue() + ",");
break;
case Cell.CELL_TYPE_BLANK:
data.append("" + ",");
break;
default:
data.append(cell + ",");
}
}
}
fos.write(data.toString().getBytes());
}
}
}