Generowanie raportów z Pandas DataFrame to jeden z najczęstszych scenariuszy w automatyzacji analitycznej. Po wczytaniu, oczyszczeniu i przetworzeniu danych zwykle trzeba zapisać wyniki w formacie, który można łatwo udostępnić, otworzyć w Excelu, wysłać e-mailem, wydrukować albo zarchiwizować.
Python pozwala tworzyć raporty w wielu formatach: CSV, Excel, PDF, JSON czy skompresowane pliki .gz. Do prostych eksportów wystarczy pandas. Do formatowania Excela przyda się openpyxl, a do generowania PDF — reportlab. Jeśli raport ma zawierać wykresy, możesz wykorzystać matplotlib.
W tym artykule zobaczysz, jak generować profesjonalne raporty z Pandas do CSV, Excel i PDF, jak dodać formatowanie, jak kompresować duże pliki oraz jak automatycznie wysyłać gotowe raporty e-mailem.
Kurs Python od podstaw — PyStart
Zacznij programować w Pythonie od zera. Praktyczny kurs wideo z ćwiczeniami — bez wcześniejszego doświadczenia.
- ✓24 lekcje wideo + 80 ćwiczeń
- ✓Realne bazy z e-commerce
- ✓Społeczność i code-review
Kiedy warto automatyzować raporty z Pandas?
Automatyzacja raportów przydaje się wszędzie tam, gdzie dane są przetwarzane cyklicznie. Zamiast ręcznie filtrować arkusze, kopiować tabele i tworzyć pliki wynikowe, możesz przygotować skrypt, który wykona cały proces za Ciebie.
Najczęstsze zastosowania to:
- codzienne raporty sprzedaży,
- tygodniowe zestawienia KPI,
- eksport danych dla działu finansów,
- raporty z kampanii marketingowych,
- raporty z plików CSV i Excel,
- automatyczne podsumowania dla klientów,
- raporty PDF do wysyłki e-mail,
- archiwizacja danych w plikach skompresowanych,
- generowanie wielu raportów dla różnych zespołów.
Największa zaleta jest prosta: raport powstaje zawsze według tych samych zasad, bez ręcznego kopiowania danych i bez przypadkowych zmian w formatowaniu.
Przygotowanie przykładowych danych
Na potrzeby przykładów utworzymy prosty DataFrame z danymi sprzedażowymi.
Python1 2 3 4 5 6 7 8 9 10import pandas as pd df = pd.DataFrame({ "Nazwa": ["Jan", "Anna", "Piotr", "Katarzyna", "Marek"], "Kategoria": ["A", "B", "A", "C", "B"], "Wartość": [100, 200, 150, 300, 250], "Data": pd.date_range("2024-01-01", periods=5) }) print(df)
W prawdziwym projekcie dane mogą pochodzić z Excela, CSV, bazy danych, API albo systemu BI. Sam etap eksportu działa podobnie niezależnie od źródła.
Eksport DataFrame do CSV
CSV to najprostszy i najbardziej uniwersalny format raportu. Można go otworzyć w Excelu, Power BI, Power Query, bazach danych i wielu innych narzędziach.
Podstawowy eksport do CSV:
Python1df.to_csv("raport.csv", index=False)
W polskich warunkach często warto użyć kodowania utf-8-sig, aby Excel poprawnie rozpoznawał polskie znaki.
Python1 2 3 4 5 6df.to_csv( "raport.csv", index=False, encoding="utf-8-sig", sep=";" )
Parametr sep=";" bywa wygodny, gdy odbiorcy otwierają plik w Excelu ustawionym na polskie formaty regionalne.
Eksport CSV z wybranymi kolumnami
Nie zawsze chcesz eksportować cały DataFrame. Czasem raport powinien zawierać tylko wybrane kolumny.
Python1 2 3 4 5 6 7 8selected_columns = ["Nazwa", "Wartość", "Data"] df[selected_columns].to_csv( "raport_wybrane_kolumny.csv", index=False, encoding="utf-8-sig", sep=";" )
To dobre rozwiązanie, gdy dane źródłowe zawierają kolumny techniczne, których odbiorca raportu nie powinien widzieć.
Kompresja raportu CSV
Jeśli raport jest duży, możesz zapisać go w formacie .gz.
Python1 2 3 4 5 6df.to_csv( "raport.csv.gz", index=False, encoding="utf-8", compression="gzip" )
Kompresja przydaje się przy archiwizacji raportów, wysyłce dużych plików lub przechowywaniu dziennych eksportów danych.
Eksport DataFrame do Excela
Excel jest najczęściej wybieranym formatem raportów biznesowych. Pandas pozwala szybko zapisać DataFrame do pliku .xlsx.
Python1df.to_excel("raport.xlsx", index=False)
Jeśli chcesz zapisać kilka tabel do jednego pliku, użyj ExcelWriter.
Python1 2 3 4 5 6 7 8 9summary = ( df.groupby("Kategoria")["Wartość"] .agg(["sum", "mean", "count"]) .reset_index() ) with pd.ExcelWriter("raporty.xlsx", engine="openpyxl") as writer: df.to_excel(writer, sheet_name="Dane", index=False) summary.to_excel(writer, sheet_name="Podsumowanie", index=False)
Taki plik jest wygodny dla odbiorców, bo zawiera zarówno dane szczegółowe, jak i gotowe podsumowanie.
Eksport do Excel z formatowaniem
Python co tydzień — newsletter dla programistów
Otrzymuj codzienne ćwiczenia, ciekawostki z ekosystemu Pythona i wskazówki do rozmów rekrutacyjnych.
Surowy eksport do Excela często jest wystarczający dla systemów, ale nie dla ludzi. Raport powinien mieć czytelne nagłówki, szerokości kolumn, formaty liczbowe i zamrożony pierwszy wiersz.
Python1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43import pandas as pd from openpyxl.styles import Font, PatternFill, Alignment from openpyxl.utils import get_column_letter def export_excel_report(df: pd.DataFrame, output_file: str): """Eksportuje DataFrame do Excela z podstawowym formatowaniem.""" with pd.ExcelWriter(output_file, engine="openpyxl") as writer: df.to_excel(writer, sheet_name="Dane", index=False) workbook = writer.book worksheet = writer.sheets["Dane"] header_fill = PatternFill( start_color="4472C4", end_color="4472C4", fill_type="solid" ) header_font = Font(bold=True, color="FFFFFF") for cell in worksheet[1]: cell.fill = header_fill cell.font = header_font cell.alignment = Alignment(horizontal="center") for column_cells in worksheet.columns: max_length = max( len(str(cell.value)) if cell.value is not None else 0 for cell in column_cells ) column_letter = get_column_letter(column_cells[0].column) worksheet.column_dimensions[column_letter].width = max_length + 3 worksheet.freeze_panes = "A2" for row in worksheet.iter_rows(min_row=2): for cell in row: if isinstance(cell.value, (int, float)): cell.number_format = "#,##0.00" print(f"Raport Excel zapisany: {output_file}") export_excel_report(df, "raport_sformatowany.xlsx")
Taki raport można wysłać bez dodatkowej ręcznej obróbki.
Raport Excel z podsumowaniem
Często raport powinien zawierać nie tylko dane, ale także agregacje: sumy, średnie i liczby rekordów.
Python1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18def create_excel_report_with_summary(df: pd.DataFrame, output_file: str): """Tworzy raport Excel z danymi i podsumowaniem.""" summary = ( df.groupby("Kategoria")["Wartość"] .agg(["sum", "mean", "count"]) .reset_index() ) summary.columns = ["Kategoria", "Suma", "Średnia", "Liczba rekordów"] with pd.ExcelWriter(output_file, engine="openpyxl") as writer: df.to_excel(writer, sheet_name="Dane", index=False) summary.to_excel(writer, sheet_name="Podsumowanie", index=False) print(f"Raport z podsumowaniem zapisany: {output_file}") create_excel_report_with_summary(df, "raport_z_podsumowaniem.xlsx")
To prosty schemat raportu biznesowego: pierwszy arkusz zawiera dane, drugi gotowe wnioski liczbowe.
Generowanie raportu PDF z DataFrame
PDF sprawdza się wtedy, gdy raport ma być wysłany, wydrukowany albo udostępniony w nieedytowalnej formie. Do generowania PDF w Pythonie możesz użyć biblioteki reportlab.
Instalacja:
Bash1pip install reportlab
Przykład raportu PDF z tabelą:
Python1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37from reportlab.lib.pagesizes import letter from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer from reportlab.lib import colors from reportlab.lib.styles import getSampleStyleSheet import pandas as pd def dataframe_to_pdf(df: pd.DataFrame, output_file: str, title: str = "Raport"): """Konwertuje DataFrame do raportu PDF.""" doc = SimpleDocTemplate(output_file, pagesize=letter) elements = [] styles = getSampleStyleSheet() elements.append(Paragraph(title, styles["Title"])) elements.append(Spacer(1, 12)) data = [df.columns.tolist()] + df.astype(str).values.tolist() table = Table(data) table.setStyle(TableStyle([ ("BACKGROUND", (0, 0), (-1, 0), colors.grey), ("TEXTCOLOR", (0, 0), (-1, 0), colors.whitesmoke), ("ALIGN", (0, 0), (-1, -1), "CENTER"), ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"), ("FONTSIZE", (0, 0), (-1, 0), 10), ("BOTTOMPADDING", (0, 0), (-1, 0), 10), ("BACKGROUND", (0, 1), (-1, -1), colors.beige), ("GRID", (0, 0), (-1, -1), 0.5, colors.black), ])) elements.append(table) doc.build(elements) print(f"Raport PDF utworzony: {output_file}") dataframe_to_pdf(df, "raport.pdf", "Miesięczny raport sprzedaży")
Warto pamiętać, że PDF nie jest najlepszym formatem dla bardzo dużych tabel. W takim przypadku lepiej wygenerować Excel lub CSV, a w PDF umieścić tylko podsumowanie.
Raport PDF z wykresem
Do wykresów możesz użyć matplotlib. Najpierw zapisujesz wykres jako obraz, a potem dodajesz go do PDF.
Python1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33import pandas as pd import matplotlib.pyplot as plt from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.pagesizes import letter def pdf_report_with_chart(df: pd.DataFrame, output_file: str): """Tworzy raport PDF z wykresem.""" summary = df.groupby("Kategoria")["Wartość"].sum() chart_path = "wykres.png" summary.plot(kind="bar", title="Suma wartości według kategorii") plt.tight_layout() plt.savefig(chart_path) plt.close() doc = SimpleDocTemplate(output_file, pagesize=letter) styles = getSampleStyleSheet() elements = [ Paragraph("Raport sprzedaży", styles["Title"]), Spacer(1, 12), Paragraph("Poniżej znajduje się wykres sumy wartości według kategorii.", styles["BodyText"]), Spacer(1, 12), Image(chart_path, width=400, height=250) ] doc.build(elements) print(f"Raport PDF z wykresem zapisany: {output_file}") pdf_report_with_chart(df, "raport_z_wykresem.pdf")
To dobry sposób na automatyczne tworzenie raportów dla osób, które potrzebują szybkiego podsumowania zamiast pełnej tabeli danych.
Kompresja raportów do JSON gzip
Python co tydzień — newsletter dla programistów
Otrzymuj codzienne ćwiczenia, ciekawostki z ekosystemu Pythona i wskazówki do rozmów rekrutacyjnych.
Jeśli raport ma być archiwizowany lub przesyłany między systemami, możesz zapisać go jako skompresowany JSON.
Python1 2 3 4 5 6 7 8 9 10 11 12 13 14 15import gzip import json import pandas as pd def compress_report(df: pd.DataFrame, output_file: str): """Kompresuje DataFrame do pliku JSON gzip.""" data = df.to_dict(orient="records") with gzip.open(output_file, "wt", encoding="utf-8") as file: json.dump(data, file, ensure_ascii=False, indent=2) print(f"Raport skompresowany: {output_file}") compress_report(df, "raport.json.gz")
Ten format jest przydatny, gdy dane mają być później odczytane przez aplikację lub proces automatyzacji.
Automatyczna wysyłka raportu e-mailem
Gotowy raport można automatycznie wysłać e-mailem jako załącznik. Dane SMTP najlepiej przechowywać w zmiennych środowiskowych, a nie wpisywać bezpośrednio w kodzie.
Python1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57import os import smtplib from pathlib import Path from email import encoders from email.mime.base import MIMEBase from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart def send_report_email( report_path: str, recipient: str, subject: str = "Automatyczny raport" ): """Wysyła raport e-mailem jako załącznik.""" path = Path(report_path) if not path.exists(): raise FileNotFoundError(f"Nie znaleziono raportu: {report_path}") msg = MIMEMultipart() msg["From"] = os.getenv("SMTP_USER", "raporty@firma.pl") msg["To"] = recipient msg["Subject"] = subject body = "Cześć,\n\nw załączniku znajduje się aktualny raport.\n" msg.attach(MIMEText(body, "plain", "utf-8")) with open(path, "rb") as file: part = MIMEBase("application", "octet-stream") part.set_payload(file.read()) encoders.encode_base64(part) part.add_header( "Content-Disposition", f'attachment; filename="{path.name}"' ) msg.attach(part) smtp_host = os.getenv("SMTP_HOST") smtp_port = int(os.getenv("SMTP_PORT", "587")) smtp_user = os.getenv("SMTP_USER") smtp_password = os.getenv("SMTP_PASSWORD") if not all([smtp_host, smtp_user, smtp_password]): print("Brak konfiguracji SMTP. Pomijam rzeczywistą wysyłkę.") return with smtplib.SMTP(smtp_host, smtp_port) as server: server.starttls() server.login(smtp_user, smtp_password) server.send_message(msg) print(f"Raport wysłany do: {recipient}") send_report_email("raport_sformatowany.xlsx", "uzytkownik@firma.pl")
Taki kod można połączyć z harmonogramem, aby raporty wysyłały się automatycznie o określonej godzinie.
Kompletny pipeline raportowy
Możesz połączyć wszystkie kroki w jeden proces: przygotowanie danych, zapis do CSV, Excel, PDF i wysyłkę.
Python1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20def generate_full_report_pipeline(df: pd.DataFrame): """Tworzy raporty w kilku formatach.""" csv_file = "raport.csv" excel_file = "raport.xlsx" pdf_file = "raport.pdf" df.to_csv(csv_file, index=False, encoding="utf-8-sig", sep=";") export_excel_report(df, excel_file) dataframe_to_pdf(df, pdf_file, "Raport automatyczny") print("Wygenerowano raporty:") print(f"- {csv_file}") print(f"- {excel_file}") print(f"- {pdf_file}") # Opcjonalnie: # send_report_email(excel_file, "uzytkownik@firma.pl") generate_full_report_pipeline(df)
To prosty fundament pod automatyczne raportowanie w firmie. W kolejnym kroku możesz dodać harmonogram, logowanie błędów i zapis raportów do katalogów według daty.
Dobre praktyki generowania raportów z Pandas
Przy automatyzacji raportów warto trzymać się kilku zasad:
- zapisuj raporty z datą w nazwie pliku,
- nie nadpisuj ważnych raportów bez kopii,
- używaj
utf-8-sigdla CSV otwieranych w Excelu, - stosuj
index=False, jeśli indeks DataFrame nie jest potrzebny, - twórz osobne arkusze dla danych i podsumowań,
- formatuj nagłówki w Excelu,
- nie wkładaj bardzo dużych tabel do PDF,
- loguj liczbę zapisanych wierszy,
- sprawdzaj, czy plik został utworzony przed wysyłką,
- przechowuj dane SMTP w zmiennych środowiskowych.
Te praktyki sprawiają, że raporty są bardziej czytelne, bezpieczne i łatwiejsze do utrzymania.
Podsumowanie
Kurs Python dla początkujących — PyStart
Zacznij programować w Pythonie! Idealne dla osób bez doświadczenia. Praktyczne zadania, projekty i wsparcie społeczności.
- ✓24 lekcje wideo + 80 ćwiczeń
- ✓Realne bazy z e-commerce
- ✓Społeczność i code-review
Generowanie raportów z Pandas pozwala zamienić przetworzone dane w gotowe pliki CSV, Excel, PDF lub JSON. CSV najlepiej sprawdza się przy wymianie danych, Excel przy raportach biznesowych, a PDF przy wysyłce, archiwizacji i wydruku.
Do podstawowych eksportów wystarczy pandas. Do formatowania Excela użyj openpyxl, do PDF — reportlab, a do wykresów — matplotlib. Połączenie tych narzędzi pozwala tworzyć raporty, które są nie tylko poprawne technicznie, ale też czytelne dla odbiorców.
Jeśli chcesz zacząć praktycznie, przygotuj jeden DataFrame, zapisz go do CSV, Excela i PDF, a potem dodaj podsumowanie oraz automatyczną wysyłkę e-mail. To dobry fundament pod pełną automatyzację raportowania.
➡️ Następny artykuł
Po opanowaniu generowania raportów naucz się automatyzować harmonogramy zadań:
Harmonogramy zadań w Pythonie: cron, APScheduler, asyncio — automatyczne uruchamianie skryptów o określonych porach, wykorzystanie równoległości i asynchroniczności w automatyzacji.



