Я пытаюсь заполнить файл Excel данными из файла JSON.
Файл JSON имеет следующий формат:
"checklist": {
"0": {
"Verdict": "",
"Issue description": "",
"Due date": "",
"Resolution": ""
},
"1": ....
}
И в нем есть много словарей, соответствующих этому формату.
Файл Excel имеет заголовок в первой строке и ключи этого словаря в столбцах второй строки.
Мне нужно заполнить строки файла Excel данными, содержащимися в файле JSON, используя словари, которые содержат значение вердикта, равное «FAIL», «NC» или «ISSUE».
Мой код на Python выглядит так:
wb = load_workbook("template.xlsx")
ws = wb['Sheet1']
verdict = ['FAIL', 'NC', 'ISSUE']
for row in ws.iter_rows(min_row=3):
for key in input_data['checklist']:
if input_data['checklist'][key]['Verdict'] in verdict:
row[1].value = input_data['checklist'][key]['Issue description']
row[2].value = input_data['checklist'][key]['Due date']
row[3].value = input_data['checklist'][key]['Resolution']
wb.save('file.xlsx')
У меня проблема в том, что файл Excel заполнен одними и теми же значениями во множестве строк, а не только одной строкой для каждого подходящего словаря.
1 ответ
Похоже, у вас возникла проблема из-за того, что вы используете вложенный цикл: для каждой строки вы снова просматриваете контрольный список, поэтому вы видите одинаковые значения в каждой строке. С такими задачами вы можете использовать zip для параллельного перебора нескольких элементов, предполагая, что они имеют одинаковую длину, или с помощью ziplongest, если вы знаете, что один список длиннее. Это особенно важно для iter_rows () в openpyxl, потому что, если рабочий лист новый, он скоро будет исчерпан. В таких случаях проще использовать ws.append ().
Во вложенных структурах данных также часто бывает полезно использовать временные переменные для длительного поиска, подверженного ошибкам.
Итак, превратите свой словарь контрольного списка во что-то вроде списка:
checklist = input_data['checklist']) # remove one level
for key, values in sorted(checklist.items()):
if values['Verdict'] in verdict:
row = values['Issue description'], values['Due date'], values['Resolution']
ws.append(row)
На новом листе вы можете перейти к третьей строке, добавив сначала две пустые строки:
ws.append([])
ws.append([])
(Точно так же вы можете дополнить строки, которые вы добавляете, с помощью None
, если вы хотите вставить, скажем, из столбца C padding = [None] * 2, а не A.)
В противном случае, если вы работаете с существующим листом, вам нужно будет установить строки вручную.
for (idx, item), row in zip(sorted(checklist.items()), ws.iter_rows(min_row=3, max_col=3, max_row=len(checklist)+3)):
for cell, key in zip(row, ['Issue description', 'Due date', 'Resolution']):
cell.value = item[key]
Однако, поскольку у вас есть условный шаг, это может привести к появлению пустых строк, где условие не выполняется. В этом случае вы можете создать свой собственный счетчик - что не рекомендуется, поскольку ошибки «выключено на 1» являются одними из самых распространенных в мире, особенно в openpyxl, где мы используем индексирование на основе 1. Лучшая альтернатива здесь - отфильтровать результаты до того, как вы начнете добавлять строки
filtered = [(key, value) for key, value in sorted(checklist.items()) if value['Verdict' in verdict]
NB, код здесь является иллюстративным только для того, чтобы показать, как решить вашу проблему, максимально используя Python и API openpyxl. У меня нет доступа к вашим данным, я не проверял опечатки и т. Д.
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.