Streszczenie
  • Kiedy warto automatyzować raporty z Pandas?
  • Przygotowanie przykładowych danych
  • Eksport DataFrame do CSV
  • Eksport CSV z wybranymi kolumnami
Raporty z Pandas do PDF/CSV/Excel

Raporty z Pandas do PDF, CSV i Excel w Pythonie

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 · 24 lekcje8h 14m
Kurs

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
699 zł
Zacznij kurs Pythona

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.

Python
1 2 3 4 5 6 7 8 9 10 import 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:

Python
1 df.to_csv("raport.csv", index=False)

W polskich warunkach często warto użyć kodowania utf-8-sig, aby Excel poprawnie rozpoznawał polskie znaki.

Python
1 2 3 4 5 6 df.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.

Python
1 2 3 4 5 6 7 8 selected_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.

Python
1 2 3 4 5 6 df.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.

Python
1 df.to_excel("raport.xlsx", index=False)

Jeśli chcesz zapisać kilka tabel do jednego pliku, użyj ExcelWriter.

Python
1 2 3 4 5 6 7 8 9 summary = ( 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

Newsletter · co środę

Python co tydzień — newsletter dla programistów

Otrzymuj codzienne ćwiczenia, ciekawostki z ekosystemu Pythona i wskazówki do rozmów rekrutacyjnych.

2 312 czytelników · ⭐ 4,8

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.

Python
1 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 import 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.

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def 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:

Bash
1 pip install reportlab

Przykład raportu PDF z tabelą:

Python
1 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 from 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.

Python
1 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 import 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

Newsletter · co środę

Python co tydzień — newsletter dla programistów

Otrzymuj codzienne ćwiczenia, ciekawostki z ekosystemu Pythona i wskazówki do rozmów rekrutacyjnych.

2 312 czytelników · ⭐ 4,8

Jeśli raport ma być archiwizowany lub przesyłany między systemami, możesz zapisać go jako skompresowany JSON.

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import 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.

Python
1 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 57 import 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ę.

Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def 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-sig dla 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 · 24 lekcje8h 14m
Kurs

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
699 zł
Rozpocznij naukę

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.

Część 15 z 26

Rozdzielanie i scalanie stron PDF w Pythonie

druga lekcja cyklu „Automatyzacja procesów z n8n — od danych do AI w jednym narzędziu"

Czytaj kolejny →