You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何用Python的Openpyxl复制同工作表含合并单元格的带格式行

用Openpyxl复制含合并单元格的行区域并保留格式

核心思路

要实现带合并单元格的行复制,需分两部分处理:普通单元格的内容与格式复制,以及合并单元格的结构复制。

完整代码示例

from openpyxl import load_workbook
from copy import copy

# 加载工作簿(操作前确保文件处于关闭状态)
wb = load_workbook("你的文件路径.xlsx")
ws = wb.active  # 或用wb["目标工作表名"]指定具体工作表

# 定义源行、目标行及复制列范围(行/列号均从1开始)
source_row = 2
target_row = 5
start_col = 1  # 起始列(如A列)
end_col = 5    # 结束列(如E列)

# 1. 复制普通单元格的内容与格式
for col in range(start_col, end_col + 1):
    source_cell = ws.cell(row=source_row, column=col)
    target_cell = ws.cell(row=target_row, column=col)
    
    # 复制单元格值
    target_cell.value = source_cell.value
    
    # 复制格式:字体、填充、边框、对齐、数字格式等
    if source_cell.has_style:
        target_cell.font = copy(source_cell.font)
        target_cell.fill = copy(source_cell.fill)
        target_cell.border = copy(source_cell.border)
        target_cell.alignment = copy(source_cell.alignment)
        target_cell.number_format = source_cell.number_format

# 2. 复制合并单元格结构
for merged_range in ws.merged_cells.ranges:
    # 筛选出源行内的合并区域
    if merged_range.min_row == source_row and merged_range.max_row == source_row:
        # 确保合并区域在指定列范围内
        if merged_range.min_col >= start_col and merged_range.max_col <= end_col:
            # 生成目标行的合并范围字符串
            new_merge_start = ws.cell(row=target_row, column=merged_range.min_col).coordinate
            new_merge_end = ws.cell(row=target_row, column=merged_range.max_col).coordinate
            ws.merge_cells(f"{new_merge_start}:{new_merge_end}")

# 保存修改后的工作簿
wb.save("修改后的文件路径.xlsx")

关键细节说明

  • 格式复制:用copy()方法复制样式对象,避免直接赋值导致的样式引用共享问题,确保目标单元格格式独立。
  • 合并单元格处理:遍历工作表所有合并区域,筛选出属于源行的部分,再在目标行对应位置创建相同范围的合并单元格。
  • 范围控制:通过start_col和end_col精准限定复制的列区域,避免冗余操作。

注意事项

  • 操作前必须关闭目标Excel文件,否则会触发权限错误。
  • 若源行的合并单元格超出指定列范围,代码会自动忽略该区域,如需包含可调整列范围参数。

内容的提问来源于stack exchange,提问作者Herve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 03:15:27