LoginSignup
6
8

More than 3 years have passed since last update.

Cloud Functions(Python) で Cloud StorageにアップロードしたファイルをExcelで文字化けしないよう変換する

Posted at

背景

BigQueryのクエリ結果をGCSに吐き出したものを社内に展開してエクセルで閲覧してほしい状況。
BigQuery -> GCS はutf8で結果を吐き出すので、エクセルで開くと日本語が文字化けしてしまう。
そこで、バケットにファイルを入れたら勝手にbom付きutf8に変換される cloud functionsを実装する。

Cloud Function with Python

初めて触る場合はこのあたりを読んで触っておくと良さげ

Python クイックスタート
最初の関数: Python

Cloud Storageで発火する関数

Cloud Storageにオブジェクトが作成されたら発火する関数とかが作れる

Cloud Storageのチュートリアル#オブジェクトのファイナライズ

サンプル

bucketに上がったファイルをbom付きutf8に変換し、prefixに bom_ をつけてuploadする関数

main.py
from google.cloud import storage


def convert_to_bom(data, context):
    bucket_name = data['bucket']
    file_path = data['name']
    prefix = 'bom_'

    file_path_arr = file_path.split('/')
    file_name = file_path_arr[-1]

    if file_name.startswith(prefix):
        return 'skipping of bom file.'

    dir_arr = file_path_arr[:-1]
    dir_path = '/'.join(dir_arr) + '/'
    local_file_path = '/tmp/' + file_name

    if(len(file_path_arr) == 1):
        new_file_path = prefix + file_path
    else:
        new_file_path = dir_path + prefix + file_name

    client = storage.Client()
    bucket = client.get_bucket(bucket_name)
    dl_blob = bucket.get_blob(file_path)
    up_blob = bucket.blob(new_file_path)

    with open(local_file_path, 'w', newline='', encoding='utf_8_sig', errors='ignore') as f:
        f.write(dl_blob.download_as_string().decode('utf8'))

    up_blob.upload_from_filename(local_file_path)

    return 'success'
requirements.txt
-i https://pypi.org/simple
cachetools==4.1.0
certifi==2020.4.5.1
chardet==3.0.4
google-api-core==1.19.0
google-auth==1.16.1
google-cloud-core==1.3.0
google-cloud-storage==1.28.1
google-resumable-media==0.5.1
googleapis-common-protos==1.52.0
idna==2.9
protobuf==3.12.2
pyasn1-modules==0.2.8
pyasn1==0.4.8
pytz==2020.1
requests==2.23.0
rsa==4.0
six==1.15.0
urllib3==1.25.9

デプロイ

gcloud functions deploy convert_to_bom --runtime python37 --trigger-resource ${YOUR_BUCKET} --trigger-event google.storage.object.finalize

ファイル書き込み時の注意点

/tmp 以外のディレクトリには書き込みできないので気をつける。書き込もうとすると関数がcrashして静かに死ぬ。

ファイル システムで書き込み可能な部分は /tmp ディレクトリだけです。このディレクトリは、関数インスタンスの一時ファイルの保存先として使用できます。

Cloud Functions 実行環境#ファイルシステム

参考

Python Client for Google Cloud Storage
[GoogleCloudStorage] GCSのPythonAPIの使い方 [備忘]

6
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8