🦋
JavaScriptで配列形式のJSONをCSVに変換してダウンロードする方法
こんにちは、AIQ株式会社のフロントエンドエンジニアのまさぴょんです!
今回は、JavaScriptで配列形式のJSONをCSVに変換してダウンロードする方法について、解説します。
配列形式のJSONをCSVに変換してダウンロードする方法 Part1
最初に作成した、配列形式のJSONをCSVに変換してダウンロードする方法は次のとおりです。
処理フロー・要点まとめ
- 
ObjectのKeyをheaderとして取り出して、結合する
- 各Objectのvalueを取り出して、結合する
- CSV文字列を返却する
- 
Blob Object(Type.CSV)を作成する
- 
Blob Object(Type.CSV)のURLを作成する
- 
aリンクを作成する
- 
hrefとdownload属性を追加して、クリックする
- 
aリンクを削除する
const groupList = [
  { id: 1, participant: "ロボたま", affiliation: "エンジニア" },
  { id: 2, participant: "まりたま", affiliation: "エンジニア" },
  { id: 3, participant: "白桃", affiliation: "営業部" },
  { id: 4, participant: "ももちゃん", affiliation: "営業部" },
  { id: 5, participant: "まさぴょん", affiliation: "営業部" },
  { id: 6, participant: "まりぴょん", affiliation: "デザイナー" },
  { id: 7, participant: "ハム太郎", affiliation: "エンジニア" },
  { id: 8, participant: "ロボ太郎", affiliation: "デザイナー" },
  { id: 9, participant: "まり太郎", affiliation: "デザイナー" },
  { id: 10, participant: "ぷる玉", affiliation: "人事部" },
  { id: 11, participant: "ぷるぷる玉", affiliation: "人事部" },
  { id: 12, participant: "ロボ玉試作1号機", affiliation: "エンジニア" },
  { id: 13, participant: "ロボ玉試作2号機", affiliation: "デザイナー" },
  { id: 14, participant: "ロボ玉試作1号機", affiliation: "ロボ玉開発部" },
];
/** Object の配列を受け取り CSV形式の文字列に変換する Func */
const convertToCSV = (objArray) => {
  const array = typeof objArray !== "object" ? JSON.parse(objArray) : objArray;
  /** 1. Objectの Key を headerとして取り出す */
  let str =
    `${Object.keys(array[0])
      .map((value) => `"${value}"`)
      .join(",")}` + "\r\n";
  // 2. 各オブジェクトの値をCSVの行として追加する
  return array.reduce((str, next) => {
    str +=
      `${Object.values(next)
        .map((value) => `"${value}"`)
        .join(",")}` + "\r\n";
    return str;
  }, str);
};
/** Download・処理 */
const downloadCSV = (data, name) => {
  /** Blob Object を作成する Type. CSV */
  const blob = new Blob([data], { type: "text/csv" });
  console.log("blob", blob);
  const url = window.URL.createObjectURL(blob);
  console.log("url", url);
  const a = document.createElement("a");
  a.setAttribute("href", url);
  a.setAttribute("download", `${name}.csv`);
  a.click();
  a.remove();
};
/** CSVデータを作成 */
const csvData = convertToCSV(groupList);
console.log(csvData);
// CSV・Download
downloadCSV(csvData, "robotama");
このScriptをconsoleで実行してもらうと、次のようなCSVファイルが作成されます。

配列形式のJSONをCSVに変換してダウンロードする方法 Part2
最初に作成した方法だと、Object.keys()によって、順序の保証がない場合があります。
そこで、まったく同じことをしようとしていた記事を見つけたので、こちらを参考・引用させてもらい、次のような配列形式のJSONをCSVに変換してダウンロードする方法も作成しました。
処理フロー・要点まとめ
- 
ObjectからMapの生成(Mapはkeyの順序が保証されている)
- 
Mapから配列を作成して、CSVのHeaderList(KeyList)を作成する
- 
header行を結合する
- 各Objectのvalueを結合して、コンテンツ部分を作成する
- 
headerとコンテンツ部分を結合して、CSVフォーマットの文字列を作成する
- 
Blob Object(Type.CSV)を作成する
- 
Blob Object(Type.CSV)のURLを作成する
- 
aリンクを作成する
- 
hrefとdownload属性を追加して、クリックする
- 
aリンクを削除する
const groupList = [
  { id: 1, participant: "ロボたま", affiliation: "エンジニア" },
  { id: 2, participant: "まりたま", affiliation: "エンジニア" },
  { id: 3, participant: "白桃", affiliation: "営業部" },
  { id: 4, participant: "ももちゃん", affiliation: "営業部" },
  { id: 5, participant: "まさぴょん", affiliation: "営業部" },
  { id: 6, participant: "まりぴょん", affiliation: "デザイナー" },
  { id: 7, participant: "ハム太郎", affiliation: "エンジニア" },
  { id: 8, participant: "ロボ太郎", affiliation: "デザイナー" },
  { id: 9, participant: "まり太郎", affiliation: "デザイナー" },
  { id: 10, participant: "ぷる玉", affiliation: "人事部" },
  { id: 11, participant: "ぷるぷる玉", affiliation: "人事部" },
  { id: 12, participant: "ロボ玉試作1号機", affiliation: "エンジニア" },
  { id: 13, participant: "ロボ玉試作2号機", affiliation: "デザイナー" },
  { id: 14, participant: "ロボ玉試作1号機", affiliation: "ロボ玉開発部" },
];
/** Objectのリストから、CSVを作成する */
const convertToCSV = (data, headerOrder) => {
  /** headerOrderを入れているのは、JavaScriptの場合Object.keys()だと順番が必ずしも守られないからです。 */
  const headerString = headerOrder.join(",");
  const replacer = (_, value) => value ?? "";
  const rowItems = data.map((row) =>
    headerOrder
      .map((fieldName) => JSON.stringify(row[fieldName], replacer))
      .join(",")
  );
  /** headerとコンテンツ部分を結合して、CSVフォーマットの文字列を作成する */
  const csv = [headerString, ...rowItems].join("\r\n");
  return csv;
};
/** Download・処理 */
const downloadCSV = (data, name) => {
  /** Blob Object を作成する Type. CSV */
  const blob = new Blob([data], { type: "text/csv" });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.setAttribute("href", url);
  a.setAttribute("download", `${name}.csv`);
  a.click();
  a.remove();
};
/** 1つの行・データ */
const csvRow = groupList[0];
/** Object から、Map の生成 => Map は、key の順序が保証されている */
const csvRowMap = new Map(Object.entries(csvRow));
// Mapから配列を作成して、CSV の HeaderList(KeyList)を作成する
const csvHeader = Array.from(csvRowMap).map((keyValList) => keyValList[0]);
console.log("csvHeader", csvHeader);
// CSVデータを作成する
const csvData = convertToCSV(groupList, csvHeader);
console.log(csvData);
// CSV・Download
downloadCSV(csvData, "robotama2");
このScriptをconsoleで実行してもらうと、次のようなCSVファイルが作成されます。

【おまけ】 配列形式のJSONと配列型のリストとの相互変換
配列形式のJSONから配列型のリストに変換する
const groupList = [
  { id: 1, participant: "ロボたま", affiliation: "エンジニア" },
  { id: 2, participant: "まりたま", affiliation: "エンジニア" },
  { id: 3, participant: "白桃", affiliation: "営業部" },
  { id: 4, participant: "ももちゃん", affiliation: "営業部" },
  { id: 5, participant: "まさぴょん", affiliation: "営業部" },
  { id: 6, participant: "まりぴょん", affiliation: "デザイナー" },
  { id: 7, participant: "ハム太郎", affiliation: "エンジニア" },
  { id: 8, participant: "ロボ太郎", affiliation: "デザイナー" },
  { id: 9, participant: "まり太郎", affiliation: "デザイナー" },
  { id: 10, participant: "ぷる玉", affiliation: "人事部" },
  { id: 11, participant: "ぷるぷる玉", affiliation: "人事部" },
  { id: 12, participant: "ロボ玉試作1号機", affiliation: "エンジニア" },
  { id: 13, participant: "ロボ玉試作2号機", affiliation: "デザイナー" },
  { id: 14, participant: "ロボ玉試作1号機", affiliation: "ロボ玉開発部" },
];
/** 1つの行・データ */
const csvRow = groupList[0];
/** Object から、Map の生成 => Map は、key の順序が保証されている */
const csvRowMap = new Map(Object.entries(csvRow));
const csvHeader = [];
// Mapから配列を作成して、CSV の HeaderList(KeyList)を作成する
Array.from(csvRowMap).forEach((keyValList) => {
  csvHeader.push(keyValList[0]);
});
const listCSV = [csvHeader];
groupList.forEach((row) => {
  listCSV.push([row.id, row.participant, row.affiliation]);
});
console.log(listCSV);
/** 実行結果 */
// [
//   ["id", "participant", "affiliation"],
//   [1, "ロボたま", "エンジニア"],
//   [2, "まりたま", "エンジニア"],
//   [3, "白桃", "営業部"],
//   [4, "ももちゃん", "営業部"],
//   [5, "まさぴょん", "営業部"],
//   [6, "まりぴょん", "デザイナー"],
//   [7, "ハム太郎", "エンジニア"],
//   [8, "ロボ太郎", "デザイナー"],
//   [9, "まり太郎", "デザイナー"],
//   [10, "ぷる玉", "人事部"],
//   [11, "ぷるぷる玉", "人事部"],
//   [12, "ロボ玉試作1号機", "エンジニア"],
//   [13, "ロボ玉試作2号機", "デザイナー"],
//   [14, "ロボ玉試作1号機", "ロボ玉開発部"],
// ];
配列型のリストから配列形式のJSONに変換する
const listCSV = [
  ["id", "participant", "affiliation"],
  [1, "ロボたま", "エンジニア"],
  [2, "まりたま", "エンジニア"],
  [3, "白桃", "営業部"],
  [4, "ももちゃん", "営業部"],
  [5, "まさぴょん", "営業部"],
  [6, "まりぴょん", "デザイナー"],
  [7, "ハム太郎", "エンジニア"],
  [8, "ロボ太郎", "デザイナー"],
  [9, "まり太郎", "デザイナー"],
  [10, "ぷる玉", "人事部"],
  [11, "ぷるぷる玉", "人事部"],
  [12, "ロボ玉試作1号機", "エンジニア"],
  [13, "ロボ玉試作2号機", "デザイナー"],
  [14, "ロボ玉試作1号機", "ロボ玉開発部"],
];
const headers = listCSV[0];
const newList = listCSV.slice(1).map((row) => {
  let obj = {};
  row.forEach((value, index) => {
    obj[headers[index]] = value;
  });
  return obj;
});
console.log(newList);
/** 実行結果 */
// [
//   { id: 1, participant: "ロボたま", affiliation: "エンジニア" },
//   { id: 2, participant: "まりたま", affiliation: "エンジニア" },
//   { id: 3, participant: "白桃", affiliation: "営業部" },
//   { id: 4, participant: "ももちゃん", affiliation: "営業部" },
//   { id: 5, participant: "まさぴょん", affiliation: "営業部" },
//   { id: 6, participant: "まりぴょん", affiliation: "デザイナー" },
//   { id: 7, participant: "ハム太郎", affiliation: "エンジニア" },
//   { id: 8, participant: "ロボ太郎", affiliation: "デザイナー" },
//   { id: 9, participant: "まり太郎", affiliation: "デザイナー" },
//   { id: 10, participant: "ぷる玉", affiliation: "人事部" },
//   { id: 11, participant: "ぷるぷる玉", affiliation: "人事部" },
//   { id: 12, participant: "ロボ玉試作1号機", affiliation: "エンジニア" },
//   { id: 13, participant: "ロボ玉試作2号機", affiliation: "デザイナー" },
//   { id: 14, participant: "ロボ玉試作1号機", affiliation: "ロボ玉開発部" },
// ];
まとめ
配列形式のJSONをCSVに変換してダウンロードする処理は、それなりに使用する処理になると思うので、誰かのお役に立てれば、幸いです。
個人で、Blogもやっています、よかったら見てみてください。
注意事項
この記事は、AIQ 株式会社の社員による個人の見解であり、所属する組織の公式見解ではありません。
求む、冒険者!
AIQ株式会社では、一緒に働いてくれるエンジニアを絶賛、募集しております🐱🐹✨

詳しくは、Wantedly (https://www.wantedly.com/companies/aiqlab)を見てみてください。
参考・引用

AIQ 株式会社 に所属するエンジニアが技術情報をお届けします。 ※ AIQ 株式会社 社員による個人の見解であり、所属する組織の公式見解ではありません。 Wantedly: wantedly.com/companies/aiqlab




Discussion