web-dev-qa-db-fra.com

copier le style de cellule openpyxl

J'essaie de copier une feuille, default_sheet, dans une nouvelle feuille new_sheet dans le même classeur.

J'ai réussi à créer une nouvelle feuille et à copier les valeurs de la feuille par défaut. Comment puis-je également copier le style de chaque cellule dans les cellules new_sheet?

new_sheet = workbook.create_sheet()
new_sheet.title = sheetName
default_sheet = workbook.get_sheet_by_name('default')
new_sheet = workbook.get_sheet_by_name(sheetName)
for row in default_sheet.rows:
    col_idx = float(default_sheet.get_highest_column())
starting_col = chr(65 + int(col_idx))
for row in default_sheet.rows:
    for cell in row:
        new_sheet[cell.get_coordinate()] = cell.value
        <copy also style of each cell>

J'utilise actuellement openpyxl 1.8.2, mais j'ai en tête de passer au 1.8.5.

Une solution est avec copie:

from copy import copy, deepcopy

new_sheet._styles[cell.get_coordinate()] = copy(
        default_sheet._styles[cell.get_coordinate()])
18
FotisK

Depuis openpyxl 2.5.4, python 3.4: (changements subtils par rapport à l'ancienne version ci-dessous)

new_sheet = workbook.create_sheet(sheetName)
default_sheet = workbook['default']

from copy import copy

for row in default_sheet.rows:
    for cell in row:
        new_cell = new_sheet.cell(row=cell.row, column=cell.col_idx,
                value= cell.value)
        if cell.has_style:
            new_cell.font = copy(cell.font)
            new_cell.border = copy(cell.border)
            new_cell.fill = copy(cell.fill)
            new_cell.number_format = copy(cell.number_format)
            new_cell.protection = copy(cell.protection)
            new_cell.alignment = copy(cell.alignment)

Pour openpyxl 2.1

new_sheet = workbook.create_sheet(sheetName)
default_sheet = workbook['default']

for row in default_sheet.rows:
    for cell in row:
        new_cell = new_sheet.cell(row=cell.row_idx,
                   col=cell.col_idx, value= cell.value)
        if cell.has_style:
            new_cell.font = cell.font
            new_cell.border = cell.border
            new_cell.fill = cell.fill
            new_cell.number_format = cell.number_format
            new_cell.protection = cell.protection
            new_cell.alignment = cell.alignment
22
Charlie Clark

L'implémentation StyleableObject stocke les styles dans une seule liste, _style et les propriétés de style sur une cellule sont en fait des getters et setters de ce tableau. Vous pouvez implémenter la copie pour chaque style individuellement, mais cela sera lent, surtout si vous le faites dans une boucle interne occupée comme je l'ai été.

Si vous êtes prêt à creuser dans des attributs de classe privés, il existe un moyen beaucoup plus rapide de cloner des styles:

if cell.has_style:
    new_cell._style = copy(cell._style)

FWIW c'est ainsi que la classe WorksheetCopy optimisée le fait dans le _copy_cells méthode.

8
ldrg

C'est peut-être le moyen le plus pratique pour la plupart.

    from openpyxl import load_workbook
    from openpyxl import Workbook
    read_from = load_workbook('path/to/file.xlsx')
    read_sheet = read_from.active
    write_to = Workbook()
    write_sheet = write_to.active
    write_sheet['A1'] = read_sheet['A1'].value
    write_sheet['A1'].style = read_sheet['A1'].style
    write_to.save('save/to/file.xlsx')
3
Avik Samaddar