Openpyxl - 将行范围从工作表转移到另一个

Openpyxl - Transfer range of rows from a worksheet to another

我想从一个sheet中取出一部分数据复制到另一个sheet中。

到目前为止,我有一个字典,其中键作为开始行,值作为结束行。

使用这个,我想做以下事情:

-从sheet0获取第一个范围并将其追加到sheet1

-从sheet0获取第二个范围并将其追加到sheet2

-从sheet0获取第三个范围并将其追加到sheet3

我尝试了以下方法:

#First range starts at 1 and ends at 34, second range from 34-52 and third from 52-75
myDict = {1: 34, 34: 52, 52: 75}

#store all the sheets, ignoring main sheet
sheet = wb.worksheets[1:] 


for item in myDict:
    for col in ws.iter_cols(min_row=item, max_row=myDict[item], min_col=1 , max_col=ws.max_column):
        for cell in col:
            for z in sheet:
                z.append(col)

另一种方法是使用函数和列表:

startRow=[1,34,52]
endRow=[34,52,75]

def addRange(first, second):
    for col in ws.iter_cols(min_row=first, max_row=second, min_col=1 , max_col=ws.max_column):
        for cell in col:
            for z in sheet:
                z.append(col)    

#Call function    
for start, end in zip(startRow, endRow):
    addRange(start, end)  

但在这两种情况下,我都收到以下错误 "ValueError: Cells cannot be copied from other worksheets"

有人知道我在这里遗漏了什么吗?

提前致谢!

from openpyxl import load_workbook
from itertools import product

filename = 'wetransfer-a483c9/testFile.xlsx'
wb = load_workbook(filename)

sheets = wb.sheetnames[1:]

其中 sheets 将是 ['Table 1', 'Table 2', 'Table 3']

# access the main worksheet
ws = wb['Main']

首先,获取每个 Table

的边界 (start-/endpoint)
span = []
for row in ws:
    for cell in row:
        if (cell.value
                and (cell.column == 2)  # restrict search to column2, which is where the Table entries are
                # this also avoids the int error, since integers are not iterable
                and ("Table" in cell.value)):
            span.append(cell.row)

# add sheet's length -> allows us to effectively capture the data boundaries
span.append(ws.max_row + 1)

结果span[1, 29, 42, 58]

其次,得到边界对。 +1 确保在捕获 tables 并将它们转换为 string 格式时包含结尾 由于openpyxl指的是字符串形式的boundaries,索引表示法是1,不是加1,而是要减1。

boundaries = [":".join(map(str,(start, end-1)))  for start, end in zip(span,span[1:])]

结果boundaries['1:28', '29:41', '42:57']

第三,创建主要 sheet、边界和其他 sheet 的笛卡尔坐标。请注意,边界和 sheets 是压缩的——本质上它们是一对。因此,我们将每个 table 与一个边界配对:

#table 1 is bound to 1:28,
#table 2 is bound to 29:41, ...

接下来,我们将主 sheet 与配对组合,因此主 sheet 与 (table 1, 1:28) 配对。同样主sheet搭配(table 2, 29:41) ...

第四,获取范围内的数据。由于我们已经成功地将主 sheet 与每一对 table 和边界配对,我们可以安全地获取该特定区域的数据并将其转移到特定的 table.

所以主要 sheet 中的 table 1 指的是 1:28,因为它绑定到这个特定的 table。当使用 table 1 完成时,它 returns 进入循环并从“Table 2”开始,仅选择“29:41”,因为这是本节中的限制,依此类推.

for main,(ref, table) in product([ws],zip(boundaries, sheets)):

    sheet_content = main[ref]
    # append row to the specified table

    for row in sheet_content:
        #here we iterate through the main sheet
        #get one row of data
        #append it to the table
        #move to the next row, append to the table beneath the previous one
        #and repeat the process till the boundary has been exhausted
        wb[table].append([cell.value for cell in row])
    

最后,保存文件。

wb.save(filename)