复制单元格样式openpyxl

Posted

技术标签:

【中文标题】复制单元格样式openpyxl【英文标题】:copy cell style openpyxl 【发布时间】:2014-06-13 11:28:49 【问题描述】:

我正在尝试将工作表 default_sheet 复制到同一工作簿中的新工作表 new_sheet

我确实设法创建了一个新工作表并从默认工作表中复制了值。如何将每个单元格的样式也复制到 new_sheet 单元格中?

new_sheet = workbook.create_sheet()
new_sheet.title = sheetName
default_sheet = workbook.get_sheet_by_name('default')
new_sheet = workbook.get_sheet_by_name(sheetName)
for row in default_sheet.rows:
    col_idx = float(default_sheet.get_highest_column())
starting_col = chr(65 + int(col_idx))
for row in default_sheet.rows:
    for cell in row:
        new_sheet[cell.get_coordinate()] = cell.value
        <copy also style of each cell>

我目前正在使用 openpyxl 1.8.2,但我想切换到 1.8.5。

一种解决方案是复制:

from copy import copy, deepcopy

new_sheet._styles[cell.get_coordinate()] = copy(
        default_sheet._styles[cell.get_coordinate()])

【问题讨论】:

我找到了一种复制方式,但我不确定这是否是最好的方式,并且它不会复制单元格的宽度/高度等所有内容! 是的,您需要使用复制。每个工作表都有一个可以复制的单元格样式字典。但是你真的想尝试使用 1.9 分支,它有一个更干净的界面来处理这类事情。 【参考方案1】:

从 openpyxl 2.5.4 开始,python 3.4:(下面旧版本的细微变化)

new_sheet = workbook.create_sheet(sheetName)
default_sheet = workbook['default']

from copy import copy

for row in default_sheet.rows:
    for cell in row:
        new_cell = new_sheet.cell(row=cell.row, column=cell.col_idx,
                value= cell.value)
        if cell.has_style:
            new_cell.font = copy(cell.font)
            new_cell.border = copy(cell.border)
            new_cell.fill = copy(cell.fill)
            new_cell.number_format = copy(cell.number_format)
            new_cell.protection = copy(cell.protection)
            new_cell.alignment = copy(cell.alignment)

对于 openpyxl 2.1

new_sheet = workbook.create_sheet(sheetName)
default_sheet = workbook['default']

for row in default_sheet.rows:
    for cell in row:
        new_cell = new_sheet.cell(row=cell.row_idx,
                   col=cell.col_idx, value= cell.value)
        if cell.has_style:
            new_cell.font = cell.font
            new_cell.border = cell.border
            new_cell.fill = cell.fill
            new_cell.number_format = cell.number_format
            new_cell.protection = cell.protection
            new_cell.alignment = cell.alignment

【讨论】:

我使用的是openpyxl 2.4.1,cell.fontcell.borderStyleProxy 的一个实例,如果使用该类型保存工作簿,你会得到一个异常。您必须将其复制到新单元格,如下所示:new_cell.font = copy(cell.font) 谢谢你 dadcold,想知道为什么我会收到“非哈希类型”错误。 值得注意的是,工作簿已经有一段时间了 copy_worksheet 方法,并且这种复制样式适合您。 这对合并的单元格不起作用,并且不保留单元格的尺寸。 这不是一个精确的副本,当我尝试时相当混乱。没有正确对齐【参考方案2】:

StyleableObject 实现将样式存储在单个列表 _style 中,并且单元格上的样式属性实际上是该数组的 getter 和 setter。您可以单独为每种样式实现副本,但这会很慢,尤其是当您像我一样在繁忙的内部循环中执行此操作时。

如果您愿意深入研究私有类属性,有一种更快的方法来克隆样式:

if cell.has_style:
    new_cell._style = copy(cell._style)

FWIW 这就是优化的WorksheetCopy 类在_copy_cells 方法中的作用。

【讨论】:

如果您希望在多个单元格中使用相同的样式,NamedStyles 会更有意义。 不错的代码。正是我目前所需要的。但事实上,在某些情况下NamedStyles 可能是更好的方法 感谢单行回答 这对我不起作用,使用 openpyxl 3.0.9【参考方案3】:

这对大多数人来说可能是最方便的方式。

    from openpyxl import load_workbook
    from openpyxl import Workbook
    read_from = load_workbook('path/to/file.xlsx')
    read_sheet = read_from.active
    write_to = Workbook()
    write_sheet = write_to.active
    write_sheet['A1'] = read_sheet['A1'].value
    write_sheet['A1'].style = read_sheet['A1'].style
    write_to.save('save/to/file.xlsx')

【讨论】:

这不是所有的样式,this answer更好,但copy必须使用。

以上是关于复制单元格样式openpyxl的主要内容,如果未能解决你的问题,请参考以下文章

完全解读 OpenPyXL 设置 Excel 单元格样式

使用openpyxl创建excel并设置单元格样式

openpyxl 设置某列单元格样式

python-openpyxl Excel的单元格样式设置,包括字体样式宽高等等!

openpyxl 库

使用 openpyxl 移动到相邻单元格