边框应用到所有的细胞与openpyxl范围(Apply borders to all cells i

2019-07-04 08:18发布

我有一个脚本,需要一个数据帧大熊猫和扒它分成几百块,并保存每个块作为一个单独的Excel文件。 每一块都会有相同的列数,但是行的数量而变化。 我已经想通了如何应用所有其他必要的格式与openpyxl这些文件,但我还没有确定应用边框的最快方式。 另外,我觉得我只是没有正确应用边框,因为下面的代码(我怀疑不应该需要遍历每个单独的单元格)不适用任何边界。

from openpyxl.style import Border

wb = load_workbook(filename = _fname)
ws = wb.worksheets[0]  
for _row in ws.range('A1:L'+str(ws.get_highest_row() ) ):
    for _cell in _row:
            _cell.style.borders.left.border_style = Border.BORDER_THIN
            _cell.style.borders.right.border_style = Border.BORDER_THIN
            _cell.style.borders.top.border_style = Border.BORDER_THIN
            _cell.style.borders.bottom.border_style = Border.BORDER_THIN
wb.save(_fname)

因此,此代码的工作 ,但它并不适用于我预计(在Excel中默认边框)的边界,它需要更多的步骤比我更喜欢。 我的期望是,我应该可以做这样的事情:

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

这是否存在功能? 如果没有,可有人请这么好心至少说明如何应用默认的边框样式,而不是这个略厚的边界? Border.BORDER_THICK,Border.BORDER_MEDIUM,Border.BORDER_THIN,或Border.BORDER_HAIR似乎都不正确。

谢谢!

Answer 1:

可能这很方便:

from openpyxl.reader.excel import load_workbook
from openpyxl.style import Border

def set_border(ws, cell_range):
    rows = ws.range(cell_range)
    for row in rows:
        row[0].style.borders.left.border_style = Border.BORDER_THIN
        row[-1].style.borders.right.border_style = Border.BORDER_THIN
    for c in rows[0]:
        c.style.borders.top.border_style = Border.BORDER_THIN
    for c in rows[-1]:
        c.style.borders.bottom.border_style = Border.BORDER_THIN

#usage example:
ws = load_workbook('example.xlsx').get_active_sheet()
set_broder(ws, "C3:H10")

它执行相当快。



Answer 2:

@ user698585你的方法似乎不错,但它并没有为openpyxl的当前版本继续工作,改变实现。 所以这应该是更新到如

    ws.cell(row=1, column=1).style.border.top.border_style = borders.BORDER_MEDIUM

但结果与转变作风是不允许出错。 作为一种变通方法我刚才定义专用的风格,但他们只是目前的款式加上边界的定义重复 - 不那么好解决方案只有当你知道是什么风格有变化的情况下对小区的工作。

    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'))))


Answer 3:

上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')


Answer 4:

如果你需要为熊猫造型(边界...)擅长数据帧我的叉子刚刚合并到主https://github.com/pydata/pandas/pull/2370#issuecomment-10898427

至于你边界问题。 设置在一次所有边界不缝在openpyxl工作。

In [34]: c.style.borders.all_borders.border_style = openpyxl.style.Border.BORDER_THIN

In [36]: c.style
'Calibri':11:False:False:False:False:'none':False:'FF000000':'none':0:'FFFFFFFF':'FF000000':'none':'FF000000':'none':'FF000000':'none':'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'

设置单独的作品(“薄”:“FF000000”)

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'

也许在openpyxl的错误。 但没什么大不了的只是包装设置顶部,底部,左,右的功能



Answer 5:

有同样的问题,但找不到任何解决这个问题,因为2019折旧。 我有一些作品下面..可能会更好,但适用于所有打算和目的。

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'))


Answer 6:

看来是没有内置的这项任务,我们必须作出一些自己的步骤,比如:

#need make conversion from alphabet to number due to range function
def A2N(s,e):
    return range(ord(s), ord(e)+1)
#B1 is the border you defined
#Assume you trying border A1-Q1 ... A3-Q3
X = A2N('A','Q')
#print X    
your_desired_sheet_range_rows = range(1,4)
#need two loop to go through cells
for row in your_desired_sheet_rows:
    for col in X:
        ca = chr(col)
        sheet[ca+str(row)].border=B1


文章来源: Apply borders to all cells in a range with openpyxl