Продолжаю цикл статей по теме
Формирование документов Excel из Python. С чем влет столкнулся - как вставить строки в
Openpyxl. То есть нет базовой функции для вставки строк документ. И это проблема для работы с шаблонами отчетов. Например накладную уже не сформируешь.
Поиск в интернете выдал 2 ссылки на примеры кода, как это сделать. По сути это перенос данных на определенное количество строк вниз. Но эти примеры переносили только содержание ячеек, не затрагивая стили и не переносили объединенные диапазоны. То есть оказались не пригодны для работы с шаблонами документа.
Порывшись в кишках
Openpyxl я обнаружил модуль
copier.py, который копирует страницы документа Excel, с переносом всех форматирований. Скрестив данный модуль с кодом найденных примеров я получил первую версию своего модуля
excelz.py с функцией
insert_rows для вставки строк в документ Excel. Сразу скажу, что данная реализация вставляет абсолютно не отформатированные строки и в ближайшем будущем придется модуль дорабатывать для вставки строк по шаблону из предыдущей строки документа.
excelz.py
import openpyxl
from copy import copy
import re
def insert_rows(sheet, startRow, nRows):
maxCol = sheet.max_column
maxRow = sheet.max_row
lastRow = maxRow + nRows
merged_cells = sheet._merged_cells
mcs = []
for m in merged_cells:
pair = m.split(':')
a = re.findall('(\d+)', pair[0])
if int(a[0]) >= startRow:
sheet.unmerge_cells(m)
mcs.append(m)
for i_row in range(maxRow, startRow - 1, -1):
sheet.row_dimensions[i_row + nRows].height = sheet.row_dimensions[i_row].height
for i_col in range(1, maxCol + 1, 1):
source_cell = sheet.cell(row = i_row, column=i_col)
target_cell = sheet.cell(row=i_row + nRows, column=i_col)
target_cell.value = None
target_cell._style = None
target_cell._hyperlink = None
target_cell.comment = None
target_cell._value = source_cell._value
target_cell.data_type = source_cell.data_type
if source_cell.has_style:
target_cell._style = copy(source_cell._style)
if source_cell.hyperlink:
target_cell._hyperlink = copy(source_cell.hyperlink)
if source_cell.comment:
target_cell.comment = Comment(source_cell.comment.text, source_cell.comment.author)
for i_row in range(startRow, startRow +nRows):
sheet.row_dimensions[i_row].height = None
for i_col in range(1, maxCol + 1, 1):
source_cell = sheet.cell(row = i_row, column=i_col)
source_cell.value = None
source_cell._style = None
source_cell._hyperlink = None
source_cell.comment = None
for m in mcs:
pair = m.split(':')
a = re.findall('(\d+)', pair[0])
if int(a[0]) >= startRow:
r1 = int(a[0]) + nRows
c1 = pair[0].split(a[0])[0]
a = re.findall('(\d+)', pair[1])
r2 = int(a[0]) + nRows
c2 = pair[1].split(a[0])[0]
newrange = '%s%d:%s%d' % (c1, r1, c2, r2)
sheet.merge_cells(newrange)