如何通过 python 从 excel 复制/粘贴合并的单元格?

How do I copy/paste merged cells from excel via python?

提问人:Howdy 提问时间:5/12/2023 最后编辑:Howdy 更新时间:5/12/2023 访问量:226

问:

我尝试使用 openpyxl 并遇到了很多麻烦,现在我正在尝试 pandas 并获得大量回溯。似乎复制粘贴合并的单元格很难而且非常具体,要么就是这样,要么我只是一个菜鸟。任何人都可以提供帮助提示或解决方案吗?

这是我与熊猫的代码

import os
import pandas as pd

# Set the paths for the interim and finals folders
interim_folder = r'C:\Users\Jake_\Downloads\Code\Interims'
finals_folder = r'C:\Users\Jake_\Downloads\Code\Finals'

# Get a list of all files in the interim folder
interim_files = os.listdir(interim_folder)

# Iterate over each file in the interim folder
for file_name in interim_files:
    # Check if the file is an Excel file
    if file_name.endswith('.xlsx'):
        interim_file_path = os.path.join(interim_folder, file_name)
        finals_file_path = os.path.join(finals_folder, file_name)

        # Read the interim Excel file using pandas with the xlrd engine
        interim_data = pd.read_excel(interim_file_path, sheet_name='Financial Report Interim Mar 10', engine='xlrd')

        # Copy the required data to a new DataFrame
        finals_data = pd.DataFrame()
        finals_data['Column B'] = interim_data.iloc[3:8, 1]  # Copy B4:B8
        finals_data['Column D'] = interim_data.iloc[5:201, 3]  # Copy D6:D200
        finals_data['Column E'] = interim_data.iloc[5:201, 4]  # Copy E6:E200
        finals_data['Column F'] = interim_data.iloc[5:201, 5]  # Copy F6:F200
        finals_data['Column G'] = interim_data.iloc[5:201, 6]  # Copy G6:G200

        # Write the data to the finals Excel file
        writer = pd.ExcelWriter(finals_file_path, engine='openpyxl')
        finals_data.to_excel(writer, sheet_name='Final Financial Report July 7', index=False)
        writer.save()

这是我得到的回溯

我想做什么:我在一个名为 interims 的文件夹中大约有 100 个文件 - 每个文件都有一个相应的文件,该文件与一个名为 finals 的文件夹同名。我想从名为“Financial Report Interim Mar 10”的特定工作表中从临时文件夹中的每个文件中复制特定的几个单元格,然后粘贴到名为“Final Financial Report July 7 July 7”的工作表中,该工作表位于 finals 文件夹中的相应文件中。已经尝试并失败了大约 6 个小时。

谢谢

尝试使用 openpyxl 和现在的 pandas,仍然没有运气。

python-3.x pandas python-2.7 openpyxl

评论

0赞 sammywemmy 5/12/2023
如果可以,请共享一个 Excel 文件,其中包含输入和预期输出
0赞 Howdy 5/12/2023
是的,当我回到家时,我可以 - 现在在商店里。大约30分钟后添加!
0赞 sammywemmy 5/12/2023
从错误消息中,您使用的是 XLRD 而不是 OpenPyXL。在 read_excel 中将 openpyxl 传递给 engine 参数。这应该可以解决您的问题,甚至可能消除共享 Excel 文件的需要
0赞 moken 5/12/2023
是的,这部分似乎很清楚,正如回溯所说,XLRD 支持 xls 文件,而不是 xlsx。此外,您应该只能在 Openpyxl 中执行此操作,Pandas 不应该是必需的,但当然是您的选择。interim_data = pd.read_excel(interim_file_path, sheet_name='Financial Report Interim Mar 10', engine='xlrd')xlrd.biffh.XLRDError: Excel xlsx file; not supported
0赞 Howdy 5/12/2023
有趣的是,除了使用 openpyxl 而不是 xlrd 之外,你们还有什么具体的会考虑改变的吗?我在第一次尝试中使用了 openpyxl,但仍然在整个过程中发现了一些随机错误 - 永远无法让它工作。它只是让合并单元格变得更加困难。另外,这里是 excel 照片的链接,如果需要,我实际上也可以上传文件。imgur.com/kMeWch2

答:

0赞 moken 5/12/2023 #1

看起来您提供的 excel 工作簿是要写入的工作簿,即“最终”工作表,所以不确定临时工作表是什么样子的。
但是,要解决 Openpyxl 中的实际问题,请仅从您提供的回溯中获取代码;

Traceback (most recent call last):
  File "C:\Users\Jake_\Downloads\step5.py", line 34, in <module>
    merged_range = interim_worksheet.merged_cells[cell.coordinate]
TypeError: 'MultiCellRange' object is not subscriptable

您要获取合并单元格的左上角单元格。无法直接从合并的单元格中获得,请更改该部分

for cell in row:
    if cell.coordinate in interim_worksheet.merged_cells:
        merged_range = interim_worksheet.merged_cells[cell.coordinate]
        top_left_cell = merged_range.split(':')[0]
        finals_worksheet[cell.coordinate].value = interim_worksheet[top_left_cell].value
    else:

像这样的东西

for cell in row:
    if cell.coordinate in interim_worksheet.merged_cells:
        top_left_cell = ''
        for item in interim_worksheet.merged_cells.ranges:
            top_left_cell = item.coord.split(':')[0]
        finals_worksheet[cell.coordinate].value = interim_worksheet[top_left_cell].value
else:

在上面的代码示例中,如果单元格 D6 和 D7 合并,则为 .top_left_cell'D6'

但正如主循环的评论中所指出的;

for row in interim_worksheet.iter_rows(min_row=6, max_row=200, min_col=4, max_col=7):
    for cell in row:

您将尝试处理不存在的细胞。以单元格 D6 和 D7 被合并为例,在第一行循环中,单元格将是 etc,然后在第二个循环中,第一个单元格将是不存在的,因此此时代码需要确定这一点,否则它将再次中断。

同样的问题也可能以相反的方式发生。如果 D7 是临时工作表中的有效单元格,但合并在最终工作表上(左上角是“D6”),则该行
D6, E6, F6D7

finals_worksheet[cell.coordinate].value = cell.value

也会失败,因为您无法在 Finals 表中写入它。它将返回错误;

AttributeError: 'MergedCell' object attribute 'value' is read-only

评论

0赞 Howdy 5/12/2023
嗯,,我仍然很奇怪地得到了一个痕迹(pastebin.com/XCzhpY71),但老实说,你的帮助让我走上了正确的轨道,我将尝试一些新的方法来解决这个问题。+1 确保帮助
0赞 moken 5/12/2023
你对 Openpyxl 的编码想法很好。您只需要确定每个单元格是否在合并的单元格中,如果是,如果它是您正在执行的左上角,则复制它。如果不是,请转到下一个单元格。那么唯一的问题是,如果两张纸上的单元格合并相同,如果是,则不应尝试将非左上角单元格复制到非左上角单元格。如果不是,那么要么添加相同的合并,如果这是你想要的,要么确定它应该在决赛中复制到哪里。
0赞 Howdy 5/12/2023
我的上帝,我想我做到了。你是最好的!非常感谢!另外,如果您没有时间,请不要担心,但它删除了所有页面上的图像 - 想知道 openpyxl 是否总是会发生这种情况?谢谢!
0赞 moken 5/12/2023
是的,Openpyxl 不会按照文档中的说明读取每个项目 openpyxl 目前不会读取 Excel 文件中所有可能的项目,因此如果以相同的名称打开和保存形状,则形状将从现有文件中丢失。 所以不幸的是,这也意味着图像。最好的选择是将它们作为代码的一部分重新添加,除非手动重新添加它们是微不足道的。
0赞 Howdy 5/12/2023
啊,伙计,太臭了。我想我可以尝试重新添加它们吗?我不知道你可以这样做,因为它们通常是自由浮动的。我会分配照片以便一个单元格来重新添加它们吗?