在最后几个小时试图找到一种方法,我决定只是问。
我经历了openpyxl docs次多次,并且经历了here和here提出的问题,甚至是{{3}的章节并没有真正回答我试图做的事情。
这是我现在的代码:
for row in ws.iter_rows():
i = 1
if row[i].internal_value() == None:
ws.Rows(i).Delete()
else:
i + 1
我已尝试过很多不同的事情,现在我收到了错误:
TypeError:' NoneType'对象不可调用
我做错了什么,如何修复它以便我遍历所有行并删除任何完全为空的行,或者(如果它更容易实现)一个空的第一个细胞?
由于
答案 0 :(得分:4)
2018更新:我正在搜索今天如何删除一行,发现该功能已添加到openpyxl 2.5.0-b2中。刚试过,它完美无缺。 这是我找到答案的链接:https://bitbucket.org/openpyxl/openpyxl/issues/964/delete_rows-does-not-work-on-deleting
以下是删除一行的语法:
ws.delete_rows(index, 1)
其中: ' WS'是工作表, '指数'是行号,和 ' 1'是要删除的行数。
还可以删除列,但我还没有尝试过。
答案 1 :(得分:4)
可能适合某人使用下一个代码:
index_row = []
# loop each row in column A
for i in range(1, ws.max_row):
# define emptiness of cell
if ws.cell(i, 1).value is None:
# collect indexes of rows
index_row.append(i)
# loop each index value
for row_del in range(len(index_row)):
ws.delete_rows(idx=index_row[row_del], amount=1)
# exclude offset of rows through each iteration
index_row = list(map(lambda k: k - 1, index_row))
答案 2 :(得分:3)
据我所知,openpyxl无法删除行。您可以使用COM代替,例如:
import win32com.client
filename = 'c:/my_file.xlsx'
sheetname = 'Sheet1'
xl = win32com.client.DispatchEx('Excel.Application')
wb = xl.Workbooks.Open(Filename=filename)
ws = wb.Sheets(sheetname)
begrow = 1
endrow = ws.UsedRange.Rows.Count
for row in range(begrow,endrow+1): # just an example
if ws.Range('A{}'.format(row)).Value is None:
ws.Range('A{}'.format(row)).EntireRow.Delete(Shift=-4162) # shift up
wb.Save()
wb.Close()
xl.Quit()
答案 3 :(得分:1)
我发现的原因之一是,每次循环运行时,您都将i的值初始化为1:
i=1
for row in ws.iter_rows():
if row[i].internal_value() == None:
ws.Rows(i).Delete()
else:
i + 1
Rest可以在查看完整代码后回答。
答案 4 :(得分:1)
可以将相同的逻辑应用于删除空列。
from openpyxl import *
import numpy as np
import os
path = "filepath"
workbooks = os.listdir(path)
workbooks = [_ for _ in workbooks if not _.startswith('~')]
for workbook in workbooks:
wb2 = load_workbook(os.path.join(path, workbook))
for sheet in wb2.worksheets:
max_row_in_sheet = sheet.max_row
max_col_in_sheet = sheet.max_column
array_3 = np.array([])
array_4 = np.array([])
r = 1
c = 1
for r in range(1, max_row_in_sheet+1):
array_1 = np.array([])
array_2 = np.array([])
for c in range (1, max_col_in_sheet+1):
if sheet.cell(row = r, column = c).value == None:
array_1 = np.append(array_2, c)
array_2 = array_1
if len(array_1) == max_col_in_sheet:
array_3 = np.append(array_4, r)
array_4 = array_3
array_3 = array_3.astype(int)
if len(array_3) != 0:
index_of_last_array_element = len(array_3) - 1
while index_of_last_array_element != -1:
sheet.delete_rows(array_3[index_of_last_array_element], 1)
index_of_last_array_element = index_of_last_array_element - 1
wb2.save(workbook)
答案 5 :(得分:0)
有很多理由说明openpyxl没有提供这种可能性,但您可以根据此代码段解决问题: https://bitbucket.org/snippets/openpyxl/qyzKn
否则请查看xlwings以远程控制Excel,而不必乱用COM。
答案 6 :(得分:0)
openpyxl.worksheet.worksheet.Worksheet.insert_rows()
openpyxl.worksheet.worksheet.Worksheet.insert_cols()
openpyxl.worksheet.worksheet.Worksheet.delete_rows()
openpyxl.worksheet.worksheet.Worksheet.delete_cols()
特定行:
ws.insert_rows(7)
列范围(与行相同):
ws.delete_cols(6, 3)
(这是2018年的功能,因此请记住升级:python3 -m pip install openpyxl --upgrade)
答案 7 :(得分:0)
此脚本遍历工作簿中的所有工作表,并删除列表“ rows_to_delete”中的行。在运行脚本之前,请确保删除所有表格格式。换句话说,您要先将表格转换为正常范围。
import openpyxl
rows_to_delete = [None, '', ' ']
for i in wb.sheetnames:
print(f'Now in sheet: {i}')
ws = wb[i]
# loop each row in column B
column_b = range(1, ws.max_row)
for i in reversed(column_b):
if ws.cell(i, 2).value in rows_to_delete:
print(f'Deleting Row: {ws.cell(i,2).row}')
ws.delete_rows(ws.cell(i,2).row)