🤳

AWS SDK V3 (TypeScript) で S3 に格納した Shift-JIS の CSV を取得・パースする

2024/08/27に公開

S3 の Shift-JIS ファイルに注意

S3 に格納したテキストファイルを扱う際、エンコードに注意する必要があります。

Shift-JIS など、エンコードが UTF-8 でない場合はパース処理が必要です!

Shift-JIS の CSV を取得・パースする

プロジェクトの準備

Shift-JIS の CSV を扱うために使用する npm パッケージは以下です。

TypeScript の実行環境を準備します。

mkdir s3-encode-sandbox
cd s3-encode-sandbox
npm init -y
npm i -D typescript tsx
npm i @aws-sdk/client-s3 iconv-lite csv-parse
npx tsc --init
touch index.ts

index.ts

S3 からのオブジェクトの取得は GetObject を使用します。

ポイントとしては GetObject のレスポンスボディが stream.Readable である点です。

Stream モジュール、iconv-lite、csv-parse を使って Shift-JIS のファイルを扱っています。

index.ts
import iconv from 'iconv-lite';
import { GetObjectCommand, S3Client } from "@aws-sdk/client-s3";
import { Readable } from 'stream';
import { parse } from 'csv-parse';

const BUCKET_NAME = "your-csv-encode-check-bucket";
const CSV_FILE_KEY = "sample.csv";

async function parseCsv(fileData: any) {
    const parsed = [];

    const decoder = iconv.decodeStream('Shift_JIS');
    // ヘッダー行を考慮する
    const parser = fileData.pipe(decoder).pipe(parse({from: 2}));
    for await (const record of parser) {
        parsed.push(record);
    }

    return parsed;
}

const main = async () => {
    const client = new S3Client({});

    const command = new GetObjectCommand({
        Bucket: BUCKET_NAME,
        Key: CSV_FILE_KEY,
    });

    try {
        const response = await client.send(command);
        if (!response?.Body) {
            throw new Error('No data');
        }

        // [POINT]: Body が stream.Readable 
        const file_data = response.Body as Readable;

        let lines = await parseCsv(file_data);
        if (lines == undefined) {
            const err = new Error('invalid file format.');
            throw err;
        }

        console.log(lines);
    } catch (err) {
        console.error(err);
    }
};

main();

実行コマンド

認証を通した状態で以下のコマンドを実行すれば、CSV の内容が出力されます。

npx tsx index.ts 

まとめ

CSV は UTF-8 がイイな🐻🐻🐻

参考

コラボスタイル Developers

Discussion