Как перебирать отдельные листы, чтобы изменить их свойства с помощью Openpyxl

#python #openpyxl

Вопрос:

Я пытаюсь перебрать несколько листов в своем коде, чтобы я мог отформатировать все листы в соответствии с моими потребностями за один раз. Мне это нужно для планировщика, который я создаю. Однако моя попытка не сработала. Он правильно форматирует только «январский» лист. «Лист» по умолчанию и другие месяцы не отформатированы. Не могли бы вы, пожалуйста, помочь мне решить эту проблему?

 import numpy as np from openpyxl import Workbook from openpyxl.styles import Alignment, Font  wb = Workbook() jan = wb.create_sheet("January") feb = wb.create_sheet("February") mar = wb.create_sheet("March") apr = wb.create_sheet("April") may = wb.create_sheet("May") jun = wb.create_sheet("June") jul = wb.create_sheet("July") aug = wb.create_sheet("August") sep = wb.create_sheet("September") octo = wb.create_sheet("October") nov = wb.create_sheet("November") dec = wb.create_sheet("December")  months = np.array([jan, feb, mar, apr, may, jun, jul, aug, sep, octo, nov, dec])  num = 1 for m in range(12):  for row in range(1, 33):  months[m].row_dimensions[num].height = 30  num = num   1  for col in range(1, 4):  months[m].cell(row, col).alignment = Alignment(horizontal="center", vertical="center", wrap_text="center")  months[m].cell(row, col).font = Font(size="15")  wb.save("sample.xlsx")  

Кроме того, я новичок в Python и Openpyxl, так что это может быть не самый эффективный способ или может быть какое-то глупое кодирование, которое я сделал, если есть, пожалуйста, дайте мне знать.

Комментарии:

1. вы можете создать список с именами, а затем использовать for цикл для months создания . Вы также можете научиться использовать for -цикл без range() — ie. for m in months: и позже использовать m вместо months[m]

Ответ №1:

Ваша проблема в том, что вы инициализируете num перед циклом for, а затем увеличиваете его в цикле, никогда не сбрасывая его. Если вы прокрутите вниз листы за февраль, март и т. Д., Вы обнаружите, что форматирование действительно существует, оно всего на 33*m строк дальше, чем вы предполагали. Вы можете решить эту проблему, введя num=1 свой цикл for.

 for m in range(12):  num = 1  for row in range(1, 33):  months[m].row_dimensions[num].height = 30  num = num   1  for col in range(1, 4):  months[m].cell(row, col).alignment = Alignment(horizontal="center", vertical="center", wrap_text="center")  months[m].cell(row, col).font = Font(size="15")  

Однако вы пытаетесь увеличить num , когда у вас уже есть увеличивающаяся переменная — row . Обе переменные имеют одинаковое значение, поэтому num оно не требуется, и вы можете заменить его на row .

 for m in range(12):  for row in range(1, 33):  months[m].row_dimensions[row].height = 30  for col in range(1, 4):  months[m].cell(row, col).alignment = Alignment(horizontal="center", vertical="center", wrap_text="center")  months[m].cell(row, col).font = Font(size="15")  

Вы также можете отформатировать свои листы так, чтобы в этом месяце было только столько строк, сколько дней (плюс строка заголовка). Полный рабочий пример, показывающий это:

 from openpyxl import Workbook from openpyxl.styles import Alignment, Font from calendar import monthrange  # Create workbook wb = Workbook()  # List of the months months = [  "January",  "February",  "March",  "April",  "May",  "June",  "July",  "August",  "September",  "October",  "November",  "December",  ]  # Create a sheet for each month month_sheets = [wb.create_sheet(month) for month in months]  # Formatting sheets for i, sheet in enumerate(month_sheets):  days_in_month = monthrange(2021, i 1)[1] # The year input only matters for February (leap years)  for row in range(1, days_in_month 2): #  2 to allow for heading row as well  sheet.row_dimensions[row].height = 30  for col in range(1, 4):  sheet.cell(row, col).alignment = Alignment(horizontal="center", vertical="center", wrap_text="center")  sheet.cell(row, col).font = Font(size="15")  wb.save("sample.xlsx")  

Комментарии:

1. Спасибо! Теперь это работает!!! Также спасибо за ваш совет

Ответ №2:

Проблема в том, что вы задаете num = 1 перед всеми месяцами — поэтому в January нем форматируются строки 1-33, в February нем форматируются строки 34-66 и т. Д.

Вы должны использовать num = 1 inside for m in range(12): для сброса значения перед каждым месяцем.