Blog

Python i Excel. Odsłona pierwsza.

Wprowadzenie do Openpyxl, czyli modułu Pythona, który pozwala manipulować obiektami w Excelu.

Python i Excel. Odsłona pierwsza.

Dzisiejszy wpis w pierwszym rzędzie ma za zadanie zatrzeć wrażenie, że kilka lat temu zaszła jakaś niespotykana rewolucja i obecnie można zaprządz do Excela “bardziej poważane” języki niż Visual Basic for Application, który od lat należy do najbardziej znienawidzonych dialektów programistycznych. Owszem Microsoft udostępnił AP do swojego pakietu biurowego, a nawet przygotował stosowną bibliotekę dla Javascript, ale już wcześniej społeczności skupione wokół różnych języków zdążyły przygotować stosowne narzędzia. Będąc zupełnie szczerym to ostatnie zdanie to bardziej moje założenia niż stwierdzenie faktu oparte na pogłębionej wiedzy, więc uściślę: z całą pewnością w Pythonie mamy do czynienia z taką sytuacją.

Pisząc ostatnie wpis przypomniałem sobie, że z okazji inauguracji moich studiów podyplomowych dostałem w prezencie książkę autorstwa Naomi Ceder, poświęconą Pythonowi właśnie. Nieduża część jednego z rozdziałów była poświęcona korzystaniu z arkuszy kalkulacyjnych przy pomocy tego języka. Sama książka dla osób początkujących jest całkiem znośna, choć trochę za mało tam ćwiczeń praktycznych, natomiast o współpracy Pythona z Excelem było naprawdę niewiele, choć jakiś punkt zaczepienia tym sposobem już miałem. Ponieważ autorka omawia tam bibliotekę Openpyxl, ale przedstawia absolutne minimum, zacząłem szukać pomocy w Internetach, a przy okazji jakiegoś ciekawego pomysłu.

Niestety poszukiwania te okazały się mało pomocne, o czym za chwilę, bo w tym momencie chciałbym zwrócić uwagę na jedną kwestię, która rzuciła mi się w oczy w trakcie przeglądania Internetów. Otóż w przypadku zapytań użytkowników różnych portali dotyczących tego, jak rozwiązać problem X związany z arkuszem kalkulacyjnym, wcześniej czy później pojawiała propozycja, by wykorzystać bibliotekę pandas. Nie chcę w tym miejscu powiedzieć, że te sugestie były błędne, bo zazwyczaj dość dobrze adresowały rozwiązanie danego problemu. Tym niemniej jeśli ktoś myśli w pierwszym rzędzie o automatyzacji zadań w Excelu na wzór tego, co robi on sam lub jego koledzy i koleżanki w VBA, to powinien omijać takie propozycje szerokim łukiem, a przynajmniej na samym początku przygody z Pythonem z dwóch powodów. Po pierwsze, biblioteka pandas wymaga zrozumienia struktury danych, z którą mamy do czynienia w jej przypadku. Choć tablice wielowymiarowe oferowane przez pandas (ndarray) na pierwszy rzut oka mogą przypominać zagnieżdżone listy, to jednak praca z nimi odbiega od tego, co znany w przypadku wbudowanych (standardowych) obiektów Pythona. Więc na samym początku trzeba będzie się z tym oswoić i nauczyć jak efektywnie korzystać z tych tablic, co wymaga trochę wysiłku, a poza tym odciąga początkującego od opanowania standardowych rozwiązań Pythona w rodzaju listy czy słownika.

Wspomniane wyżej zastrzeżenie nie jest jakoś szalenie istotne i ma bardziej charakter – powiedzmy – dydaktyczny. Moje dalece poważniejsze zastrzeżenie dotyczy tego, że tak naprawdę w tym wypadku nie pracujemy ze skoroszytem Excela, tylko wykorzystujemy dane tam zawarte. Tym samym choć pandas oferują możliwość bardzo prostego załadowania pliku xls czy xlxs, to tak naprawdę cała interakcja z Excelem do tego się sprowadza w tym scenariuszu. Biblioteka ta nie ma tak naprawdę do zaoferowania niczego w zakresie pracy z innymi “obiektami” arkusza kalkulacyjnego niż dane właśnie, choć to nie może dziwić, bo w sumie nie do tego ma ona służyć. Tymczasem taki Openpyxl oferuje całe mnóstwo metod, które pozwalają chociażby manipulować przy tabelach przestawnych, majstrować z formatowaniem czy też tworzyć wykresy.  Innymi słowy: pozwala pracować z arkuszem kalkulacyjnych na zasadach znanych każdemu użytkownikowi.

To napisawszy wracam do wątku niezbyt owocnych poszukiwań pomysłów na praktyczne ćwiczenie, które mógłbym na łamach mojego bloga zaprezentować. Niestety w ostatnich latach korzystam z Excela w bardzo ograniczonym zakresie, co powinno się jednak niedługo zmienić, głównie jako nośnika danych już przetworzonych, chociażby w ramach skryptu SQL. W związku z tym potrzebowałem silnej inspiracji, by zaprezentować jakiś praktyczny przykład pokazujący faktyczne zalety takie rozwiązania. Niestety w tym przypadku Internety okazały się mało przydatne albo ja nieumiejętnie szukałem. Większość napotkanych przeze mnie wprowadzeń czy tutoriali przedstawia rozwiązania tak banalne lub wydumane, że nie w rzeczywistości nie ma z nich żadnego pożytku, bo to samo nierzadko szybciej i łatwiej wykonać w arkuszu kalkulacyjnym przy użyciu niezbyt wyszukanej formuły. Najczęściej jest to powielanie dokumentacji w jakimś wąskim zakresie, a co gorsza te przykładowe “skrypty” czy ćwiczenie są powielna na kolejnych blogach oraz stronach, czyli mamy do czynienia z sytuacją “kopiuj/wklej”, czyli tym czego na tym blogu staram się unikać w miarę możliwości.

Niestety w efekcie dzisiejszy wpis również będzie tylko krótką zajawką biblioteki Openpyxl, gdzie po prostu spróbuję zaprezentować jak wczytać skoroszyt, uzyskać dostęp do poszczególnych arkuszy oraz odczytać zawartość poszczególnych komórek oraz ewentualnie nadpisać jakieś wartości.

Moduł Openpyxl nie jest częścią biblioteki standardowej, więc przed rozpoczęciem pracy należy go uprzednio zainstalować przy pomocy polecenia: pip install openpyxl. Ja korzystam z wersji 3.0.7, co może być dość istotne dla wykonania ćwiczenia z niniejszego tekstu, ponieważ z tego co się zorientowałem pewne dość popularne metody (get_sheet_by_name na ten przykład) w 3 wersji zostały porzucone.  W drugiej kolejności umieścić plik z interesującym nas arkuszem kalkulacyjnym w katalogu roboczym dla naszego skryptu. Oczywiście to ostatnie nie jest koniecznie, ale przynajmniej na etapie ćwiczeń unikniemy konieczności precyzyjnego wskazywania ścieżki dostępu.

Ja na potrzeby dzisiejszego ćwiczenia przygotowałem skoroszyt zawierający trzy arkusze o nazwch “Pierwszy”, “Drugi” oraz – a jakże – “Trzeci”. W ostatnim z nich umieściłem zaś niewielką tabelką, którą można podziwiać niżej.

ImięMiejsce zamieszkaniaPrzegieg w latachZapoznany
MarysiaSierociniec152021-04-19
KrzyśStumilowy Las122021-04-01
MikołajekGdzieś we Francji102021-04-10

Skoro już wszystko gotowe, to tworzymy skrypt pythona (o dowolnej nazwie), w którym na początku załadujemy moduł Openpyxl. Następnie przy jego pomocy wczytamy nasz skoroszyt i ten nowo utworzony obiekt przypiszemy od razu do zmiennej ws (jak workbook). Całość powinna wyglądać tak (Znajomi.xlsx to nazwa, którą nadałem plikowi z moim skoroszytem):

import openpyxl
 
wb = openpyxl.load_workbook('Znajomi.xlsx')

Przy pomocy w ten sposób utworzonego obiektu będziemy mogli dokonywać różnych zabiegów na interesującym nas pliku. Na samym początku możemy sprawdzić, jakie arkusze są w nim zawarte (metoda sheetnames), dzięki której otrzymamy stosowną listę. Przy okazji zweryfikować możemy arkusz, który w tym wypadku jest aktywny (metoda active). 

print(wb.sheetnames)
print(wb.active)

Powiedzmy jednak, że doskonale wiemy, który z arkuszy nas interesuje i co by rozpocząć z nim pracę, chcemy przypisać do zmiennej ws (jak worksheet). Jeśli jest to arkusz aktywny to rzecz jasna możemy użyć metody active, ale równie dobrze w tym przypadku możemy wskazać ten konkretnie nas interesujący i do tego należy skorzystać z notacja z nawiasami kwadratowymi. Akurat w moim przypadku oba wyniki będa tożsame, ale podaję oba warianty.

ws = wb['Trzeci']
ws2 = wb.active
 
print(ws)
print(ws2)

Gdy już mamy dostęp do obiektu odpowiadającemu naszemu arkuszowi, w tym momencie możemy wreszcie realizować planowane zadania, czyli chociażby wyszukiwać i pobierać interesujące wartości, wstawiać odpowiednie formuły, majstrować przy stylach, czyli z grubsza robić to, co udostępnia aplikacja użytkownikowi. Tym jednak bardziej szczegółowo zajmiemy się w kolejnym wpisie i mam nadzieję, że do tego czasu uda mi się wymyślić lub chociaż skopiować czyjś pomysł na jakieś fajne ćwiczenie, które pokaże chociaż część możliwości tego pakietu.