Automazione Excel con Python: Tutorial Pratico per Dashboard Finanziarie

Cerca:

Generic selectors
Exact matches only
Search in title
Search in content
Post Type Selectors
L'Anima di Python nel Corpo di Excel

Hai presente quel file Excel? Quello che pesa ormai troppo, pieno di celle colorate a mano, con formule lunghe tre righe che se ne tocchi una per sbaglio esplode tutto il report mensile? Ecco. È il momento di lasciarselo alle spalle.

Non siamo qui per dire che Excel è morto; è ancora il re dei fogli di calcolo. Ma usarlo come database, motore di calcolo e strumento di presentazione tutto insieme è il modo migliore per impazzire. Oggi vediamo come delegare la parte noiosa del lavoro “sporco” a Python.

L’obiettivo non è farti diventare un programmatore puro, ma un analista “aumentato”: qualcuno che lancia uno script e in due secondi ottiene quello che i colleghi fanno in tre ore di copia-incolla. Costruiremo un sistema che prende dati grezzi, li pulisce e  restituisce un report finanziario elegante, pronto per essere inviato al manager.

Partiremo dalla generazione di dati sintetici (per simulare un ambiente aziendale reale) e arriveremo a un file Excel formattato, pronto per essere presentato.

Pubblicità

Preparazione dell’Ambiente: Generazione dei Dati

Il primo passo è creare il nostro database di test. Utilizziamo pandas per la struttura e numpy per simulare la stagionalità delle vendite e la casualità delle spese.

import pandas as pd
import numpy as np
from datetime import datetime

np.random.seed(1122)

# Crea dati per 12 mesi
mesi = ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno',
        'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre']

# --- FOGLIO VENDITE ---
# Vendite con stagionalità
vendite_base = [120000, 115000, 130000, 125000, 140000, 135000,
                150000, 145000, 160000, 155000, 170000, 165000]

# Aggiungi variazioni casuali
vendite_importo = [base * np.random.uniform(0.9, 1.1) for base in vendite_base]
vendite_importo = [round(x, 2) for x in vendite_importo]

df_vendite = pd.DataFrame({
    'Mese': mesi,
    'Importo': vendite_importo,
    'Clienti_Attivi': np.random.randint(150, 250, 12),
    'Nuovi_Clienti': np.random.randint(10, 30, 12)
})

# --- FOGLIO SPESE ---
# Spese per categoria
categorie_spese = ['Personale', 'Affitto', 'Utilità', 'Marketing', 'IT', 'Varie']
spese_mensili = []

for mese in mesi:
    spese_mese = []
    for cat in categorie_spese:
        if cat == 'Personale':
            base = 60000
        elif cat == 'Affitto':
            base = 12000
        elif cat == 'Marketing':
            base = np.random.randint(8000, 15000)
        elif cat == 'IT':
            base = np.random.randint(3000, 7000)
        else:
            base = np.random.randint(1000, 5000)
        
        # Variazione mensile
        spese_mese.append(base * np.random.uniform(0.95, 1.05))
    
    spese_mensili.append(spese_mese)

df_spese = pd.DataFrame(spese_mensili, columns=categorie_spese)
df_spese['Mese'] = mesi
df_spese['Importo'] = df_spese[categorie_spese].sum(axis=1).round(2)

# Riordina colonne
df_spese = df_spese[['Mese', 'Importo'] + categorie_spese]

# --- FOGLIO PERSONALE ---
# Dipendenti con dettagli
dipendenti = ['Mario Rossi', 'Luigi Bianchi', 'Giulia Verdi', 'Anna Neri', 
              'Paolo Gialli', 'Laura Blu', 'Marco Viola', 'Sara Rosa']

stipendi_base = [45000, 42000, 38000, 35000, 32000, 30000, 28000, 26000]
mansioni = ['Dirigente', 'Manager', 'Sviluppatore Senior', 'Sviluppatore', 
            'Marketing', 'Vendite', 'Amministrazione', 'Supporto']

# Crea dati mensili per personale
dati_personale = []
for mese in mesi:
    for i, (nome, stipendio, mansione) in enumerate(zip(dipendenti, stipendi_base, mansioni)):
        # Aggiungi bonus occasionali
        stipendio_mensile = stipendio / 12
        if np.random.random() < 0.2:  # 20% probabilità bonus
            stipendio_mensile *= 1.1
        
        dati_personale.append({
            'Mese': mese,
            'Dipendente': nome,
            'Mansione': mansione,
            'Stipendio_Mensile': round(stipendio_mensile, 2),
            'Ore_Lavorate': np.random.randint(140, 180)
        })

df_personale = pd.DataFrame(dati_personale)
# Somma per mese per il foglio principale
df_personale_tot = df_personale.groupby('Mese')['Stipendio_Mensile'].sum().reset_index()
df_personale_tot.columns = ['Mese', 'Importo']

# --- SALVA TUTTI I FOGLI ---
with pd.ExcelWriter('azienda_dati.xlsx', engine='openpyxl') as writer:
    # Fogli principali per l'esercizio
    df_vendite.to_excel(writer, sheet_name='Vendite', index=False)
    df_spese.to_excel(writer, sheet_name='Spese', index=False)
    df_personale_tot.to_excel(writer, sheet_name='Personale', index=False)
    
    # Fogli aggiuntivi per dati dettagliati
    df_personale.to_excel(writer, sheet_name='Dettaglio_Personale', index=False)
    
    # Foglio di configurazione/metadati
    metadati = {
        'Anno': [2024, 2024, 2024],
        'Report_Generato': [datetime.now().strftime("%Y-%m-%d %H:%M:%S")] * 3,
        'Versione': ['1.0', '1.0', '1.0'],
        'Note': ['Dati di vendita', 'Dati di spesa', 'Dati personale']
    }
    pd.DataFrame(metadati).to_excel(writer, sheet_name='Metadati', index=False)

print("File 'azienda_dati.xlsx' creato con successo!")
print("Contiene 5 fogli: Vendite, Spese, Personale, Dettaglio_Personale, Metadati")
print(f"Vendite totali: €{df_vendite['Importo'].sum():,.2f}")
print(f"Spese totali: €{df_spese['Importo'].sum():,.2f}")

Spiegazione

Crea 3 fogli principali

Forse potrebbe interessarti anche:  Platypus: Guida Completa all'Ottimizzazione Multi-Obiettivo in Python con Algoritmi Evolutivi

Foglio “Vendite”

  • Genera vendite mensili con stagionalità crescente verso fine anno

  • Aggiunge una variazione casuale del ±10% per simulare fluttuazioni

  • Include metriche aggiuntive:

    • Clienti_Attivi: tra 150-250 clienti/mese

    • Nuovi_Clienti: tra 10-30 nuovi clienti/mese

Foglio “Spese”

  • Crea spese per 6 categorie: Personale, Affitto, Utilità, Marketing, IT, Varie

  • Ogni categoria ha un valore base realistico

  • Aggiunge variazioni casuali del ±5% mensili

  • Calcola il totale mensile delle spese

Foglio “Personale”

  • Simula 8 dipendenti con nomi, mansioni e stipendi diversi

  • Calcola stipendio mensile (annuale/12)

  • Aggiunge occasionali bonus del 10% (20% di probabilità)

  • Tiene traccia delle ore lavorate (140-180 ore/mese)

  • Crea sia una versione aggregata mensile che una dettagliata

Fogli aggiuntivi

  • Dettaglio_Personale: dati completi per ogni dipendente ogni mese

  • Metadati: informazioni sul report (anno, data generazione, versione, note)

Output finale

Salva tutto in un file Excel chiamato azienda_dati.xlsx con 5 fogli separati.

 A questo punto abbiamo un file Excel che, pur essendo generato automaticamente, riproduce la complessità di un vero ambiente aziendale.
La fase successiva non riguarda più la generazione dei dati, ma la loro interpretazione.

Il “Cervello”: Elaborazione e Normalizzazione

Questa è la fase più critica del processo. Il codice deve essere in grado di interpretare i fogli di calcolo e comprenderne la struttura semantica in modo autonomo, senza necessità di configurazioni manuali ripetitive.

Il progetto completo, organizzato per moduli e sezioni, è disponibile qui:

👉Dashboard_Aziendale_Python_Codice_Completo


1. Pulizia Dinamica delle Colonne

Utilizziamo le Regex (Espressioni Regolari) e le funzioni di manipolazione delle stringhe per normalizzare i nomi delle colonne. Ad esempio, se un utente inserisce “Mese ” (con uno spazio finale), il sistema lo correggerà automaticamente in “mese”.

# Normalizzazione: minuscolo, rimuovi spazi e caratteri speciali
df_foglio.columns = (
    df_foglio.columns
    .astype(str)
    .str.lower()
    .str.replace(' ', '_', regex=False)
    .str.replace(r'[^\w_]', '', regex=True) 
)

2. Unione dei Dati (Merge)

Invece di una semplice concatenazione, utilizziamo una merge di tipo “outer”. Questa scelta è strategica: se in un determinato mese non sono state registrate vendite ma sono presenti delle spese, vogliamo che quel mese appaia comunque nel report finale per garantire l’integrità del bilancio.

Forse potrebbe interessarti anche:  Prompt Engineering per AI Generativa

3. Calcolo del Profitto e dei Margini

Implementiamo una logica basata su keyword per distinguere i flussi in entrata (Ricavi) da quelli in uscita (Costi). Una volta mappati i dati, applichiamo le formule finanziarie standard:

[math]\displaystyle \text{Profitto} = \sum \text{Ricavi} – \sum \text{Costi}[/math]

[math]\displaystyle \text{Margine %} = \left( \frac{\text{Profitto}}{\text{Ricavi}} \right) \cdot 100[/math]

4. Visualizzazione: Il Grafico Ibrido

Per la dashboard non utilizziamo un grafico standard, ma un sistema a doppio asse Y per gestire ordini di grandezza differenti:

  • Asse Primario (Barre): Per visualizzare i volumi monetari di Ricavi e Costi.
  • Asse Secondario (Linea): Per monitorare il trend del profitto.
fig, ax1 = plt.subplots(figsize=(12, 7))

# Barre per i volumi
ax1.bar(x, ricavi, color='green', alpha=0.7, label='Ricavi')
ax1.bar(x + width, costi, color='red', alpha=0.7, label='Costi')

# Linea per il profitto (asse gemello)
ax2 = ax1.twinx()
ax2.plot(x, profitto, 'b-^', linewidth=3, label='Profitto')

5. Crafting dell’Excel: Estetica e Funzionalità

Grazie alla libreria openpyxl, il documento finale non è un semplice dump di dati, ma un report professionale:

  • Formattazione Condizionale: Se il profitto è negativo, la cella viene evidenziata in rosso automaticamente.
  • Ancoraggio Immagini: Il grafico generato in Matplotlib viene inserito dinamicamente in una cella specifica (es. A{riga}).
  • Stili di Cella: Applicazione di bordi, font grassetti per le intestazioni e totalizzatori annuali.

🏁 Il Risultato Finale

Eseguendo lo script, il sistema genererà un file denominato azienda_dashboard.xlsx contenente:

  1. Un foglio Dashboard con i dati unificati e puliti.
  2. Totalizzatori annuali a fondo pagina.
  3. Un Grafico ad alta risoluzione integrato nel foglio Excel.
  4. Un riepilogo testuale nel terminale con l’indicazione del miglior e peggior mese dell’anno.

🛠️ Il Tuo Toolkit

Per questo progetto abbiamo utilizzato la “Trinità” della data automation in Python:

  • Pandas: Per la manipolazione e pulizia dei dati.

  • Matplotlib: Per la creazione del motore grafico.

  • Openpyxl: Per “scrivere” fisicamente dentro Excel, gestendo stili, colori e immagini.

Forse potrebbe interessarti anche:  Massima Verosimiglianza e Inferenza Bayesiana: Guida Pratica con Esercizi Svolti

Formattazione Professionale con Openpyxl

L’output non è un semplice dump di dati. Utilizziamo openpyxl per trasformare un foglio bianco in un report pronto per una riunione direzionale:

Funzionalità Descrizione
Styling Titoli Font grandi, grassetto e sfondo blu navy.
Formattazione Valuta Numeri formattati automaticamente con il simbolo € e separatore delle migliaia.
Highlighting Condizionale Celle dei profitti in Verde se positive, in Rosso se negative.
Inserimento Immagini Il grafico generato viene ancorato esattamente sotto la tabella dei totali.

Conclusione

Grazie a questo flusso, quello che prima richiedeva 30 minuti di lavoro manuale ora viene eseguito in meno di 2 secondi. Hai creato un sistema che non solo calcola dati, ma li interpreta e li presenta.

👉 Ultimo passo: inviare automaticamente il report via email

Articoli di approfondimento

👉 Excel + Python: un’accoppiata vincente

👉 Python e Excel: automatizzare analisi dati in 10 minuti (case study)

👉 Excel e Python per l’analisi dati: guida completa

👉 Excel e Python: perché l’integrazione è il futuro della data analysis

👉 Cos’è il Risolutore di Excel?

👉 Power BI & Python: analisi dati avanzata e machine learning

👉Ottimizza vendite & marketing: probabilità e break-even con Excel + Python

👉Python ed Excel: Guida Pratica all’Automazione con Pandas e OpenPyXL (Esercizi Reali)

Pubblicità