简体   繁体   中英

How to move specific cells in an excel file to a new column with openpyxl in python

I am trying to moving some specific cells to a designated location. As shown in the image, would like to move data in cells D3 to E2, D5 to E4,..... so on so for. Is it doable with openpyxl? Any suggestions would be greatly appreciate it!! Click to see the image

Here is what I got so far. It worked per say.

wb=xl.load_workbook(datafile)
ws=wb['Sheet1']

#insert a new column #5
ws.insert_cols(idx=5,amount=1)
wb.save(datafile)

mr=ws.max_row
   
#move cells

for i in range (1,mr+1):
    v=ws.cell(row = i+1,column=4) 
    ws.cell(row=i,column =5).value=v.value

wb.save(datafile)
wb.close

Thanks for the help.

I revised the codes and it worked well. I then wanted to delete the unwanted rows and it didn't work. Looks like it got into an infinite loop. Codes are shown here. What did I do wrong?

wb=xl.load_workbook(datafile)
ws=wb['Sheet1']
#insert a new column #5
ws.insert_cols(idx=5,amount=1)

#Calculate total number of rows 
mr=ws.max_row
   
#move cells
for i in range (2,mr,2):
    ws.cell(row=i,column=5).value=ws.cell(row=i+1,column=4).value

#delete unwanted rows
for i in range (2,mr,2):
    ws.delete_rows(idx=i+1,amount=1)
    
wb.save(datafile)

Thats a good effort.
Here are some comments to help and also on how to skip one row.

  1. Should generally only ever need to save the workbook once at the end of all your edits, unless you are making multiple copies. So the wb.save after the insert command is not necessary.
  2. There shouldn't be need to use 'mr + 1' here. Just the value 'mr' is fine, it matches the rows count.
  3. Not necessary to assign an intermediate variable for just copying a value from one cell to another. Assign the new cell value to the existing cell value in one line as shown. However it's fine if you want to use the variable 'v' as an intermediate.
  4. wb.close should be wb.close() however wont do anything on this workbook anyway Only affects read-only and write-only modes which is a method when opening the workbook. So not need to include that line.

To skip rows you can set the stepping in the range. Stepping is the last number in the range params. So

range(2, mr, 2)

Means 'i' starts at 2, increases to max value [ws.max_row] in increments of 2.
In this case since the max value is 7, i will be 2, 4 and 6
...

wb = xl.load_workbook(datafile)
ws = wb['Sheet1']

# insert a new column #5
ws.insert_cols(idx=5, amount=1)
# wb.save(datafile)  # <--- not necessary just save at the end

mr = ws.max_row

# move cells
# Move and delete the rows by making the changes from the bottom up
for i in reversed(range(2,mr,2)):
    ws.cell(row=i, column=5).value = ws.cell(row=i + 1, column=4).value
    ws.delete_rows(idx=i + 1, amount=1)

wb.save(datafile)
# wb.close  # <-- Not needed, should have brackets anyway

#---- Additional Information ----#
The issue with the deletion is; when you delete a row the rows below shift up immediately. Therefore if you delete row 2 then row 3 becomes row 2 which means starting from the top and deleting down in a pattern like this usually wont work.
To delete the unncessary rows its easier to run the loop in reverse so deletion of a row doesn't affect the rows you have yet to change.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM