У меня есть два файла: input.csv, содержащий данные, и template.xlsx, содержащий стили. Я пытаюсь создать файл output.xlsx, используя эти файлы.
Проблема
Если к ячейкам в template.xlsx напрямую применены стили, проблем нет. Однако если ячейки пусты и стили применены только к столбцу, стили переносятся неправильно. В частности, когда к нескольким столбцам применены стили, переносится только стиль из первого столбца.
Справочная информация
Ранее я задавал аналогичный вопрос (если Python вводит значение в пустая ячейка, могу ли я применить стиль к этой строке или столбцу?) и на основе ответов создал функцию под названием apply_style_if_empty. Эта функция позволяет мне получить стиль из столбца, когда ячейка пуста. Однако это работает только для первого столбца, если несколько столбцов имеют стили.
Пример
Я создал пустой файл шаблона и применил цвета к нескольким столбцам.

Когда я использую предоставленный код для копирования значений, первый столбец (A) сохраняет цвет, а остальные столбцы теряют свои стили.

Вопрос
Есть ли способ обеспечить корректную передачу стилей из всех столбцов?
import openpyxl
import csv
import sys
import copy
def apply_style_if_empty(worksheet, cell):
column = cell.column_letter
row = cell.row
column_properties = worksheet.column_dimensions.get(column, None)
row_properties = worksheet.row_dimensions.get(row, None)
# Check if the cell is empty
if cell.value is None:
# Apply style from column_dimensions if available
if column_properties:
if column_properties.fill:
cell.fill = copy.copy(column_properties.fill)
if column_properties.font:
cell.font = copy.copy(column_properties.font)
if column_properties.alignment:
cell.alignment = copy.copy(column_properties.alignment)
if column_properties.number_format:
cell.number_format = copy.copy(column_properties.number_format)
# If column_properties is None or has no style, apply from row_dimensions if available
if row_properties:
if row_properties.fill:
cell.fill = copy.copy(row_properties.fill)
if row_properties.font:
cell.font = copy.copy(row_properties.font)
if row_properties.alignment:
cell.alignment = copy.copy(row_properties.alignment)
if row_properties.number_format:
cell.number_format = copy.copy(row_properties.number_format)
def integrate_template_with_csv(template_path, csv_path, output_path):
# Open template file
template_wb = openpyxl.load_workbook(template_path)
template_ws = template_wb.active
# Open CSV file
with open(csv_path, newline='') as csvfile:
csvreader = csv.reader(csvfile)
csv_data = list(csvreader)
# Fill template with CSV data
for row_idx, row_data in enumerate(csv_data, start=1):
for col_idx, cell_value in enumerate(row_data, start=1):
if not cell_value:
continue
template_cell = template_ws.cell(row=row_idx, column=col_idx)
if not isinstance(template_cell, openpyxl.cell.cell.MergedCell):
target_cell = template_ws.cell(row=row_idx, column=col_idx)
# Apply style from template
apply_style_if_empty(template_ws, target_cell)
target_cell.value = cell_value
# Save as a new file
template_wb.save(output_path)
if __name__ == "__main__":
output_path = sys.argv[1]
csv_path = sys.argv[2]
template_path = sys.argv[3]
integrate_template_with_csv(template_path, csv_path, output_path)
print(f"Data has been successfully integrated and saved as '{output_path}' file.")
Подробнее здесь: https://stackoverflow.com/questions/786 ... yle-is-ret