使用Openpyxl对单元格范围应用边框

时间:2022-11-12 12:15:08

I am using python 2.7.10 and openpyxl 2.3.2 and I am a Python newbie.

我正在使用python 2.7.10和openpyxl 2.3.2,我是一个python新手。

I am attempting to apply a border to a specified range of cells in an Excel worksheet (e.g. C3:H10). My attempt below is failing with the the following message:

我正在尝试对Excel工作表中指定的单元格范围应用边框(例如C3:H10)。以下是我的失败尝试:

AttributeError: 'Cell' object has no attribute 'styles'.

AttributeError:“Cell”对象没有属性“style”。

How do I attach a border to a cell? Any insights would be gratefully received.

如何在单元格上附加边框?任何见解都会受到欢迎。

My current code:

我现在的代码:

import openpyxl
from openpyxl.styles import Border, Side

def set_border(ws, cell_range):
    rows = ws.iter_rows(cell_range)
    for row in rows:
        row[0].styles.borders = Border(left=Side(border_style='thin', color="FF000000"))
        row[-1].styles.borders = Border(right=Side(border_style='thin', color="FF000000"))
    for c in rows[0]:
        c.styles.borders = Border(top=Side(border_style='thin', color="FF000000"))
    for c in rows[-1]:
        c.styles.borders = Border(bottom=Side(border_style='thin', color="FF000000"))


# Example call to set_border
wb = openpyxl.load_workbook('example.xlsx')
ws = wb.get_sheet_by_name('Sheet1')

set_border(ws, "B3:H10")

2 个解决方案

#1


7  

First of all properties are called style (not styles) and border (not borders). Also to change border you should set cell.border directly.

首先,所有属性都被称为样式(不是样式)和边框(不是边框)。还要更改边框,您应该设置单元格。直接边界。

Besides that you have some problems with borders logic, it's more complex to get it working correctly, because of iterators and corners. Here is a rough version (it is as simple as I could get it, but not memory efficient):

此外,您还存在一些与边界逻辑有关的问题,因为迭代器和转角,使它正常工作更加复杂。这里有一个粗略的版本(它很简单,但是内存不够):

def set_border(ws, cell_range):
    rows = ws[cell_range]
    side = Side(border_style='thin', color="FF000000")

    rows = list(rows)  # we convert iterator to list for simplicity, but it's not memory efficient solution
    max_y = len(rows) - 1  # index of the last row
    for pos_y, cells in enumerate(rows):
        max_x = len(cells) - 1  # index of the last cell
        for pos_x, cell in enumerate(cells):
            border = Border(
                left=cell.border.left,
                right=cell.border.right,
                top=cell.border.top,
                bottom=cell.border.bottom
            )
            if pos_x == 0:
                border.left = side
            if pos_x == max_x:
                border.right = side
            if pos_y == 0:
                border.top = side
            if pos_y == max_y:
                border.bottom = side

            # set new border only if it's one of the edge cells
            if pos_x == 0 or pos_x == max_x or pos_y == 0 or pos_y == max_y:
                cell.border = border

#2


0  

border = Border(
            left=cell.border.left,
            right=cell.border.right,
            top=cell.border.top,
            bottom=cell.border.bottom)

can be replaced by:

可以替换为:

border = cell.border.copy()

PS: your answer helped me...

你的回答帮助了我……

#1


7  

First of all properties are called style (not styles) and border (not borders). Also to change border you should set cell.border directly.

首先,所有属性都被称为样式(不是样式)和边框(不是边框)。还要更改边框,您应该设置单元格。直接边界。

Besides that you have some problems with borders logic, it's more complex to get it working correctly, because of iterators and corners. Here is a rough version (it is as simple as I could get it, but not memory efficient):

此外,您还存在一些与边界逻辑有关的问题,因为迭代器和转角,使它正常工作更加复杂。这里有一个粗略的版本(它很简单,但是内存不够):

def set_border(ws, cell_range):
    rows = ws[cell_range]
    side = Side(border_style='thin', color="FF000000")

    rows = list(rows)  # we convert iterator to list for simplicity, but it's not memory efficient solution
    max_y = len(rows) - 1  # index of the last row
    for pos_y, cells in enumerate(rows):
        max_x = len(cells) - 1  # index of the last cell
        for pos_x, cell in enumerate(cells):
            border = Border(
                left=cell.border.left,
                right=cell.border.right,
                top=cell.border.top,
                bottom=cell.border.bottom
            )
            if pos_x == 0:
                border.left = side
            if pos_x == max_x:
                border.right = side
            if pos_y == 0:
                border.top = side
            if pos_y == max_y:
                border.bottom = side

            # set new border only if it's one of the edge cells
            if pos_x == 0 or pos_x == max_x or pos_y == 0 or pos_y == max_y:
                cell.border = border

#2


0  

border = Border(
            left=cell.border.left,
            right=cell.border.right,
            top=cell.border.top,
            bottom=cell.border.bottom)

can be replaced by:

可以替换为:

border = cell.border.copy()

PS: your answer helped me...

你的回答帮助了我……