Приведенный ниже фрагмент кода очень близок к созданию правильного вывода, но в нем отсутствуют некоторые необходимые строки и добавлено несколько строк, которых не должно быть, и я не могу понять, почему.
LU = "Gilford"
for i, row in enumerate(sourcews2.iter_rows(min_row=5, min_col= 1, max_col=33)):
if sourcews2.cell(row=i+1, column=1).value == LU:
destinationws.append([cell.value for cell in row])
Строки на изображении ниже, где первая ячейка = Гилфорд, — это строки, которые я пытаюсь извлечь и добавить в другой лист Excel.
Результаты вывода на другом листе Excel выглядят так, как показано на рисунке ниже. В исходном листе отсутствуют 4 строки из верхней части стека Гилфорда, а также добавлены 4 строки, следующие за стеком Гилфорда, которые начинаются с «Серый». Ссылаясь на приведенный выше фрагмент кода, я не знаю, как и почему он извлекает строки, начинающиеся с «Серый».
Вот и все, что было. Я не учел строки вверху, в которых содержалась информация о таблице и имена столбцов. Спасибо! Но я все еще не понимаю, почему он захватывает «серые» строки, потому что у меня есть оператор if?
По той же причине, потому что sourcews2.cell(row=i+1, column=1)
и [cell.value for cell in row]
— это не одна и та же строка.
Это не очень эффективный способ делать то, что вы делаете, но вы знаете, что перечисление может начинаться с любого номера, который вы выберете, например, for i, row in enumerate(sourcews2.iter_rows(min_row=5, min_col= 1, max_col=33),5):
начнет i
считать с 5, чтобы оно было синхронизировано с row
. Но тогда вы сразу поймете, почему ваша реализация неэффективна.
Ааа, ладно, теперь это имеет смысл. Не знаю, догадался ли бы я когда-нибудь об этом. Спасибо за объяснения.
row[0].row
— это номер строки, которую вы сейчас ищете, i
является избыточным.
Возможно, сначала используйте print()
(и print(type(...))
, print(len(...))
и т. д.), чтобы увидеть, какая часть кода выполняется и что на самом деле у вас есть в переменных. Он называется "print debuging"
и помогает увидеть, что на самом деле делает код.
Есть ли в openpyxl метод или функция, которую можно использовать для указания, в какую ячейку добавлять данные на целевом листе? Я не могу найти ничего подобного. Вместо этого мне кажется, что мне придется разобраться с этим, используя destinationws.cell(row= , column= ).value = cell.value
Moken уже предоставил решение, но я просто добавлю, что если вы используете ws.iter_rows()
, вам почти никогда не придется использовать ws.cell()
в одном и том же коде. В вашем случае cell.offset()
имело бы больше смысла, но это было бы лишним, потому что у вас есть все ячейки в строке.
Вам не нужно беспокоиться об автоматическом добавлении.
Ваш код будет работать, вам просто не нужен лишний счетчик i
.
Приложение Openpyxl всегда будет добавлять данные в следующую неиспользуемую строку. Это следующая строка после последней строки, содержащей ячейку со значением, отличным от None
.
Данные должны быть предоставлены в виде списка или словаря.
destinationws.append({'A': 'Value1', 'C': 'Value2'})
«Значение1» вводится в столбец A, а «Значение2» вводится в столбец C.И всегда в следующую неиспользованную строку.
Все, что вам нужно, это следующее;
В каждой итерации iter_rows row[0]
— это первая ячейка в строке, т. е. столбец A, поэтому row[0].value
— это значение в ячейке, в которой вы ищете «Гилфорд».
Найдя, создайте свой список, как вы это делаете, и поскольку row
в вашем создании списка является той же строкой, что и вы в данный момент ищете «Гилфорд», выбранные данные будут для правильной строки.
Затем добавьте эти данные. Список добавляется к следующей неиспользуемой строке.
from openpyxl import Workbook, load_workbook
sourcewb = load_workbook('data.xlsx')
sourcews2 = sourcewb['Sheet1']
destinationwb = Workbook()
destinationws = destinationwb.active
LU = "Gilford"
for row in sourcews2.iter_rows(min_row=5, min_col=1, max_col=33):
if row[0].value == LU:
destinationws.append([cell.value for cell in row])
destinationwb.save('new.xlsx')
Поскольку координаты ячеек не имеют значения, вы можете использовать здесь values_only=True
, а затем просто передать строку для добавления. И, наверное, можно использовать read_only=True
в рабочей тетради. Если это возможно, сочетание этого с режимом «только запись» является хорошим шаблоном.
sourcews2.cell(row=i+1, column=1)
«отключен» на 4 строки.