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: 4 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の大体のリソースです
コメントはやさしくお願いいたします^^
座右の銘は、「狭き門より入れ」「願わくは、我に七難八苦を与えたまえ」です^^



コメント