PythonでJSONを読み込んでCSV出力する

## 目的
JSONファイルを読み込んで中身を集計してCSV出力するためのプログラムです。
集計内容は用途によって変わるので、JSONを読み込んで出す、というところだけを作っています。

## 行うこと
- ファイル選択ダイアログを表示する
- JSONファイルを読み込む
- 集計してCSV出力する

### ファイル選択ダイアログを表示する
GUI（ファイル選択ダイアログ）を表示するために`tkinter`を使用します。
実行したらすぐにファイル選択ダイアログが表示され、JSONファイルのみを選択できるようにします。

```python
# モジュールのインポート
import os, tkinter, tkinter.filedialog

# ファイル選択ダイアログの表示
root = tkinter.Tk()
root.withdraw()

# jsonファイルのみを選択可能にする
fTyp = [("","*.json")]
iDir = os.path.abspath(os.path.dirname(__file__))
file = tkinter.filedialog.askopenfilename(filetypes = fTyp, initialdir = iDir)

# 選択したファイルのパスを確認
print(file)
```

### JSONファイルを読み込む
ファイル選択ができるようになったらJSONファイルの中身を確認します。
`json`ライブラリを追加してファイルを読込み扱えるようにします。

```python
# モジュールのインポート
import os, json, tkinter, tkinter.filedialog

# ファイル選択ダイアログの表示
root = tkinter.Tk()
root.withdraw()

# jsonファイルのみを選択可能にする
fTyp = [("","*.json")]
iDir = os.path.abspath(os.path.dirname(__file__))
file = tkinter.filedialog.askopenfilename(filetypes = fTyp, initialdir = iDir)

# jsonファイルを読み込む
json_open = open(file, 'r', encoding="utf-8")
json_load = json.load(json_open)

# jsonファイルの中身を確認
print(json_load[0])
```

### CSV出力する（完成）
JSONファイルを読み込めたのでCSVに出力できるようにしましょう。


```python
# モジュールのインポート
import os, json, csv, tkinter, tkinter.filedialog

# ファイル選択ダイアログの表示
root = tkinter.Tk()
root.withdraw()

# jsonファイルのみを選択可能にする
fTyp = [("","*.json")]
iDir = os.path.abspath(os.path.dirname(__file__))

# ファイル情報を取得
file = tkinter.filedialog.askopenfilename(filetypes = fTyp, initialdir = iDir)

# jsonファイルを読み込む
json_open = open(file, 'r', encoding='utf-8')
json_load = json.load(json_open)

# CSVヘッダーの設定
csv_header = ['H1', 'H2', 'H3']
csv_pack = []
csv_pack.append(csv_header)

# ※JSON例
# json_load = {'c1':'Test1','c2':'tEst2','c3':'teSt3'}

# 出力内容を集計
for item in json_load:
  # 1行分の情報を初期化
  csv_line = [''] * 5

  # JSONの情報を取得
  csv_line[0] = item['c1']
  csv_line[1] = item['c2']
  csv_line[2] = item['c3']

  # 1行分を格納
  csv_pack.append(copy.copy(csv_line))

# CSVを出力するフォルダとファイル名を設定（読み込んだJSONファイルと同じ場所に同じ名前）
folder_file = os.path.split(file)
folder = folder_file[0] # フォルダパスを取得
file_name = file.rsplit('/', 1)[1][0:-5] # ファイル名を取得
csv_file_path = folder + '/' + file_name + '.csv'

# CSVファイルを作成（既に存在すれば上書き）
if not os.path.isfile(csv_file_path):
  open(csv_file_path, 'x', encoding='utf-8')
csv_file = open(csv_file_path, 'w', encoding='utf-8')

# CSVに書込み
w = csv.writer(csv_file, lineterminator='\n')
w.writerows(csv_pack)
csv_file.close()
```

以上。
あとはお好みで集計しましょう。

## おまけ
### フォルダ内の全てのJSONファイルを取得して集計する場合

```python
# モジュールのインポート
import os, json, copy, csv, datetime, glob, tkinter, tkinter.filedialog, tkinter.messagebox

# フォルダ選択ダイアログの表示
root = tkinter.Tk()
root.withdraw()

# フォルダ内のJSONファイルを取得する
iDir = os.path.abspath(os.path.dirname(__file__))
iDirPath = tkinter.filedialog.askdirectory(initialdir = iDir)
files = glob.glob(iDirPath + "/" + "*.json")

# CSVヘッダーの設定
csv_header = ['H1', 'H2', 'H3', 'H4', 'H5']
csv_pack = []
csv_pack.append(csv_header)

# JSONファイルを１つずつ取得して処理をする
folder = ''
for file in files:
  # ファイルパスからフォルダとファイル名を切り離す
  folder_file = os.path.split(file)

  # フォルダパスのみを取得
  folder = folder_file[0]

  # JSONファイルを読み込む
  json_open = open(file, 'r', encoding='utf-8')
  json_load = json.load(json_open)

  # ※JSON例
  # json_load = {'c1':'Test1','c2':'tEst2','c3':'teSt3','c4':'tesT3','c5':'test1'}

  # 出力内容を集計
  for item in json_load:
    # 1行分の情報を初期化
    csv_line = [''] * 5

    # JSONの情報を取得
    csv_line[0] = item['c1']
    csv_line[1] = item['c2']
    csv_line[2] = item['c3']
    csv_line[3] = item['c4']
    csv_line[4] = item['c5']

    # 1行分を格納
    csv_pack.append(copy.copy(csv_line))

# リンクCSVファイルを作成
if not '' == folder:
  # CSVを作成（既にファイルがあれば上書き）
  csv_file_path = folder + '/sum.csv'
  if not os.path.isfile(csv_file_path):
    open(csv_file_path, 'x', encoding='cp932')
  csv_file = open(csv_file_path, 'w', encoding='cp932')

  # CSVに書込み
  w = csv.writer(csv_file, lineterminator='\n')
  w.writerows(csv_pack)
  csv_file.close()

  # メッセージ
  tkinter.messagebox.showinfo('処理完了', '選択したフォルダ内のJSONをCSVに変換して出力しました。')
else:
  tkinter.messagebox.showinfo('エラー', 'フォルダが選択されていないかファイルが見つかりません。')
```

## 参考
- [Python：処理ファイルをGUIから選択する方法](https://qiita.com/chanmaru/items/1b64aa91dcd45ad91540)
- [PythonでJSON 読み込み](https://qiita.com/kikuchiTakuya/items/53990fca06fb9ba1d8a7)
- [Python:webAPIからJSONデータの読み込み](https://qiita.com/tamago324/items/3b189a87342ae6120b1c)
- [Pythonでcsvファイルに出力](https://qiita.com/a_t_a/items/50623aedf7e1dab3b876)
- [【Python】Pythonでcsvファイルに書き込み](https://qiita.com/koichi_baseball/items/3158e0c977c1c7bdd2c5)
- [PythonでJsonファイルを読み込むときに「cp932」ファイルが開けなかった話](https://senablog.com/python-cp932/)
- [[Python] ファイルの読み込み、書き込み（上書き、追記）について](https://hibiki-press.tech/python/fileobject_open_read_write/1019)
- [Pythonのcsvモジュールで出力されるファイルの改行コードをLFにする](https://tsutsuko.hatenablog.com/entry/2019/02/13/183613)