概要
pythonでexcelのデータをJSONに変換します。
変換するexcelデータは日本食品標準成分表より、
以下の果実類のexcelファイルを使おうと思います。(クリックするとファイルがダウンロードされます。)
https://www.mext.go.jp/component/a_menu/science/detail/__icsFiles/afieldfile/2016/01/15/1365344_1-0207r.xlsx
excel2json
とopenpyxl
の二つの方法でやってみます。
(excel2json
の方はうまくいってないです。)
方法1 excel2jsonを使う
excel2jsonはpythonでexcelのデータをJSONに変換するモジュールなんですが、機能がとても限られています。excelを読み込んでjsonファイルを作成するくらいしかないです。
とりあえずインストールしてみます。末尾の-3
を入れないと別のモジュールがインストールされるので注意。
$ pip install excel2json-3
インストールできたら使ってみましょう。コードはこれだけ
from excel2json import convert_from_file
convert_from_file("変換したいexcelファイルのPATH")
実行するとexcelファイルと同じディレクトリにjsonファイルが生成されます。jsonファイルの名前はexcelのsheetの名前(固定っぽい)です。
ダウンロードしてきたexcelファイルをそのまま入れて実行したらうまくjsonファイルが作成できなかったので、表の上の余計な部分を消して再実行してみます。
できたjsonファイルを開いて見ると...
{
"\u98df\u54c1\u7fa4": "07",
"\u98df\u54c1\u756a\u53f7": "07001",
"\u7d22\u5f15\u756a\u53f7": 751.0,
...
}
このようにunicodeになってしまっています。
試しにvscodeの「encode decode」というextensionsで修正してみるとこんな感じになりました。
{
"食品群": "07",
"食品番号": "07001",
"索引番号": 751.0,
...
}
コードの量が少なくて、すでに整っているデータならとても楽にできますが、取得するデータを指定できなかったりして少し不便です。
文字コードに関しても、上記以外の方法が見つかなかったので、とりあえず他の方法を試してみようとおもいます。
方法2 openpyxlを使う
openpyxlはpythonでexcelの操作をするためのモジュールです。まずはopenpyxlをインストールします
$ pip install openpyxl
インストールできたら使ってみます。
excellファイルはダウンロードしてきたものをそのまま使ってるので注意してください。
今回は食品番号、食品名、食物繊維、カリウム、鉄、ビタミンB1、ビタミンCの7項目を取得します。
コードはこちら
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))
記事に関する部分を説明しておきます。
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を取得します。
food_id = sheet.cell(row = 1, column = 2).value
excelのセルを行と列で指定してデータを取得します。このコードだと1行2列のデータを取得しています。
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,
})
取得したデータを辞書にまとめて、配列に追加します。
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で何とかできる。
- 取得したいデータが増えてくると少し大変かも?