使用openpyxl复制单元格样式

44 投票
4 回答
82975 浏览
提问于 2025-04-18 04:32

我正在尝试把一个工作表,叫做 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()])

4 个回答

2

我把上面的答案整理了一下,下面的代码对我有效。

(它可以复制单元格的值和格式)

from openpyxl import load_workbook
from copy import copy

wb = load_workbook(filename = 'unmerge_test.xlsx') #your file name
ws = wb['sheet_merged'] #your sheet name in the file above

for group in list(ws.merged_cells.ranges):
    min_col, min_row, max_col, max_row = group.bounds
    cell_start = ws.cell(row = min_row, column = min_col)
    top_left_cell_value = cell_start.value

    ws.unmerge_cells(str(group))

    for i_row in range(min_row, max_row + 1):
        for j_col in range(min_col, max_col + 1): 
            ws.cell(row = i_row, column = j_col, value = top_left_cell_value)
            #copy the cell format
            ws.cell(row = i_row, column = j_col).alignment = copy(cell_start.alignment)
            ws.cell(row = i_row, column = j_col).border = copy(cell_start.border)
            ws.cell(row = i_row, column = j_col).font = copy(cell_start.font)

wb.save("openpyxl_unmerged.xlsx")

希望这能帮到你!

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

StyleableObject这个实现方式是把样式都放在一个叫_style的列表里,而单元格上的样式属性其实就是对这个列表的获取和设置。你可以为每个样式单独实现复制,但这样做会很慢,特别是当你在一个繁忙的循环里这样做的时候,就会更慢。

如果你愿意深入了解一些私有的类属性,有一种更快的方式来克隆样式:

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

顺便提一下,这就是优化过的WorksheetCopy类在_copy_cells方法中是怎么做的。

57

从 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

撰写回答