Node.jsを使って何かしらのcsvファイルをUTF-8に変換、さらにそのCSVファイルの指定した列を削除して、新しいファイルとして書き出す方法をご紹介します。
必要なモジュールのインストール
npm i csv --save
npm i iconv-lite --save
npm i encoding-japanese --save
csvは文字列をCSVファイルに変換するために、iconv-liteはファイルの文字コードを変換するために、encoding-japaneseはファイルの文字コードを判別するために使います。
今回行う処理
今回は入力されたSHIFT-JISのファイルをUTF-8に変換。さらには不必要な列を削除すると共に、1行目の項目名の変更などを行います。
具体例を出すと、下記のような形です。項目名を日本語➡️英語に編集。さらには不要なパスワード、住所・郵便番号の項目は削除、そして複数あるメールアドレスに関しては(メール2が配列になっているデータもあります)、それぞれ一行ずつにして表します。
想定としては、顧客リストなどの個人情報の入ったデータを、登録に必要な情報のみに変換して、何かしらの用途に用いるなどが考えられます。
ID,名前,メール1,パスワード,メール2,郵便番号,住所
1,Bob,test@bob.com,xxxxxx,test2@bob.com,xxx-xxxx,xxxxxxxx
2,Alice,test@alice.com,xxxxxx,test2@alice.com,xxx-xxxx,xxxxxxxx
3,Naomi,test@naomi.com,xxxxxx,test2@naomi.com,xxx-xxxx,xxxxxxxx
4,Key,test@key.com,xxxxxx,"test2@key.com,test3@key.com",xxx-xxxx,xxxxxxxx
5,Annna,test@annna.com,xxxxxx,"test2@annna.com,test3@annna.com,test4@annna.com",xxx-xxxx,xxxxxxxx
↓
id,name,email
1,Bob,test@bob.com
1,Bob,test2@bob.com
2,Alice,test@alice.com
2,Alice,test2@alice.com
3,Naomi,test@naomi.com
3,Naomi,test2@naomi.com
4,Key,test@key.com
4,Key,test2@key.com
4,Key,test3@key.com
5,Annna,test@annna.com
5,Annna,test2@annna.com
5,Annna,test3@annna.com
5,Annna,test4@annna.com
実際の処理
では実際の処理を紹介します。
const fs = require('fs');
const csv = require('csv');
const iconv = require('iconv-lite');
const encoding = require('encoding-japanese');
const parser = csv.parse((error, data) => {
let newData = [];
//ループしながら1行ずつ処理
data.forEach((element, index, array) => {
if(index == 0){
let row = [];
row.push('id');
row.push('name');
row.push('email');
newData.push(row);
return newData;
}else{
let row = [];
createNewRow(element,row,element[2],newData);
if(element[4].indexOf('@') != -1){
if(element[4].indexOf(',') != -1){
var arr = element[4].split(',');
for(i=0; i < arr.length; i++){
let row = [];
createNewRow(element,row,arr[i],newData);
}
}else{
let row = [];
createNewRow(element,row,element[4],newData);
}
}
}
})
//write
csv.stringify(newData,(error,output)=>{
fs.writeFile('編集・変換後のファイル名.csv',output,(error)=>{
console.log('処理データをCSV出力しました。');
})
})
})
var buf = fs.readFileSync('ファイル名.csv');
if(encoding.detect(buf) == 'SJIS'){
fs.readFile('ファイル名.csv', function(err, data){
if (err) throw err;
var buf = new Buffer.from(data, 'binary'); //バイナリバッファを一時的に作成する
var retStr = iconv.decode(buf, "Shift_JIS"); //作成したバッファを使い、iconv-liteでShift-jisからutf8に変換
fs.writeFile('変換後のファイル名.csv',retStr,(error)=>{
console.log('処理データをCSV出力しました。');
});
fs.createReadStream('変換後のファイル名.csv').pipe(parser);
});
}else if(encoding.detect(buf) == 'ASCII'){
fs.createReadStream('ファイル名.csv').pipe(parser);
}else{
console.log('この形式のファイルでは文字コードを変換できません。SHIFT-JISかUTF8のみ対応しています');
}
function createNewRow(element,row, email, newData){
row.push(element[0]);
row.push(element[1]);
row.push(email);
newData.push(row);
return newData;
}
細かく分けて説明していきます。もともとShift-jisだったcsvファイルの文字コードをUTF8に変更します。
var buf = fs.readFileSync('ファイル名.csv');
if(encoding.detect(buf) == 'SJIS'){
fs.readFile('ファイル名.csv', function(err, data){
if (err) throw err;
var buf = new Buffer.from(data, 'binary');
var retStr = iconv.decode(buf, "Shift_JIS"); //作成したバッファを使い、iconv-liteでShift-jisからutf8に変換
fs.writeFile('変換後のファイル名.csv',retStr,(error)=>{
console.log('処理データをCSV出力しました。');
});
fs.createReadStream('変換後のファイル名.csv').pipe(parser);
});
}else if(encoding.detect(buf) == 'ASCII'){
fs.createReadStream('ファイル名.csv').pipe(parser);
}else{
console.log('この形式のファイルでは文字コードを変換できません。SHIFT-JISかUTF8のみ対応しています');
}
次は実際に編集をする処理です。
const parser = csv.parse((error, data) => {
let newData = [];
data.forEach((element, index, array) => {
if(index == 0){
let row = [];
row.push('id');
row.push('name');
row.push('email');
newData.push(row);
return newData;
}else{
let row = [];
createNewRow(element,row,element[2],newData);
if(element[4].indexOf('@') != -1){
if(element[4].indexOf(',') != -1){
var arr = element[4].split(',');
for(i=0; i < arr.length; i++){
let row = [];
createNewRow(element,row,arr[i],newData);
}
}else{
let row = [];
createNewRow(element,row,element[4],newData);
}
}
}
})
csv.stringify(newData,(error,output)=>{
fs.writeFile('編集・変換後のファイル名.csv',output,(error)=>{
console.log('出力成功');
})
})
})
function createNewRow(element,row, email, newData){
row.push(element[0]);
row.push(element[1]);
row.push(email);
newData.push(row);
return newData;
}
csvモジュールの機能を使って、csvファイルをparseします。元のcsvファイルを一行ずつ処理していきます。一行目は大きく描き変えるために、新しい要素を直接書き込みます。二行目以降に関しては、必要な要素のみを抽出して処理します。
そしてメール2の項目の要素を持っている行に関しては、それをEmailに当てはめます。メール2項目を複数持っている物に関しては、そのようがカンマを持っていることで判別して、カンマで分割することで、配列要素にしそれを1つずつ行に入れていきます。
そして、それらのデータが入ったnewDataをfs.writeFileでcsvファイルとして書き出します。
以上になります。
参考記事