Why delete_rows of openpyxl doesn't delete all empty rows

Question:

I am trying to delete all empty rows in an excel document using openpyxl delete_rows method. And it works fine if there is just one empty row between cells with content, but it would not delete rows if there are more than 2 empty rows. What am I doing wrong?

from openpyxl import *
from openpyxl.utils import get_column_letter
import selenium

wb = load_workbook(r"C:UsersUserDesktopреставрация.xlsx")

ws = wb['main']
ws2 = wb['clean']
print(ws[1][1].value)
c = ws2['C5'].value

# for row in range(1, ws.max_row+1):
#     if ws[row][1].value is None:
#         ws2[row][1].value = ws[row][2].value

for row in range(1, ws2.max_row+1):
    if ws2[row][1].value is None:
        ws2.delete_rows(idx=row, amount = amoun)

wb.save(r"C:UsersUserDesktopреставрация.xlsx")

enter image description here

Asked By: Evgenslam

||

Answers:

The reason for skipping rows is because once you delete a row, the row below it comes up by 1. The range moves one more cell down, so a cell gets skipped. Easiest way to resolve this is to iterate from bottom to top. I have tested it on sample data and it works well. Update the for loop as below. Note that I am not sure what amount=amoun in your code is, but I made it 1.

for row in range(ws2.max_row+1, 1, -1):  ##range is from bottom to top, step -1 
    if ws2[row][1].value is None:
        ws2.delete_rows(idx=row, amount = 1)
Answered By: Redox

Sorry to have bothered you, ladies and gentlemen. Looks like openpyxl has a problem deleting rows when using a loop. I have solved the problem. Looks like you need first to 1)gather rows to be deleted in a list 2)reverse it 3)loop the delete_rows method with the reversed list.

This code solved my problem.

from openpyxl import *

wb = load_workbook(r"C:UsersUserDesktopреставрация.xlsx")

ws = wb['main']
ws2 = wb['clean']
c = ws2['C5'].value    

# for row in range(1, ws.max_row+1):
#     if ws[row][1].value is None:
#         ws2[row][1].value = ws[row][2].value

# gather rows to be deleted in one list
del_rows = []
for row in range(1, ws2.max_row+1):
    if ws2[row][1].value is None:
        del_rows.append(row)
# delete em one by one
for i in reversed(del_rows):
    ws2.delete_rows(i)

wb.save(r"C:UsersUserDesktopреставрация.xlsx")
Answered By: Evgenslam
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.