7
votes

Appliquer des frontières à toutes les cellules d'une gamme avec OpenPyXL

J'ai un script qui prend un dataframe de Pandas et le recharge dans plusieurs centaines de morceaux et enregistre chaque morceau de fichier Excel distinct. Chaque morceau aura le même nombre de colonnes, mais le nombre de lignes varie. J'ai compris comment appliquer toutes les autres formatage nécessaires à ces fichiers avec OpenPyXL, mais je n'ai pas encore déterminé le moyen le plus rapide d'appliquer des frontières. En outre, je pense que je ne suis tout simplement pas une application correctement, car le code ci-dessous (que je soupçonne pas de ne pas avoir besoin de boucler sur chaque cellule individuellement) n'applique pas de bordures.

from openpyxl.style import Border

wb = load_workbook(filename = _fname)
ws = wb.worksheets[0]

_range = ws.some_range_func('A1:L'+str(ws.get_highest_row() ) ):
    _range.style.borders.all_borders = Borders.BORDER_THIN


0 commentaires

9 Réponses :


1
votes

Si vous avez besoin de style (bordures ...) pour Pandas Excel Dataframe Ma fourche vient de se faire fusiller dans le maître https://github.com/pydata/pandas/prop/2370#issuecomment-10898427

comme pour vous des problèmes de frontières. Réglage de toutes les bordures à la fois ne se met à la fois pas pour fonctionner à OpenPycYXL. P>

In [37]: c.style.borders.top.border_style = openpyxl.style.Border.BORDER_THIN

In [38]: c.style
Out[38]: 'Calibri':11:False:False:False:False:'none':False:'FF000000':'none':0:'FFFFFFFF':'FF000000':'none':'FF000000':'none':'FF000000':'thin':'FF000000':'none':'FF000000':'none':'FF000000':0:'thin':'FF000000':'none':'FF000000':'none':'FF000000':'none':'FF000000':'none':'FF000000':'general':'bottom':0:False:False:0:'General':0:'inherit':'inherit'


3 commentaires

Attendez, donc avec votre changement, je devrais pouvoir appliquer le style XLSX dans mon appel à DF.TO_EXCEL ()? Pouvez-vous peut-être me montrer une démonstration de la manière dont cela fonctionnerait et explique également ce que je dois faire pour mettre à jour ma version de Pandas pour inclure votre fonctionnalité?


Il suffit de cloner maître et d'installer à partir de la source. DF.TO_Excel ajoutera des frontières à Header, Bold Colnames, Merge Multidex ... Voici une photo Cl.ly/Image/ 2R102L0E1L23 . Ce sera autostyle. Vous pouvez regarder la source pour résoudre votre problème ci-dessus


Je veux appliquer mon propre style, donc ce n'est pas ce dont j'ai besoin. On dirait que le meilleur moyen est de ce que je fais déjà. Merci!



8
votes

Peut-être que ceci est pratique: xxx

il fonctionne raisonnablement rapide.


4 commentaires

DEF SET_BORDER (WS, CELL_RANGEGANGE): ROWS = WS [CELL_RANGE] Pour la ligne de lignes: Rangée [0] .FORMER = bordure (gauche = côté (style = 'mince')). Frontière (droite = côté (style = 'mince')) pour c en rangées [0]: c.border = bordure (haut = côté (style = 'mince')) pour C en rangées [-1]: C.Border = Bordure (bas = côté (style = 'mince'))


Reçu l'erreur: attributError: "feuille de calcul" n'a aucun attribut 'gamme' spécifiquement, en ligne: lignes = ws.range (cell_range)


Remplacez la plage par: Row = WS [Cell_Range]


Je pense que ce code ne borde que les premières lignes et les dernières colonnes, plus la réponse apt serait la @tarun (juste en dessous)



2
votes

@ user698585 Votre approche semble agréable mais elle ne fonctionne plus comme la version actuelle de l'openPyxl modifier la mise en œuvre. Cela devrait donc être mis à jour dans E.G.

    border_style = Style(font=Font(name='Console', size=10, bold=False,
                         color=Color(openpyxl.styles.colors.BLACK)),
                         fill=PatternFill(patternType='solid', fgColor=Color(rgb='00C5D9F1')),
                         border=Border(bottom=Side(border_style='medium', color=Color(rgb='FF000000'))))


1 commentaires

Les styles sont immuables car ils peuvent être partagés par différentes cellules. La meilleure façon de changer le style d'une cellule est de .Copy () et de passer dans les pièces que vous souhaitez modifier.



4
votes

décision qui fonctionne sur OpenPyXL 2.3.5

from openpyxl.styles import Border, Side

def set_border(ws, cell_range):
    border = Border(left=Side(border_style='thin', color='000000'),
                right=Side(border_style='thin', color='000000'),
                top=Side(border_style='thin', color='000000'),
                bottom=Side(border_style='thin', color='000000'))

    rows = ws.iter_rows(cell_range)
    for row in rows:
        for cell in row:
            cell.border = border

set_border(worksheet, 'A5:C10')


1 commentaires

Erreur que j'ai reçue: 'typeError:' str 'objet ne peut pas être interprété comme un entier'



-1
votes

semble qu'il n'y ait pas d'intégré pour cette tâche et nous devons nous faire quelques marches, comme: xxx


0 commentaires

0
votes

avait le même problème mais ne pouvait trouver rien qui résout ce problème pour 2019 en raison de l'amortissement. J'ai quelque chose qui fonctionne ci-dessous. Cela pourrait être meilleur mais fonctionne pour toutes les inthies et les objectifs.

def set_border(ws, cell_range):
    rows = ws[cell_range]
    for row in rows:
        if row == rows[0][0] or row == rows[0][-1] or row == rows[-1][0] or row == rows[-1][-1]:
            pass
        else:
            row[0].border = Border(left=Side(style='thin'))
            row[-1].border = Border(right=Side(style='thin'))
        for c in rows[0]:
            c.border = Border(top=Side(style='thin'))
        for c in rows[-1]:
            c.border = Border(bottom=Side(style='thin'))
    rows[0][0].border = Border(left=Side(style='thin'), top=Side(style='thin'))
    rows[0][-1].border = Border(right=Side(style='thin'), top=Side(style='thin'))
    rows[-1][0].border = Border(left=Side(style='thin'), bottom=Side(style='thin'))
    rows[-1][-1].border = Border(right=Side(style='thin'), bottom=Side(style='thin'))


1 commentaires

Je suppose que cela applique une bordure extérieure à la gamme



6
votes

Il y a une légère modification pour répondre de @karimov
Vous trouverez ci-dessous comment votre code doit être

self.__format_ws__(ws=writer.book.worksheets[0], cell_range='A1:G10')


0 commentaires

4
votes

de manière plus pythonique pour OpenPyXL == 3.0.5:

from openpyxl.styles import Border, Side

def set_border(ws, cell_range):
    thin = Side(border_style="thin", color="000000")
    for row in ws[cell_range]:
        for cell in row:
            cell.border = Border(top=thin, left=thin, right=thin, bottom=thin)

set_border(worksheet, 'A5:C10') 


0 commentaires

1
votes
def set_border(ws, cell_range, style='thin'):
rows = ws[cell_range]
for row in rows:
    temp_row = copy(row[0].border)
    row[0].border = Border(left=Side(style=style), right=temp_row.right, top=temp_row.top, bottom=temp_row.bottom)

    temp_row = copy(row[-1].border)
    row[-1].border = Border(right=Side(style=style), left=temp_row.left, top=temp_row.top, bottom=temp_row.bottom)
for c in rows[0]:
    temp_row = copy(c.border)
    c.border = Border(top=Side(style=style), left=temp_row.left, bottom=temp_row.bottom, right=temp_row.right)
for c in rows[-1]:
    temp_row = copy(c.border)
    c.border = Border(bottom=Side(style=style), left=temp_row.left, top=temp_row.top, right=temp_row.right)
This keeps the existing borders of the side and you can also style your border

0 commentaires