Поиск в файле excel python

поиск в Excel-файле

Привет всем! Интересный вопрос был задан мне в Telegram несколько дней назад. В целом, он сводился к задаче, которая звучала как: поиск в Excel-файле. Давайте попробуем ее решить? 🙂

Собственно, любой Excel-файл — это некоторое количество строк и колонок. Работаем, как всегда — с помощью библиотеки Openpyxl, а для работы с каждой отдельной ячейкой — используем цикл while.

В целом, алгоритм работы кода сводится к:
1. Открываем файл (об этом я писал ранее)
2. Читаем первую ячейку в строке
3. Переходим к следующей строке в этом столбце
4. После того, как достигли максимума по количеству ячеек в столбце — переходим к следующему столбцу.
5. И так до полной обработки файла.

Важно: для того, что бы цикл работал — нам нужно знать количество ячеек в строках и в столбцах. Для этого используем конструкции в виде:

  1. row_max = sheet_active.max_row  # Получаем количество столбцов

и

  1. column_max = sheet_active.max_column  # Получаем количество строк

Сам код с комментариями — доступен ниже.

  1. import openpyxl
  2. from openpyxl.utils import get_column_letter
  3. import re
  4.  
  5. path_to_file = 'base_to_search.xlsx'
  6.  
  7. search_text = input(str('Какой текст ищем: '))
  8. search_text = search_text.lower()
  9. print('Ищем:', search_text)
  10.  
  11. wb = openpyxl.load_workbook(path_to_file)  # Грузим наш прайс-лист
  12. sheets_list = wb.sheetnames  # Получаем список всех листов в файле
  13. sheet_active = wb[sheets_list[0]]  # Начинаем работать с самым первым
  14. row_max = sheet_active.max_row  # Получаем количество столбцов
  15. #print(type(row_max))
  16. column_max = sheet_active.max_column  # Получаем количество строк
  17.  
  18. print('В файле:', path_to_file, 'n Cтолбцов:', row_max, 'n Колонок:', column_max)
  19.  
  20. row_min = 1 #Переменная, отвечающая за номер строки
  21. column_min = 1 #Переменная, отвечающая за номер столбца
  22.  
  23. while column_min <= column_max:
  24.     row_min_min = row_min
  25.     row_max_max = row_max
  26.     while row_min_min <= row_max_max:
  27.         row_min_min = str(row_min_min)
  28.  
  29.         word_column = get_column_letter(column_min)
  30.         word_column = str(word_column)
  31.         word_cell = word_column + row_min_min
  32.  
  33.         data_from_cell = sheet_active[word_cell].value
  34.         data_from_cell = str(data_from_cell)
  35.         #print(data_from_cell)
  36.         regular = search_text
  37.         result = re.findall(regular, data_from_cell)
  38.         if len(result) > 0:
  39.             print('Нашли в ячейке:', word_cell)
  40.         row_min_min = int(row_min_min)
  41.         row_min_min = row_min_min + 1
  42.     column_min = column_min + 1

Конечно, я буду рад любым комментариям и вопросам. Для этого используйте почту или Telegram.

Больше …

Самое основное, с чего начинается изучение языка — с фраз…

Устали фильтровать данные в excel?

Есть решение, как с помощью Python осуществить поиск строк в файле по ключевым словам в столбцах.

Несомненно, многие из нас в своей работе не раз сталкивались с необходимостью фильтрации данных в файле excel, обычно мы делаем это через встроенный в программу фильтр, но бывают ситуации, когда нужно осуществить отбор строк по большому количеству условий (в нашем случае – по ключевым словам) сразу по нескольким столбцам.

Рассмотрим задачу более подробно. Например, у нас есть файл excel с обращениями клиентов в банк (тысячи строк), который содержит следующие колонки: «ИНН клиента», «Дата обращения», «Обращение», «Решение». В столбце «Обращение» содержится текст обращения клиента, в столбце «Решение» — ответ банка на обращение. Суть обращений может быть абсолютно любой (кредитование, страхование, эквайринг и т.д).

Требуется с помощью поиска ключевых слов/сочетаний слов (например, «КАСКО», «ОСАГО», «автострахов», «залог…авто» и т.п.) в колонках «Обращение» и «Решение» выбрать обращения клиентов, которые относятся к страхованию автотранспорта. Нужные слова могут содержаться как в обоих столбцах, так и в одном из них.

Конечно, можно начать фильтровать данные колонки в excel, но это будет долго и трудоёмко, особенно, если слов для поиска подходящих обращений много (или столбцов, в которых необходимо найти ключевые слова). Поэтому для решения нашей задачи требуется более удобный инструмент – Python.

Ниже представлен код, с помощью которого мы отберем необходимые обращения клиентов:

# Импорт библиотек.
import pandas as pd
import numpy as np
import re
#Чтение исходного файла с данными.
df = pd.read_excel(r’ПУТЬ К ФАЙЛУНазвание исходного файла с данными.xlsx’, dtype=’str’)
# Регулярные выражения.
# Шаблон (слова/сочетания слов, которые необходимо найти в столбцах).
r = r'(каско)|(осаго)|(страх.*?транспорт)|(транспорт.*?страх)|(страх.*?авто)|(авто.*?страх)|(залог.*?транспорт)|(транспорт.*?залог)|(залог.*?авто)|(авто.*?залог)|(автострахов)’

Поясним, что «.*?» в выражении (страх.*?транспорт) ищет между «страх» и «транспорт» любое количество символов, вопросительный знак отключает жадность алгоритма поиска (поиск заканчивается как только находится первый «транспорт»).

#Для каждой строки ищем шаблон в столбце «Обращение».
obr = df[‘Обращение’].apply(lambda x: re.search(r, str(x).lower())) #другой вариант: obr = df[‘ Обращение ‘].str.lower().str.contains(r)
#Для каждой строки ищем шаблон в столбце «Решение».
otvet = df[‘Решение’].apply(lambda x: re.search(r, str(x).lower())) #другой вариант: otvet = df[‘Решение’].str.lower().str.contains(r)
#Для каждой строки проверяем наличие шаблона хотя бы в одном из столбцов «Обращение» и «Решение» (результат — True/False).
itog = np.any(np.array([~obr.isnull(), ~otvet.isnull()]), axis=0)
#Результат (оставляем только те строки в таблице, по которым получен результат True).
new_df = df[itog]
#Запись результата в excel.
new_df.to_excel(‘Название итогового файла.xlsx’, index=False)

В результате получаем новый файл excel, в который полностью скопированы нужные нам обращения клиентов:

— в обращении клиента с ИНН 1111111111 в столбцах «Обращение» и «Решение» содержится слово «КАСКО»;

— в обращении клиента с ИНН 333333333333 в столбце «Решение» содержатся сочетания слов «залог…транспорт», «транспорт…страх», «залог…авто», «страх…авто»;

— в обращении клиента с ИНН 444444444444 в столбце «Обращение» содержатся сочетания слов «страх…транспорт»; «транспорт…залог».

Количество столбцов, в которых можно производить поиск ключевых слов, не ограничен – в приведенном примере их два, но у вас может быть больше.

При необходимости для каждого столбца можно задать свой шаблон для поиска слов:

#Шаблон 1 для столбца «Обращение».
r1= r'(каско)|(осаго)|(страх.*?транспорт)|(транспорт.*?страх)|(страх.*?авто)|(авто.*?страх)’
#Шаблон 2 для столбца «Решение».
r2= r'(залог.*?транспорт)|(транспорт.*?залог)|(залог.*?авто)|(авто.*?залог)|(автострахов)’
#Поиск шаблонов 1 и 2 в столбцах «Обращение» и «Решение» соответственно.
obr = df[‘Обращение’].apply(lambda x: re.search(r1, str(x).lower()))
otvet = df[‘Решение’].apply(lambda x: re.search(r2, str(x).lower()))

Если требуется выбрать строки, в которых ключевые слова содержатся и в том, и в другом столбце, то нужно заменить функцию any() на all():

itog = np.all(np.array([~obr.isnull(), ~otvet.isnull()]), axis=0)

Теперь рассмотрим ситуацию, когда у нас имеется несколько файлов excel с обращениями клиентов (с аналогичной структурой столбцов), и необходимо в каждом выбрать подходящие обращения.

Тогда код, с помощью которого мы отберем нужные строки, будет выглядеть так:

#Импорт библиотек.
import pandas as pd
import numpy as np
import os
import re
import warnings
#Игнорирование всех предупреждений.
warnings.filterwarnings(‘ignore’)
#Путь к папке с исходными файлами.
path = r’ПУТЬ К ПАПКЕ С ФАЙЛАМИ ‘
#Регулярные выражения.
#Шаблон (слова/сочетания слов, которые необходимо найти в столбцах).
r= r'(каско)|(осаго)|(страх.*?транспорт)|(транспорт.*?страх)|(страх.*?авто)|(авто.*?страх)|(залог.*?транспорт)|(транспорт.*?залог)|(залог.*?авто)|(авто.*?залог)|(автострахов)’
#Создание папки, в которую будут сохраняться файлы с нужными обращениями.
os.makedirs(‘Нужные обращения’, exist_ok=True)
#Получение списка полных имён для всех файлов xlsx в папке с исходными файлами.
docs = []
for root, _, files in os.walk(path):
for file in files:
if file.split(‘.’)[-1] == ‘xlsx’:
docs.append(os.path.join(root, file))
print(f’В директории {path} nобнаружено {len(docs)} файлов’)
#Для каждого файла из списка производим его чтение, поиск шаблона в столбцах «Обращение» и «Решение», проверяем наличие шаблона хотя бы в одном из данных столбцов, оставляем только те строки в таблице, по которым получен результат True, записываем результат в excel в папку «Нужные обращения».
%%time
for i, doc in enumerate(docs):
df = pd.read_excel(doc)
print(f'{i+1} файл из {len(docs)} прочитан’, end=’ ‘)
obr = df[‘Обращение’].apply(lambda x: re.search(r, str(x).lower()))
otvet = df[‘Решение’].apply(lambda x: re.search(r, str(x).lower()))
itog = np.any(np.array([~obr.isnull(), ~otvet.isnull()]), axis=0)
df = df[itog]
df.to_excel(os.path.join(‘Нужные обращения’, doc.split(‘\’)[-1]), index=False)
print(‘и обработан’)

В результате создается папка «Нужные обращения», в которой содержатся новые файлы excel с полностью скопированными нужными обращениями клиентов. По количеству и названию данные файлы соответствуют исходным.

Таким образом, благодаря Python поиск строк в файлах по ключевым словам в столбцах становится быстрым и несложным делом. Приведенный код значительно ускоряет и упрощает работу аналитика в части фильтрации строк по большому количеству условий по нескольким столбцам.

I’m trying to search for a word in a cell that has a text string that looks like this (Energy;Green Buildings;High Performance Buildings). Here is the code I wrote, I get a syntax error

for row in ws.iter_rows('D2:D11'):
    for cell in row:
        if 'Energy' in ws.cell.value :
            Print 'yes'

Obviously, I don’t want to print yes, this was to test the search function.

Additionally, I want to get the cell location, and then tell openpyxl to assign a color to a cell in the same row under column E. here is a snap shot of my Excel sheet.
I know how to assign a color using this command

c.fill = PatternFill(start_color='FFFFE0', end_color='FFFFE0'
fill_type='solid'
)

I just need help getting the cell location (the cell that has a matching text) and assign its row number to another cell in column E

enter image description here

UPDATE: I wrote this code below that is working fine for me:

import xml.etree.ElementTree as ET



fhand = open ('My_Collection')    
tree =ET.parse('My_Collection.xml')
data= fhand.read()
root = tree.getroot()
tree = ET.fromstring(data)

title_list= ['Title']
year_list = ['Year']
author_list= ['Author']
label_list = ['Label']



for child in tree:
    for children in child:
        if children.find('.//title')is None :
            t='N'
        else:
            t=children.find('.//title').text
        title_list.append(t)
    print title_list
    print len(title_list)


for child in tree:
    for children in child:
        if children.find('.//year')is None :
            y='N'
        else:
            y=children.find('.//year').text
        year_list.append(y)
    print year_list
    print len(year_list)


for child in tree:
    for children in child:
        if children.find('.//author')is None :
            a='N'
        else:
            a=children.find('.//author').text
        author_list.append(a)
    print author_list
    print len(author_list)


for child in tree:
    for children in child:
        if children.find('label')is None :
            l='N'
        else:
            l=children.find('label').text
        label_list.append(l)
    print label_list
print len(author_list) 





Modified_label_list=list()        
import re
for labels in label_list:

    all_labels=labels.split(';')

    for a_l in all_labels:
        if a_l not in  Modified_label_list: 
            Modified_label_list.append(a_l)
        else:
            continue
print Modified_label_list
print len(Modified_label_list)
label_list_for_col_header= Modified_label_list[1:]
print label_list_for_col_header
print len(label_list_for_col_header)




from openpyxl import Workbook 
wb = Workbook() 
ws = wb.active 


for row in zip(title_list, year_list, author_list, label_list): 
        ws.append(row)




r = 5
for N in label_list_for_col_header:
    ws.cell(row=1, column=r).value = str(N)
    r += 1


from openpyxl.styles import PatternFill 


general_lst= list()



COLOR_INDEX = ['FF000000', 'FFFFFFFF', 'FFFF0000', 'FF00FF00', 'FF0000FF',
               'FFFFFF00', 'FFFF00FF', 'FF00FFFF', 'FF800000', 'FF008000', 'FF000080',
               'FF808000', 'FF800080', 'FF008080', 'FFC0C0C0', 'FF808080', 'FF9999FF',
               'FF993366', 'FFFFFFCC', 'FFCCFFFF', 'FF660066', 'FFFF8080', 'FF0066CC',
               'FFCCCCFF', 'FF000080', 'FFFF00FF', 'FFFFFF00', 'FF00FFFF', 'FF800080',
               'FF800000', 'FF008080', 'FF0000FF', 'FF00CCFF', 'FFCCFFFF', 'FFCCFFCC',
               'FFFFFF99', 'FF99CCFF', 'FFFF99CC', 'FFCC99FF', 'FFFFCC99', 'FF3366FF',
               'FF33CCCC', 'FF99CC00', 'FFFFCC00', 'FFFF9900', 'FFFF6600', 'FF666699',
               'FF969696', 'FF003366', 'FF339966', 'FF003300', 'FF333300', 'FF993300',
               'FF993366', 'FF333399', 'FF333333']

import random
color_lst= random.sample(COLOR_INDEX, len(label_list_for_col_header))
print color_lst

print int(label_list_for_col_header.index(label_list_for_col_header[0]))

h= len(title_list)
m= 0    
for lbls in label_list_for_col_header: 
    j= int(label_list_for_col_header.index(lbls))+5
    for row in ws.iter_rows('D2:D11'):
        for cell in  row:

            if lbls in cell.value : 
                general_lst.append(cell.row)
                for items in range(len(general_lst)):

                    ws.cell(row = general_lst[items], column = j).fill = PatternFill(start_color=str(color_lst[m]), end_color=str(color_lst[m]) , fill_type='solid')
    general_lst = []
    m +=1       


ws.column_dimensions['A'].width = 70    
ws.column_dimensions['C'].width = 23
ws.column_dimensions['B'].width = 5        
wb.save("Test61.xlsx")      

enter image description here

Доброго времени суток.
Пишу в отчаянии.

Уже несколько суток пытаюсь освоить хоть что-нибудь (openpyxl, xlsxwriter, xlrd-xlwt…) что поможет мне выполнить следующий, казалось бы простой алгоритм:

  1. Открыть Excel файл.
  2. Найти в определенном столбце ячейку совпадающую с заранее заданным словом (на русском языке).
  3. Скопировать всю строку вместе с этой ячейкой и всеми данными в этой строке (ряду).
  4. Создать новый файл Excel и записать туда все это (все ряды, в которых нашлось то заранее заданное слово).

Попробовал ровно каждый из модулей. В одних жуткие траблы с получением данных из строки, другие не воспринимают русский язык в ячейках, третьи вообще отказываются работать…

Вот допустим последний неудавшийся пример с использованием win32com:

import win32com.client
Excel = win32com.client.Dispatch("Excel.Application")

text = 'Блендер'
counter = 2

def write(val, pos):
    wb = Excel.Workbooks.Add()
    ws = wb.ActiveSheet
    i = 1
    for rec in val:
        ws.Cells(pos,i).value = rec
        i = i + 1
    wb.SaveAs('test.xlsx')
    wb.Close()
    Excel.Quit()


def search():
    wb = Excel.Workbooks.Open(u'C:/Users/User/Desktop/excel.xlsx')
    sheet = wb.ActiveSheet
    srch = [r[0].value for r in sheet.Range("B2:B13")]
    for items in srch:
        if text in items:
            global counter
            print ('Found')
            found = sheet.Range("A%s:D%s" % (counter,counter)).Value
            print (found)
            write(found,counter)
        counter += 1
    
search()

Наверняка этот код настолько неидеален, насколько это вообще возможно.
Но пусть там будет хоть овер999 костылей, лишь бы работало, а он не работает даже с этим — при виде русскоязычного текста впадает истерику и кричит ‘OLE error NONE NONE’. А даже без русских символов один фиг записывает только первую ячейку.

Буду бесконечно рад любой помощи.

Last updated on 
Feb 10, 2022

Do you need to search and replace a list of values in a big Excel file with many sheets?

If so, I’ll show you the steps to search in Excel file — list of words and replace them. In this article you can find the exact cell(with packages like xlrd, xlwt and openpyxl) and partial cell match. At the end a new Excel file is generated with the replaced values.

Let’s check the example data:

A B C
4321 3210 2100
1 0 0
2 1 0
3 2 1
4 3 2

we are going to search for 0 and 1 — and replace them with False and True.

A B C
4321 3210 2100
True False False
2 True False
3 2 True
4 3 2

You can check also this video:
Easily extract information from Excel with Python and Pandas

Python and Excel — search and replace with xlrd and xlwt

In this example we are going to use two Python packages: xlrd and xlwt.

Step 1: Read Excel file

The first package reads the Excel file and a given sheet by name or index:

import xlwt
import xlrd

# read Excel file and sheet by name
workbook = xlrd.open_workbook('/home/vanx/Documents/example1.xlsx')
sheet = workbook.sheet_by_name('Test')
sheet2 = workbook.sheet_by_index(2)

Step 2: Create new Excel file

The second package — xlwt — will be used to write the data into new Excel file:

new_workbook = xlwt.Workbook()
new_sheet = new_workbook.add_sheet('Test')

Step 3: Search and replace a cell in xlsx file

The next step is to define replacement pairs like: {1:True, 0:False}:

replacement = {1:True, 0:False}

Step 4: Search and replace a cell in xlsx file

Finally the code iterates over the rows and columns is controlled by:

  • ncols — number of columns in the selected sheet
  • nrows — number of rows in the selected sheet

This is the final part of the code:

# iterate over the rows
for i in range(sheet.nrows):
    print(i)

    data = [sheet.cell_value(i, col) for col in range(sheet.ncols)]

    for index, value in enumerate(data):

        if value in replacement.keys():
            new_sheet.write(i, index, str(replacement.get(value)))
        else:
            new_sheet.write(i, index, value)

new_workbook.save('example.xls')

where new_workbook.save('example.xlsx') saves the data into file — example.xlsx

Python and Excel — search and replace with openpyxl

Another Python package exists and can be used — openpyxl. It can do the same as the previous example. Difference is that only one module is used for reading and writing new Excel file:

import openpyxl
from openpyxl.utils.cell import get_column_letter

wb = openpyxl.load_workbook('/home/vanx/Documents/example1.xlsx')
wb.sheetnames
sheet = wb["Test"]
number_rows = sheet.max_row
number_columns = sheet.max_column

replacement = {'1':True, '0':False}


for i in range(number_columns):
    for k in range(number_rows):
        cell = str(sheet[get_column_letter(i+1)+str(k+1)].value)
        for key in replacement.keys():
            if str(cell) == key:
                newCell = replacement.get(key)
                sheet[get_column_letter(i+1)+str(k+1)] = str(newCell)

wb.save('example1.xlsx')

The code above reads file: example1.xlsx from folder ~/Documents and then produces a new Excel file in the current working directory. In the file there are several sheets — we are interested in the one named — Test.

Getting the number of rows and columns is done by:

  • sheet.max_row
  • sheet.max_column

Finally we iterate and search for the values. In case of a match then we will replace the cell with the new values.

Python and Excel — partial match

The previous examples work with exact text matches for the cell value. If you need to perform partial match than you can try with Python code like:

if str(cell[0]) == key:

This will search only the first character of the cell if it’s exactly the searched value.

Or if the cell contains the key:

 if key in str(cell[0]):

Regex can be used as well. The problem for such partial matches is performance — it might take resources and time for large Excel files.

Понравилась статья? Поделить с друзьями:
  • Поиск в слова в word по всему документу
  • Поиск в файлах excel по содержанию
  • Поиск в скрытых ячейках excel
  • Поиск в файлах excel не открывая
  • Поиск в сводной таблице excel