Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8691

【Node.js】JSON文字列をCSVファイルとして吐き出す

$
0
0

要件

・DBに格納されているデータをCSVでダウンロードできるようにする
・データはユーザーが回答したアンケートの結果

使用したモジュール

・json2csv
https://www.npmjs.com/package/json2csv

開発

1. データの成形

今回は、ユーザーが回答したアンケート結果をCSVとして出力したいと思いますので、表示する項目をユーザー名メールアドレスアンケート設問回答結果とします。

データを成形する
// DBから出力したいデータを取得するconstdata=awaitgetData.getUserData(user_id);// データをJSON型に整える constgroupData=data.reduce((result,current)=>{// user_idごとにデータをまとめるconstelement=result.find((p)=>{returnp.id===current.user_id;});// user_idが既にあればquestionとanswerのみを追加するif(element){element.data.push({question:current.question,answer:current.answer});}else{// user_idが切り替わった時に新規の要素としてgroupDataに追加するresult.push({id:current.user_id,name:current.user_name,email:current.user_email,data:[{question:current.question,answer:current.answer,}],});}returnresult;},[]);

DBから取得したデータをJSONに成形しました。reduce関数を使っているのは1クエリで適切な形でデータを取得できなかったためなので、必須ではありません。for文やmap関数を使ってきれいにしてください。
reduce関数でのデータをグループ化は以下を参考にさせて頂きました。


参考サイト
JavaScript オブジェクト配列をsqlのgroup byのように集計する


成形したデータは以下のようになりました。dataの個数は同じでなくても大丈夫です。

groupDataの中身
[{id:267,name:"taro",email:"taro@example.com",data:[{question:"好きなプログラミング言語は?",answer:["HTML","CSS","JavaScript"]},{question:"得意なプログラミング言語は?",answer:["HTML","CSS"]},{question:"苦手なプログラミング言語は?",answer:["JavaScript"]}]},{id:269,name:"jiro",email:"jiro@example.com",data:[{question:"好きなプログラミング言語は?",answer:["Go","JavaScript"]},{question:"得意なプログラミング言語は?",answer:["PHP","Ruby"]},{question:"苦手なプログラミング言語は?",answer:["Java"]}]},]

2. JSONをCSVに変換

続いてJSONに成形したデータをCSVに変換していきます。今回はjson2csvというモジュールを使用しました。他にもCSV系のモジュールはたくさんありましたので、自分にとって使いやすいものや仕様に沿っているものを選択すると良いかと思います。

get_csv.js
const{Parser,transforms:{unwind}}=require('json2csv');functiongetCsv(data,fields,pathes,res){consttransforms=[unwind({paths:pathes,blankOut:true,})];constjson2csvParser=newParser({fields,transforms});constcsv=data.length?json2csvParser.parse(data):'';res.setHeader('Content-disposition','attachment; filename=data.csv');res.setHeader('Content-Type','text/csv; charset=UTF-8');returnres.send(csv);}module.exports=getCsv;

引数のdataは先程成形したデータが渡ってきます。fieldsにはdataの中の表示させたい項目を配列で渡します。今回の例ですと、以下のようになります。

fieldsの中身
constfields=['name','email','data.question','data.answer'];

questionとanswerはdataの入れ子になっているのでドット繋ぎにします。

最後のpathesはdataの中でネストされている項目を配列で渡します。今回の例では以下のようになります。

pathesの中身
constpathes=['data']

ここで、pathesの中にdata.answerを入れると、answerに格納されている配列が展開されて表示されるようになります。今回は、一つの設問に対して複数の回答を1行で表示させたかったのでdataのみにしました。
他にも色々オプションがありますので、詳しくは公式ドキュメントを参照してください。

3. CSVの出力

後は、CSVに変換したデータをPOSTなどのルーティングでres.sendしてあげることで、ブラウザからファイルをダウンロードすることができます。

CSV出力
constcsv=getCsv(groupData,fields,pathes,res);res.send(csv);

出力結果

以上です。


Viewing all articles
Browse latest Browse all 8691

Trending Articles