使用 Openpyxl 将边框应用于单元格范围

问题描述 投票:0回答:3

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

我正在尝试将边框应用于 Excel 工作表中指定的单元格范围(例如

C3:H10
)。我的以下尝试失败并显示以下消息:

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

如何为单元格添加边框?任何见解将不胜感激。

我当前的代码:

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")
python excel openpyxl
3个回答
18
投票

首先,所有属性称为

style
(不是
styles
)和
border
(不是
borders
)。另外,要更改边框,您应该直接设置
cell.border

除了边界逻辑存在一些问题之外,由于迭代器和角点的存在,使其正常工作更加复杂。这是一个粗略的版本(它是我能得到的最简单的版本,但是内存效率不高):

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

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

可以替换为:

border = cell.border.copy()

PS:你的回答对我有帮助...


0
投票

有一个 cell_range 模块,您可以使用 CellRange 对象来定义(矩形)范围。

CellRange 实例包含一个可以循环访问的属性“cells”。它还包含属性“top”、“bottom”、“left”和“right”,每个属性都是一个元组列表(行、列),表示给定范围内的单元格(分别)到给定单元格区域的顶部、底部、左侧和右侧。例如,cell_range.top 中的 (2, 4) 表示单元格 C4 属于单元格区域的“顶部”部分。 您可以使用它来定义每个单元格的边框,同时循环遍历给定单元格范围中的所有单元格:

from openpyxl.styles import Alignment, Font, PatternFill, Side, Border 
from openpyxl.worksheet.cell_range import CellRange

def set_border(ws, cell_range):
    side = Side(border_style='thin', color="FF000000")
    for cell in cell_range.cells:
        right = side if cell in cell_range.right else None
        left = side if cell in cell_range.left else None
        top = side if cell in cell_range.top else None
        bottom = side if cell in cell_range.bottom else None
        current_cell = ws.cell(*cell)
        current_cell.border = Border(right=right, left=left, top=top, bottom=bottom)

set_border(ws, cell_range=CellRange("C3:H10"))
© www.soinside.com 2019 - 2024. All rights reserved.