Работа с Excel в Питоне

Автор: | 16.11.2018

Работа с Excel в Питоне.

Для работы с файлами Excel в Python создано несколько библиотек. Часть из них ориентирована на работу только с файлами типа XLS, а другие могут обрабатывать и файлы типа XLSX. Файлы первого типа двоичные и кодированные, файлы второго типа текстовые, и на самом деле в действительности состоят из ряда папок (директорий). Это можно увидеть, если изменить тип файла на неизвестный системе, например, XL,DO,PP.

При просмотре в Total Commander мы увидим только гипертекстовые файлы типа XML.

Я пока предпочитаю работать в старой системе 2003.

Для обработки файлов Excel необходимо сначала скачать необходимые библиотеки, но на первом этапе надо установить программы PIP или PIP3 – установщики пакетов. Эти программы типа EXE.

После установки ПИПОВ скачиваем сами библиотеки. Для начала это могут быть пакеты чтения файлов Excel, записи файлов Excel, утилит, обработки файлов Excel в формате близком к VBA.

Все скачиваемые пакеты будут иметь  расширение WHL и длинное имя. Лучше имена укоротить  до XLRD, XLWT, XLUTILS и PYWIN32. Все имена файлов скачиваются в строчном формате. Я их просто выделил.

Для установки пакетов вызываем командное окно системы. Я это делаю через Выполнить и cmd в окне. В начале лучше войти в папку, где находятся пакеты для установки. Я скопировал эти пакеты в директорию scripts папки Python 3_7  на диске С.

Поэтому набираю в командном окне

cd C:\ Python 3_7\scripts

Т.к. по умолчанию система ПК предполагает выбор директории Мои Документы или User в некоторых случаях, то в ней можно создать Bat файл  с командами выше. Я это делаю. Файл можно назвать питон.bat или python.bat. Для Анаконда я создаю файл conda.bat.

После установки exe файлов pip.exe или pip3.exe можно начать устанавливать пипами выбранные пакеты.

pyp3 install xlrd, потом pyp3 install xlwt и т.д.

Установка библиотек для работы с файлами Excel  происходит быстро. Если возникают ошибки, то они видны в окне CMD. О попытке загрузки уже установленной ранее библиотеки  также появляется  сообщение. Пакет может быть, хотя и установлен, но не работать по каким-то причинам. Так у меня в начале произошло с пакетом PANDAS. В этом случае для удаления сбойного пакета вызывается в том же окне CMD команда UNINSTALL. Между прочим у меня не пошла установка и пакета Anaconda3. Все правильно установилось только тогда, когда я снёс старый Питон и почистил реестр Windows методом тупого поиска ссылок. Хотя это можно сделать было и программно.

Пакет utils связующий между пакетами xlrd, xlwt.

Что я заметил при обработке файлов Excel?

Обработка файлов Excel в питоне с помощью COM32  (Win32) более понятна и близка по виду к работе с макросами. Но время обработки зато приближается к времени обработке в самом Excel или даже больше. Обработка файлов Excel командами библиотек XLRD и XLWT происходит быстро, очень быстро.

Второй момент. Модуль XLRD служит лишь для  чтения и обработки считанного файла. Записать открытый файл, сохранить его нельзя. Это приводит к ошибке.

Обязательно надо сначала создать модулем XLWT новый файл Excel и добавить в него необходимое число листов, затем переписать в него данные со считанного ранее файла и записать новые  сведения. Новый файл можно создать и методом копирования. Обработку  данных надо вести в считанном по XLRD файле, формировать данные на листах выходного файла, а только потом записывать, перезаписывать или добавлять вниз. К листу можно обратиться или по имени, или по индексу.

Ниже один из примеров с полей Интернет

Пример просто на чтение и обработку:

import xlrd

wb_path = r’c:\Python 3_7\Работа с Excel\analiz.xls’

output_path = r’c:\Python 3_7\Работа с Excel\output.txt’

wb = xlrd.open(wb_path)

ws = wb.sheets()[0]# Это обращение к первому листу файла

# assuming you want to work with the first sheet in the workbook with open(output_path, ‘w’) as output_file:

for i in xrange(ws.nrows):

row = [cell.value for cell in ws.row(i)]

# … replace the following if statement with your own conditions …

if row[0] == u’interesting’:

output_file.write(‘\t’.join(row) + ‘\r\n’)

Пример на создание нового файла и запись в него данных

 # тут важно поставить ‘utf-8’, если надо писать русские символы и так далее

import xlwt

wbk = xlwt.Workbook(‘utf-8’)

# добавляем лист

sheet = wbk.add_sheet(‘sheet 1’)

# пишем в первую строку и первый столбец

sheet.write(0, 0, ‘bla bla’)

print (2**3)

# сохраняем в файл

wbk.save(‘C:/Python 3_7/test.xls’)

Параметры команд каждого модуля можно просмотреть командой Dir, например, dir(xlrd), dir (xlwt). При работе с Питоном не стоит забывать, что он чувствителен к написанию команд и идентификаторов в строчном или заглавном формате, например,  команда Print (…..) вызовет ошибку, т.к. она должна набираться как print.

P.S. Сегодня день ракетных войск и артиллерии 19 ноября, посвященный фактически началу зимнего контрнаступления под Сталинградом. Я служил когда-то в ракетных войсках, так что это и мой праздник.

А теперь к теме. Наконец-то я написал свой работающий модуль обработки Экселовского файла диагностических работ. В нем данные со 2 строки по 861. Шапка в первой строке. Файлы диагностики есть на моём сайте, поэтому я его не размещаю. В исходном файле данные почему-то по 107 столбец, хотя заполнено всего 27, а вернее 28. Питон ведь ведёт отсчёт с нуля. К этому тоже надо привыкать после VBA. В VBA проблема выделения столбцов решается переходом с метода UsedRange на метод XlEnd. В питоне пришлось действовать пока более грубо путём поиска пустого первого столбца.

В своём модуле я создавал много проверочных операторов print, чтобы отладить программу. Часть из них я до сих пор оставил по привычке делать программы более удобные для диагностики и обучения.

Какая ещё проблема возникла у меня? Очень простая, но я долго из-за неё искал ошибку. Это тип данных и их преобразование.

Вариант программы для обработки файлов Excel Анализ диагностических работ.

Напомню, что этот файл состоит из 7 основных полей –

Муниципалитет Общеобразовательная организация Класс Участник Сумма баллов Процент выполнения Оценка

Далее идут столбцы заданий. В моём проверочном файле было 20 заданий в столбцах 8-27. В питоне это range(7,27). По каждому выполненному заданию выставляется оценка-критерий 0,1,2 или X-латинское. Поиск школ – это лишнее в алгоритме, но использовалось для проверки. Была попытка использовать функцию для подсчета количества данных критериев по столбцу, что логично. Но это приводило к смещению выводимых данных на столбец вправо. Так и не сумел в этом разобраться. Поэтому использовал алгоритм подсчёта количества записей по данному критерию в данном столбце в данной школе в самом тексте программы. У меня есть аналогичная программа в макросах VBA.  Но в питоне обработка ведётся в десятки раз быстрее, не смотря на операторы вывода, правда пока не сумел сохранить форматирование. В макросах я могу моделировать и функции Excel, а возможно ли это здесь? Пока не знаю.

Выходные данные работы программы

Sheet: Лист1
Число столбцов = 107
Число строк на листе – 861 А число найденных столбцов на листе – 107

Определяем пустую ячейку и колонку

Номер первого пустого столбца = 27

Диапазон поиска: строк= 861 столбцов 27
#Список 29 школ и числа учащихся в них опущен
spList= [0.0, 1.0, 2.0, ‘X’]
Список оценок заданий, отсортированный по убыванию – [‘X’, ‘2.0’, ‘1.0’, ‘0.0’]
Список оценок заданий, отсортированный по возрастанию – [‘0.0’, ‘1.0’, ‘2.0’, ‘X’]

#Выше видно, что уже изначально список был Питоном отсортирован по возрастанию, но типы данных разные

#Из-за этого сортировка давала бы ошибку, если бы не было приведению к одному типу
Число значений = 4
0.0
1.0
2.0
X
Число оценок = 4
X <class ‘str’>
s.nrows= 861
>>>

Текст программы

from xlrd import open_workbook
import xlrd
import xlwt
import xlutils
import sys

wb_path = r’c:\Python 3_7\Работа с Excel\analiz.xls’
output_path = r’c:\Python 3_7\Работа с Excel\output_school_kriterii_schools.xls’
wb = open_workbook(wb_path,formatting_info=True)

#Создаём новую рабочую книгу
wbk = xlwt.Workbook(‘utf-8’)
ws = wbk.add_sheet(‘A Test Sheet’)
#print (wb.sheet.name)
for s in wb.sheets():
print (‘Sheet:’,s.name)
# s=wb.sheets(0)
print(“Число столбцов =”,s.ncols)

#Определяем номер последней строки и последней колонки на листе WB
i=s.nrows
j=s.ncols

#Число колонок часто больше по UsedRange в VBA, чем заполненных
#Ищем последнюю колонку таблицы
print (“Число строк на листе -“,i,” А число найденных столбцов на листе -“,j)
print (“\nОпределяем пустую ячейку и колонку”)

for p in range(s.ncols):
if s.cell(1,p).value==””:
break
print (“\nНомер первого пустого столбца = “,p)
j=p
print (“\n\nДиапазон поиска: строк=”,i, ” столбцов”,j)

#Заводим значения типа Set для получения значений критериев и наименований школ
values = set()
schools = set()

#Получение данных о количестве и значении оценок заданий

for row in range(1,i):
n=row%100 # Ниже условие для подсчета числа обработанных строк
# if n==0:
#Вывод количества обработанных строк с шагом 100
# print (“Обработано строк-“,row)

#Заполнение наименований школ из колонки №2
school=s.cell(row,1).value
schools.add(school)

for col in range(7,j):
value = (s.cell(row,col).value)

# try : value = str(int(value))
# except : pass
values.add(value)

#Печать найденных школ после преобразования в список

spSchool=list(schools)
spSchool.sort(reverse=False)
#for s1 in spSchool:
# print (“\n”,s1)

# Предыдущий и этот циклы можно было объединить
#Подсчет числа записей в конкретной школе и вывод на печать для контроля
n=1
for sps in spSchool:

for i in range(2,s.nrows):
school=s.cell(i,1).value
if sps==school:
n+=1
print (sps,” -“, n)
n=0

#Вывод критериев – оценок задания диагностической работы
global spList
spList=list(values)

print(“spList=”,spList)
#Перевод всех значений в строковый вид, иначе будет ошибка ниже, т.к 1.0 – float. а Х – str
for k in range(len(spList)):
spList[k]=str(spList[k])

#Печать значений в прямой и обратной сортировке
spList.sort(reverse=True)
print (“Список оценок заданий, отсортированный по убыванию – “,spList)
spList.sort(reverse=False)
print (“Список оценок заданий, отсортированный по возрастанию – “,spList)

print (spList[3],type(spList[3]))

#Перезапись в новый файл первой строки шапки, запоминание текущей школы во второй строке
for j in range(p):
ws.write(0,j,s.cell(0,j).value)

#Начало вывода данных в файл и формирование сумм по критериям задания по каждой школе
school1=s.cell(1,1).value #Запоминание школы
stroka_end=0 #Конечная строка в текущей школе
stroka_begin=stroka_end #Начальная строка в текущей школе
stroka_ws=1 #Запоминание текущей строки вывода в выходной файл

for i in range(1,s.nrows): # Исправить на s.nrows
school2=s.cell(i,1).value
if school2==school1:
stroka_end+=1
#stroka_ws+=1

for j in range (p):
ws.write(stroka_ws,j,s.cell(i,j).value)
stroka_ws+=1
else:
#Школа2 не равна Школе1
school1=school2
stroka_ws+=1
stroka_end+=1
for j1 in range (7,p):
n1=n2=n3=n4=0
for i in range(stroka_begin,stroka_end):
value =str(s.cell(i,j1).value)
if value==spList[0]:
n1+=1
if value==spList[1]:
n2+=1
if value==spList[2]:
n3+=1
if value==spList[3]:
n4+=1

ws.write(stroka_ws+1,j1,n1)
ws.write(stroka_ws+2,j1,n2)
ws.write(stroka_ws+3,j1,n3)
ws.write(stroka_ws+4,j1,n4)

ws.write(stroka_ws+1,6,spList[0])
ws.write(stroka_ws+2,6,spList[1])
ws.write(stroka_ws+3,6,spList[2])
ws.write(stroka_ws+4,6,spList[3])
stroka_ws+=6
#Дополнительная корректировка вывода, т.к. иначе теряется первая строка новой школы
for j in range (p):
ws.write(stroka_ws,j,s.cell(i+1,j).value)
stroka_ws+=1
stroka_begin=stroka_end

print(“Школа1=”,school1,” Школа2=”,school2,n1,n2,n3,n4,stroka_begin,stroka_end,stroka_ws)
stroka_ws+=1
ws.write(stroka_ws+1,6,spList[0])
ws.write(stroka_ws+2,6,spList[1])
ws.write(stroka_ws+3,6,spList[2])
ws.write(stroka_ws+4,6,spList[3])

for j1 in range (7,p):
n1=n2=n3=n4=0 #Обнуляем значения
for i in range(stroka_begin,stroka_end):
value =str(s.cell(i,j1).value)
if value==spList[0]:
n1+=1
if value==spList[1]:
n2+=1
if value==spList[2]:
n3+=1
if value==spList[3]:
n4+=1
ws.write(stroka_ws+1,j1,n1)
ws.write(stroka_ws+2,j1,n2)
ws.write(stroka_ws+3,j1,n3)
ws.write(stroka_ws+4,j1,n4)

wbk.save(output_path)

#Выход из программы, если обработка больше не нужна
sys.exit([n])

Рекомендую установить Anaconda3. Среди её модулей есть прекрасное приложение JupiterLab. Это и прекрасный редактор и программная среда, сохраняющая и текст программы и результаты её работы.

Пример созданной в JupiterLab статьи на основе информации из Интернет

Пример подключения файла Excel для получения входных данных для круговой диаграммы

Эти статьи надо скачать и запустить на своём ПК, но можно вставлять непосредственно и на свой сайт.

Эти примеры созданы в JupiterLab и переведены в файлы HTML через File-> Export->HTML

Посмотрите новую заметку по консолидации

Консолидация данных Excel в Питоне