見出し画像

【業務効率化】ExcelをCloud FunctionでCSV形式に変換してBigQueryに連携する

今回は、Excelのxlsx形式のファイルをCloud Storageにアップロード後、Cloud Functionでcsv形式に変換して、Bigqueryに連携する方法をまとめていきます。

この投稿は、Google Cloudのアカウント設定はすでに完了している前提で進めていきます。

全体の流れは以下です。
①ExcelファイルをCloud Storageにアップロードする
②Cloud Functionでcsv形式に変換
③Cloud StorageからBigqueryに連携

Cloud Storageでバケットをつくる

Excelファイルをアップロードするバケットを作成する

Google CloudでCloud Storageを表示して「バケット」を選択します。

上部にある「+作成」をクリックする。

バケットに名前を付けて「続行」をクリックする

「Region」「asia-northest1(東京)」を選択して
「続行」をクリックする。

その他の項目はそのままで[続行]を選択して、最後[作成]を選択します。バケットが作成されました。

もうひとつ、CSVファイルをアップロードするバケットを作成する

上記Excel用バケットと同じ要領でもうひとつバケットを作成しておきます。

アップロードするExcelファイルの準備

Excelでxlsx形式のファイルを生成します。
ファイルをマージするため、2ファイル生成します。

Cloud Functionsで関数をデプロイする

イベントを作成する

+ファンクションを作成をクリックします

環境:第1世代
関数名:ここではcsv_test
トリガーのタイプ:Cloud Storage
バケット:ここではxslx_upload_test
「保存」して「次へ」をクリック

コードをかいていく

requirements.txtに
openpyxlとgoogle-cloud-storageライブラリを記載する

openpyxl==3.*
google-cloud-storage

次にmain.pyに以下のコードを記入して「デプロイ」をクリック

import io
import openpyxl
import re
import csv
from google.cloud import storage

def download_blob_to_buffer(blob):
    """Download a blob to an in-memory buffer."""
    buffer = io.BytesIO()
    blob.download_to_file(buffer)
    buffer.seek(0)
    return buffer

def read_excel_and_extract_data(buffer, sheet_name, start_row):
    """Read an Excel file from a buffer and extract data from a specified sheet."""
    wb = openpyxl.load_workbook(buffer)
    if sheet_name not in wb.sheetnames:
        return []
    sheet = wb[sheet_name]
    max_row, max_column = sheet.max_row, sheet.max_column

    data = []
    for row in range(start_row, max_row + 1):
        row_data = [sheet.cell(row=row, column=col).value for col in range(1, max_column + 1)]
        data.append(row_data)
    
    wb.close()
    return data

def upload_csv_to_bucket(client, bucket_name, data, output_name):
    """Upload CSV data to a specified Google Cloud Storage bucket."""
    bucket = client.get_bucket(bucket_name)
    blob = bucket.blob(output_name)

    si = io.StringIO()
    writer = csv.writer(si, quoting=csv.QUOTE_ALL)
    writer.writerows(data)
    
    blob.upload_from_string(si.getvalue(), content_type='text/csv')
    si.close()

def conv_csv_2(event, context):
    """Google Cloud Function to convert Excel files in a GCS bucket to a single CSV file."""
    BUCKET_NAME = event['bucket']
    TARGET_BUCKET_NAME = "csv_output_1"
    TARGET_SHEET_NAME = "ローデータ"
    OUT_NAME = 'merge.csv'
    START_ROW = 2

    client = storage.Client()
    bucket = client.get_bucket(BUCKET_NAME)
    blobs = client.list_blobs(BUCKET_NAME)

    data = []
    pattern = r".*\.(xlsx|xls)$"

    for blob in blobs:
        if re.match(pattern, blob.name, re.IGNORECASE):
            buffer = download_blob_to_buffer(blob)
            data.extend(read_excel_and_extract_data(buffer, TARGET_SHEET_NAME, START_ROW))

    upload_csv_to_bucket(client, TARGET_BUCKET_NAME, data, OUT_NAME)
    
    return "OK"

デプロイが終わると、緑のチェックがつきます

動作テスト

Excelファイルが、csvに変換されるかテストします。
Excelファイルをバケットにアップロードする

csvのバケット csv_output_1 に無事csv形式に変換されたファイルが格納されました。

BigQueryで外部テーブルとして登録する

次にファイルをBigqueryに連携します。

BigQuery → BigQuery Studioを選択する

データセットを作成

データセットID
リージョンを選択
データのロケーション:asia-northeast1(東京)
「データセットを作成」をクリック

データセットにテーブルを作成する

テーブルの作成元:Google Cloud Storage
参照をクリックしてバケット csvを選択「merge.scv」を選び「選択」をクリック

テーブル名を入力
テーブルタイプ:外部テーブル
スキーマ「テキストとして編集」をクリックして

以下コードを入力します。

[
  {
    "mode": "NULLABLE",
    "name": "ID",
    "type": "INTEGER",
    "description": "Identifier"
  },
  {
    "mode": "NULLABLE",
    "name": "imp",
    "type": "INTEGER",
    "description": "Impressions"
  },
  {
    "mode": "NULLABLE",
    "name": "CLICK",
    "type": "INTEGER",
    "description": "Clicks"
  },
  {
    "mode": "NULLABLE",
    "name": "CV",
    "type": "INTEGER",
    "description": "Conversions"
  }
]

テーブルが作成されました。

クエリでデータを参照する

作成したテーブルをクリックして、クエリを選択します。

SQLを入力する

SELECT * FROM 'プロジェクトID' LIMIT 1000

データを確認することができました。

まとめ

業務でExcelファイルをBigQueryにアップロードする可能性がでてきたため、csvに変換して、BigQueryで参照できるようにしてみました。
最後まで読んでいただきありがとうございます。

この記事が気に入ったらサポートをしてみませんか?