pythonでExcelのデータをJSONに変換する

## 概要
pythonでexcelのデータをJSONに変換します。

変換するexcelデータは[日本食品標準成分表](https://www.mext.go.jp/a_menu/syokuhinseibun/1365297.htm)より、
以下の果実類のexcelファイルを使おうと思います。(クリックするとファイルがダウンロードされます。）
https://www.mext.go.jp/component/a_menu/science/detail/__icsFiles/afieldfile/2016/01/15/1365344_1-0207r.xlsx

`excel2json`と`openpyxl`の二つの方法でやってみます。
（`excel2json`の方はうまくいってないです。）

## 方法１　excel2jsonを使う
excel2jsonはpythonでexcelのデータをJSONに変換するモジュールなんですが、機能がとても限られています。excelを読み込んでjsonファイルを作成するくらいしかないです。

とりあえずインストールしてみます。末尾の`-3`を入れないと別のモジュールがインストールされるので注意。

```terminal
$ pip install excel2json-3
```

インストールできたら使ってみましょう。コードはこれだけ

```python:excel2json.py
from excel2json import convert_from_file

convert_from_file("変換したいexcelファイルのPATH")
```
実行するとexcelファイルと同じディレクトリにjsonファイルが生成されます。jsonファイルの名前はexcelのsheetの名前（固定っぽい）です。

ダウンロードしてきたexcelファイルをそのまま入れて実行したらうまくjsonファイルが作成できなかったので、表の上の余計な部分を消して再実行してみます。

修正後のexcelファイルはこんな感じ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/440765/e0d2dc11-d193-6e7f-42fc-9c941ce22d6a.png)

できたjsonファイルを開いて見ると...

```json
{
    "\u98df\u54c1\u7fa4": "07",
    "\u98df\u54c1\u756a\u53f7": "07001",
    "\u7d22\u5f15\u756a\u53f7": 751.0,
    ...
}
```
このようにunicodeになってしまっています。
試しにvscodeの「encode decode」というextensionsで修正してみるとこんな感じになりました。

```json
{
    "食品群": "07",
    "食品番号": "07001",
    "索引番号": 751.0,
    ...
}
```
コードの量が少なくて、すでに整っているデータならとても楽にできますが、取得するデータを指定できなかったりして少し不便です。
文字コードに関しても、上記以外の方法が見つかなかったので、とりあえず他の方法を試してみようとおもいます。

## 方法２　openpyxlを使う

openpyxlはpythonでexcelの操作をするためのモジュールです。まずはopenpyxlをインストールします

```
$ pip install openpyxl
```
インストールできたら使ってみます。

excellファイルはダウンロードしてきたものをそのまま使ってるので注意してください。
今回は食品番号、食品名、食物繊維、カリウム、鉄、ビタミンB1、ビタミンCの7項目を取得します。

<details><summary>コードはこちら</summary><div>

```python
import openpyxl
import json

load_book = openpyxl.load_workbook('excelファイルのPATH')
sheet = load_book['07 果実類']
json_path = 'jsonファイルのPATH'

fruits_list = [{
    "food_id": 0,
    "name": ""
}]
for i in range(9, 183):
    food_id = sheet.cell(row = i, column = 2).value
    name = sheet.cell(row = i, column = 4).value
    dietary_fiber = sheet.cell(row = i, column = 21).value
    potassium = sheet.cell(row = i, column = 24).value
    iron = sheet.cell(row = i, column = 28).value
    vitamin_b1 = sheet.cell(row = i, column = 48).value
    vitamin_c = sheet.cell(row = i, column = 56).value

    food_id = int(food_id)

    if dietary_fiber == 'Tr':
        dietary_fiber = 0
    if potassium == 'Tr':
        potassium = 0
    if iron == 'Tr':
        iron = 0
    if vitamin_b1 == 'Tr':
        vitamin_b1 = 0
    if vitamin_c == 'Tr':
        vitamin_c = 0

    if name.split("　")[0][0] == '(' or name.split("　")[0][0] == '（':
        name = name.split("　")[1]
    else:
        name = name.split("　")[0]
    
    if fruits_list[-1]['name'] != name:
        fruits_list.append({
            "food_id": food_id,
            "name": name,
            "dietary_fiber": dietary_fiber,
            "potassium": potassium,
            "iron": iron,
            "vitamin_b1": vitamin_b1,
            "vitamin_c": vitamin_c,
        })
    
fruits_list.pop(0)

data_dict = {
    "data": "fruits",
    "fruits": fruits_list
}

with open(json_path, mode = 'w', encoding = 'utf-8') as f:
    f.write(json.dumps(data_dict, ensure_ascii = False, indent = 4))
```
</div></details>


記事に関する部分を説明しておきます。

```python
import openpyxl
import json

load_book = openpyxl.load_workbook('excelファイルのPATH')
sheet = load_book['sheet名']
json_path = 'jsonファイルのPATH'
```
openpyxlと、jsonを操作したいのでjsonモジュールもimportしておきます。`openpyxl.load_workbook()`でexcelファイルを読み込んで、`load_book['sheet名']`でsheetを取得します。

```python
food_id = sheet.cell(row = 1, column = 2).value
```
excelのセルを行と列で指定してデータを取得します。このコードだと1行2列のデータを取得しています。

```python
fruits_list.append({
    "food_id": food_id,
    "name": name,
    "dietary_fiber": dietary_fiber,
    "potassium": potassium,
    "iron": iron,
    "vitamin_b1": vitamin_b1,
    "vitamin_c": vitamin_c,
})
```

取得したデータを辞書にまとめて、配列に追加します。

```python
data_dict = {
    "data": "fruits",
    "fruits": fruits_list
}

with open(json_path, mode = 'w', encoding = 'utf-8') as f:
    f.write(json.dumps(data_dict, ensure_ascii = False, indent = 4))
```

最後にさっきのデータを辞書にしてjsonファイルに書き込みます。
`open()`の`mode='a'`はファイルを書き込みモードで開くことを指定しています。ちなみに、`mode`が`r`だと読み込みモード、`a`だと追記モードになります。

## まとめ
- excel2json
  - 短いコードでまとめて変換できるので楽。
  - ただ汎用性はそんなに高くない。
  - 日本語のデータはできない？（方法あったらぜひ教えてください。）
- openpyxl
  - 取得したいデータを指定して取得できるので汎用性高い。
  - データが整ってなくてもpythonで何とかできる。
  - 取得したいデータが増えてくると少し大変かも？