How to swap columns using openpyxl

天大地大妈咪最大 提交于 2021-01-28 06:27:55

问题


I've .xlsx file. Rows are good, values are just fine. But i need to change the columns order by list of new columns positions, e.g: old = [1, 2, 3, 4] new = [2, 1, 4, 3]

Docs are checked - there is no straightforward options for this problem. I've tried to iterate over columns, so:

old = {cell.column: cell.value for cell in ws[1]}.keys() # [1, 2, 3, 4]
new = [2, 1, 4, 3]

for i, col in enumerate(ws.iter_cols(max_col=old[-1]), 1):
    if old[i-1] != new[i-1]:
        for one in ws[get_column_letter(i)]:
            old_cell = one
            new_cell = ws.cell(old_cell.row, old[new[i-1]]-1)
            new_cell.value, old_cell.value = old_cell.value, new_cell.value
        old[i] = new_cell.column
        old[new_cell.column] = old_cell.column

...but it work only for a few cases. Probably i'm missing some general solution.

At the and it should be, for example, old = [1, 2, 3, 4] new = [2, 1, 4, 3]:

Input file:

x A  B  C  D 
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C3 D4

Output file:

x A  B  C  D 
1 B1 A1 D1 C1
2 B2 A2 D2 C2
3 B3 A3 D3 C3
4 B4 A4 D3 C4

回答1:


Your current approach risks overwriting cells. I'd be tempted to move the cells from existing columns to new columns in the correct order and then delete the old ones.

for c in ws['A']:
    new_cell = c.offset(column=6)
    new_cell.value = c.value

for c in ws['B']:
    new_cell = c.offset(column=5)
    new_cell.value = c.value

ws.delete_cols(min_col=1, max_col=4)

This is just to give you the general idea could be optimised and parametrised so you could do each row at once.

Or you could use move_range:

ws.move_range(min_col=1, max_col=1, min_row=1, max_row=ws.max_row, cols=5)

In either case be careful not to overwrite existing cells before you've moved them.



来源:https://stackoverflow.com/questions/57080554/how-to-swap-columns-using-openpyxl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!