S3にあるShift-JISのCSVファイルをLambda(node.js)で読み込んでUTF-8に変換してS3にアップする – AWS SDK for JavaScript v3
Shift-JISのCSVファイルを用意します。機種依存文字とかも入れてみます。(①)
streamのままuploadしたいので@aws-sdk/lib-storageをインストールします。文字コード関連はiconv-liteを使用します。
npm i --save @aws-sdk/client-s3 @aws-sdk/lib-storage iconv-lite
バケットのtmp/in.csvとしてcpしておきます。
Lambda(node.js)
Shift-JIS(機種依存文字が入っているのでCP932)のCSVファイルをS3に配置しているので、iconv-liteモジュールを使用してCP932で読み込む必要があります。
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3' import { Upload } from '@aws-sdk/lib-storage' import iconv from 'iconv-lite' export async function handler(event, context) { const input = { Bucket: '<バケット名>', Key: 'tmp/in.csv' } const client = new S3Client({ region: 'ap-northeast-1' }) const command = new GetObjectCommand(input) const data = await client.send(command) // cp932(ms932)で読み込む const bodyContents = data.Body.pipe(iconv.decodeStream('CP932')) const upload = new Upload({ client: client, params: { Bucket: '<バケット名>', Key: 'var/data/out.csv', Body: bodyContents // stream upload } }) upload.on('httpUploadProgress', progress => { console.log(progress) }) await upload.done() const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!') } return response }
これでバケットのvar/data/out.csvにPUTしなおしています。
PUTしなおしたファイルは文字コードがUTF-8に変わっています。
2次元配列に変換する
Shift-JISだとs3 selectできないので、そのまま取得し2次元配列に変換してみます。
GetObjectCommandとcsv-parse/syncモジュールを使用します。
$ npm i csv-parse
index.mjs
import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3' import { parse } from 'csv-parse/sync' import iconv from 'iconv-lite' export const handler = async(event) => { const input = { Bucket: '<バケット名>', Key: 'tmp/in.csv' } const client = new S3Client({ region: 'ap-northeast-1' }) const command = new GetObjectCommand(input) const data = await client.send(command) const bodyContents = data.Body.pipe(iconv.decodeStream('CP932')) const csv = parse(await streamToString(bodyContents),{ columns: false, // JSON配列として扱いたい場合はtrue from_line: 2 // ヘッダ行スキップする(基底=1) }) console.log(csv) // 2次元配列として扱える const response = { statusCode: 200, body: JSON.stringify('Hello from Lambda!'), } return response } async function streamToString(stream) { let chunks = [] await new Promise((resolve, reject) => { stream.on('data', chunk => chunks.push(chunk)) stream.on('error', reject) stream.on('end', () => resolve()) }) return chunks.join('') }
ストリームを文字列変換してparseすればcsvを2次元配列として取得することができます。
parseのオプションによってJSON配列にすることも可能です。
参考サイト
iconv-lite
Convert character encodings in pure javascript.. Latest version: 0.6.3, last published: 3 years ago. Start using iconv-l...
AWS SDK for JavaScript v3
API Reference
Attention Required! | Cloudflare
文字コードがShift-JISのCSVファイルを読み込む方法@React [サンプル付き]
React や node.js は文字コードが utf-8 で動いているため、 utf-8 以外の CSVファ…
KHI入社して退社。今はCONFRAGEで正社員です。関西で140-170/80~120万から受け付けております^^
得意技はJS(ES6),Java,AWSの大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^
コメント