Python实现Excel跨工作簿表格复制技巧详解:从一个Excel文件复制Sheet到另一个Excel文件的方法大全

场景

在工作中,我们有时候会将一个excel中的sheet复制到一个新的excel中。这通常我们如果使用pandas中的dataframe就能轻松实现,但是当我们遇到有合并单元格的多级表头的excel,dataframe处理起来就麻烦多了,我们更倾向于使用openpyxl库与pandas结合起来处理数据。这个时候就会有一个问题:你会发现openpyxl复制的时候,按照网上的方法,通常只会复制数据,将数据格式和合并单元格,边框等都丢掉了,导致复制表格这个操作失败。
代码如下:

import openpyxl
# 打开源Excel文件和工作表
source_workbook = openpyxl.load_workbook('source.xlsx')
source_sheet = source_workbook.active
# 创建目标Excel文件和工作表
target_workbook = openpyxl.Workbook()
target_sheet = target_workbook.active
# 复制数据和格式
for row in source_sheet.iter_rows(values_only=True):
target_sheet.append(row)

以上代码只复制了数据,但是没有复制数据格式和合并单元格等表格样式。

跨工作簿带格式复制分类

跨工作簿带格式复制总体上大概分成两种情况:(1)直接从文件中读取,然后复制;(2)已经通过openpyxl库读取到内存中,经过数据处理后,要将sheet复制到一个新的excel中保存。

第一类:

第一种比较简单,在网上也能看到很多总结,我这里也找到其中一种进行举例:

# 代码1:带格式复制一个sheet到另一个sheet
from openpyxl import load_workbook
import xlwings as xw
app = xw.App(visible=False, add_book=False)
source_workbook = app.books.open('原表.xlsx')
target_workbook = app.books.open('target.xlsx')
sheet_name = source_workbook.sheets['汇总']  # 要复制的工作表名称
target_worksheet = target_workbook.sheets[0]
sheet_name.copy(before=target_worksheet)
target_workbook.save()
target_workbook.close()
source_workbook.close()
app.quit()

以上代码可以将一个文件名为“原表.xlsx”,sheet名为“汇总”的表格原样复制到文件名为:“target.xlsx”的文件中,大家可以自行测试。

第二类:

但是当需要对数据处理,再带格式复制到另一个excel文件的时候,第一种情况提供的代码就很棘手了。话不多说,直接上案例。如下图一个名称为“original.xlsx”的工作簿,里面包含两个sheet,sheet名称分别为:“汇总”和“清单”。

现在我们想要将original.xlsx工作簿按照“州名”这一列的值进行拆分,生成若干个新的工作簿。拿州名“威斯康星州”举例,生成的新文件为“威斯康星州.xlsx”。如图。

要做以上操作,需要先将原表original.xlsx读入,处理这种有合并单元格的表,我感觉openpyxl更擅长。所以我用load_workbook()方法将original.xlsx读入到内存,先拿出“汇总”表做数据处理,拆成一个州一个文件,这时候我需要先暂存在列表了,然后再拿出“清单”表做数据处理,同样保存到一个列表里,最后我遍历两个列表将一个州的汇总和清单表放到一个文件保存。这时候使用网上的教程要不缺少格式,要不缺少合并单元格,要不缺少列宽。我提供的程序可以将原表全部格式原样复制到新表。但需要注意的是,合并单元格的列宽程序无法全部获取,部分列的列宽设置了默认值,可能无法完全跟原表一致。代码如下:

def copy_sheet_to_sheet(old_sht, new_sht):

    for i in range(1,old_sht.max_row+1):  # 最大行+1

        for j in range(1, old_sht.max_column+1): #最大列+1
            src_cell = old_sht.cell(i, j)

            # getattr(ws.cell(row=m,column=c),"value")
            new_sht.cell(row=i,column=j).value=src_cell.value
            if src_cell.has_style:  #拷贝格式
                new_sht.cell(row=i, column=j).font = copy(src_cell.font)
                new_sht.cell(row=i, column=j).border = copy(src_cell.border)
                new_sht.cell(row=i, column=j).fill = copy(src_cell.fill)
                new_sht.cell(row=i, column=j).number_format = copy(src_cell.number_format)
                new_sht.cell(row=i, column=j).protection = copy(src_cell.protection)
                new_sht.cell(row=i, column=j).alignment = copy(src_cell.alignment)

    if old_sht.merged_cells:
        # 获取合并单元格的边界
        print(old_sht.merged_cells)
        for mergecell in old_sht.merged_cells:
            print(str(mergecell))
            # 在新工作簿中创建合并单元格
            new_sht.merge_cells(str(mergecell))

    # 遍历所有可能的列
    for col_idx in range(1, old_sht.max_column + 1):
        col_letter = get_column_letter(col_idx)
        if col_letter in old_sht.column_dimensions:
            # 列存在且有明确定义的宽度
            column_width = old_sht.column_dimensions[col_letter].width
            # print(f"Column {column} has width: {column_width}")
            new_sht.column_dimensions[col_letter].width = column_width
        else:
            # 列存在但没有明确定义的宽度,可以设置一个默认值
            new_sht.column_dimensions[col_letter].width = 14.35

作者:nrb123

物联沃分享整理
物联沃-IOTWORD物联网 » Python实现Excel跨工作簿表格复制技巧详解:从一个Excel文件复制Sheet到另一个Excel文件的方法大全

发表回复