web-dev-qa-db-fra.com

Définir des styles dans Openpyxl

J'ai besoin de conseils sur la définition des styles dans Openpyxl.

Je vois que le NumberFormat d'une cellule peut être défini, mais j'ai également besoin de la définition des couleurs et des attributs de police (gras, etc.). Il existe une classe style.py mais il semble que je ne puisse pas définir l'attribut style d'une cellule et que je ne veuille pas vraiment commencer à bricoler avec le code source openpyxl.

Quelqu'un a-t-il trouvé une solution à cela?

38
Nelson Shaw

Depuis openpyxl version 1.5.7, j'ai appliqué avec succès les options de style de feuille de calcul suivantes ...

from openpyxl.reader.Excel import load_workbook
from openpyxl.workbook import Workbook
from openpyxl.styles import Color, Fill
from openpyxl.cell import Cell

# Load the workbook...
book = load_workbook('foo.xlsx')

# define ws here, in this case I pick the first worksheet in the workbook...
#    NOTE: openpyxl has other ways to select a specific worksheet (i.e. by name
#    via book.get_sheet_by_name('someWorksheetName'))
ws = book.worksheets[0]

## ws is a openpypxl worksheet object
_cell = ws.cell('C1')

# Font properties
_cell.style.font.color.index = Color.GREEN
_cell.style.font.name = 'Arial'
_cell.style.font.size = 8
_cell.style.font.bold = True
_cell.style.alignment.wrap_text = True

# Cell background color
_cell.style.fill.fill_type = Fill.FILL_SOLID
_cell.style.fill.start_color.index = Color.DARKRED

# You should only modify column dimensions after you have written a cell in 
#     the column. Perfect world: write column dimensions once per column
# 
ws.column_dimensions["C"].width = 60.0

Pour votre information, vous pouvez trouver les noms des couleurs dans le openpyxl/style.py... Je mappe parfois des couleurs supplémentaires à partir de les noms de couleurs X11

class Color(HashableObject):
    """Named colors for use in styles."""
    BLACK = 'FF000000'
    WHITE = 'FFFFFFFF'
    RED = 'FFFF0000'
    DARKRED = 'FF800000'
    BLUE = 'FF0000FF'
    DARKBLUE = 'FF000080'
    GREEN = 'FF00FF00'
    DARKGREEN = 'FF008000'
    YELLOW = 'FFFFFF00'
    DARKYELLOW = 'FF808000'
77
Mike Pennington

Depuis openpyxl 2.0, la définition des styles de cellule est réalisée en créant de nouveaux objets de style et en les affectant aux propriétés d'une cellule.

Il existe plusieurs objets de style: Font, PatternFill, Border et Alignment. Voir le doc .

Pour modifier une propriété de style d'une cellule, vous devez d'abord copier l'objet de style existant à partir de la cellule et modifier la valeur de la propriété ou créer un nouvel objet de style avec les paramètres souhaités. Ensuite, affectez le nouvel objet de style à la cellule.

Exemple de définition de la police en gras et en italique de la cellule A1:

from openpyxl import Workbook
from openpyxl.styles import Font
# Create workbook
wb = Workbook()
# Select active sheet
ws = wb.active()
# Select cell A1
cell = ws['A1']
# Make the text of the cell bold and italic
cell.font = cell.font.copy(bold=True, italic=True)
11
Tomasz Nguyen

Depuis openpyxl-1.7.0, vous pouvez le faire aussi:

cell.style.fill.start_color.index = "FF124191"

J'ai quelques fonctions d'aide qui définissent un style sur une cell donnée - des choses comme les en-têtes, les pieds de page, etc.

2
Enda Farrell

Pour openpyxl versions 2.4.1 et supérieures, utilisez le code ci-dessous pour définir la couleur de la police:

from openpyxl.styles import Font
from openpyxl.styles.colors import Color

ws1['A1'].font = Font(color = "FF0000")

les codes hexadécimaux de différentes couleurs sont disponibles à l’adresse suivante: http://dmcritchie.mvps.org/Excel/colors.htm

1
Parth Karia

Comme openpyxl doc a dit:

Il s'agit d'un projet open source, maintenu par des volontaires pendant leur temps libre. Cela peut signifier qu’il manque certaines fonctionnalités ou fonctions que vous souhaitez. 

J'ai vérifié le code source openpyxl, constaté que:

Jusqu'à openpyxl 1.8.x, les styles sont mutables. Leur attribut peut être assigné directement comme ceci:

from openpyxl.workbook import Workbook
from openpyxl.style import Color

wb = Workbook()
ws = wb.active
ws['A1'].style.font.color.index = Color.RED

Cependant depuis openpyxl 1.9, les styles sont immuables.

Les styles sont partagés entre les objets et une fois affectés, ils ne peuvent plus être modifiés. Cela évite les effets secondaires indésirables, tels que le changement de style pour de nombreuses cellules au lieu d’une seule.

Pour créer un nouvel objet de style, vous pouvez l'affecter directement ou en copier un à partir du style d'une cellule existante avec de nouveaux attributs. Répondez à la question à titre d'exemple (pardonnez mon anglais chinois):

from openpyxl.styles import colors
from openpyxl.styles import Font, Color
from openpyxl import Workbook
wb = Workbook()
ws = wb.active

a1 = ws['A1']
d4 = ws['D4']

# create a new style with required attributes
ft_red = Font(color=colors.RED) 
a1.font = ft_red

# you can also do it with function copy
ft_red_bold = ft_red.copy(bold=True)

# you can copy from a cell's style with required attributes
ft_red_sigle_underline = a1.font.copy(underline="single")

d4.font = ft_red_bold

# apply style to column E
col_e = ws.column_dimensions['E']
col_e.font = ft_red_sigle_underline

Un style de cellule contient les attributs suivants: police, remplissage, bordure, alignement, protection et numéro_format. Vérifiez openpyxl.styles.

Ils sont similaires et doivent être créés en tant qu'objet, à l'exception de number_format, dont la valeur est string type.

Certains formats numériques prédéfinis sont disponibles. Ils peuvent également être définis sous forme de type chaîne. Vérifiez openpyxl.styles.numbers.

from openpyxl.styles import numbers

# use pre-defined values
ws.cell['T49'].number_format = numbers.FORMAT_GENERAL
ws.cell(row=2, column=4).number_format = numbers.FORMAT_DATE_XLSX15

# use strings
ws.cell['T57'].number_format = 'General'
ws.cell(row=3, column=5).number_format = 'd-mmm-yy'
ws.cell['E5'].number_format = '0.00'
ws.cell['E50'].number_format = '0.00%'
ws.cell['E100'].number_format = '_ * #,##0_ ;_ * -#,##0_ ;_ * "-"??_ ;_ @_ '
1
aishenghuomeidaoli

Cela semble être une fonctionnalité qui a changé plusieurs fois. J'utilise openpyxl 2.5.0 et j'ai pu définir l'option barré de la manière suivante:

new_font = copy(cell.font)
new_font.strike = True
cell.font = new_font

Il semble que les versions précédentes (1.9 à 2.4?) Avaient une méthode copy sur la police qui est maintenant déconseillée et déclenche un avertissement:

cell.font = cell.font.copy(strike=True)

Les versions jusqu'à 1.8 avaient des polices mutables, vous pouvez donc faire ceci:

cell.font.strike=True

Cela soulève maintenant une erreur.

0
Don Kirkby