有没有办法使用Dataflow读取Excel文件

时间:2017-04-26 05:59:04

标签: google-cloud-storage google-cloud-dataflow

有没有办法使用Dataflow读取存储在GCS存储桶中的Excel文件?

我还想知道我们是否可以使用Dataflow访问GCS中对象的元数据。如果是,那么如何?

3 个答案:

答案 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

https://cloud.google.com/dataflow/model/par-do#side-inputs

答案 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());
            }    

        }
      }