I file di Excel (.xlsx e, più di rado, il vecchio .xls) sono il formato più comune in cui le aziende inviano i dati: listini prezzi, disponibilità, report, esportazioni dai gestionali. A differenza del CSV, un Excel non è testo semplice ma un documento strutturato: dentro un .xlsx c’è un archivio ZIP con la descrizione XML di fogli, stili e formule. Per questo non si può leggerlo «come righe di testo»: servono librerie che capiscano la struttura interna della cartella di lavoro. L’articolo prosegue la nostra panoramica sul parsing di documenti.
Cosa complica il parsing di Excel
A differenza di un CSV piatto, una cartella di lavoro Excel ha diversi livelli di complessità. Primo, i fogli multipli: i dati possono essere distribuiti su più schede e bisogna scegliere esplicitamente quella giusta. Secondo, le formule: una cella può contenere sia la formula =B2*C2 sia il suo valore calcolato, e quello che ottieni dipende dal modo di lettura. Terzo, le celle unite, per colpa delle quali un’intestazione «pende» sopra più colonne e nei dati compaiono dei vuoti. Quarto, i formati: una data può arrivare non come 2026-06-01 ma come il numero 46184 (il numero seriale con cui Excel memorizza le date), e un prezzo come un numero con il formato valuta salvato a parte. Di tutto questo bisogna tenere conto in fase di estrazione.
Python
Lo strumento di base per gli .xlsx è openpyxl. Dà il controllo completo sulla cartella di lavoro: fogli, celle, celle unite.
from openpyxl import load_workbook
wb = load_workbook("prices.xlsx", data_only=True) # data_only=True → valori al posto delle formule
ws = wb["Listino"] # scegliamo il foglio per nome
for row in ws.iter_rows(min_row=2, values_only=True):
sku, name, price = row[0], row[1], row[2]
print(sku, name, price)Fai attenzione a data_only=True: senza, una cella con formula restituisce il testo della formula e non il risultato. E ricorda che il valore calcolato esiste solo se il file è stato aperto almeno una volta in Excel — openpyxl non calcola le formule da sé.
Quando non serve un’iterazione riga per riga ma un’analisi — filtri, aggregazioni, unione di tabelle — si passa a pandas, che carica il foglio in un DataFrame con una sola riga (sotto il cofano usa openpyxl).
import pandas as pd
df = pd.read_excel("prices.xlsx", sheet_name="Listino")
print(df[df["price"] > 3000])
# se serve, conversione in CSV
df.to_csv("prices.csv", index=False, encoding="utf-8-sig")Per il vecchio formato binario .xls pandas usa un motore a parte, xlrd; i file moderni .xlsx passano per openpyxl.
JavaScript / Node.js
Nell’ecosistema JS lo standard de facto è SheetJS (pacchetto xlsx). Funziona sia in Node sia nel browser, legge quasi tutti i formati di tabella e trasforma comodamente un foglio in un array di oggetti.
const XLSX = require("xlsx");
const wb = XLSX.readFile("prices.xlsx");
const sheet = wb.Sheets[wb.SheetNames[0]]; // primo foglio
const rows = XLSX.utils.sheet_to_json(sheet); // array di oggetti secondo la riga di intestazione
for (const row of rows) {
console.log(row.sku, row.name, row.price);
}Quando oltre a leggere bisogna anche generare cartelle di lavoro complesse con stili, la scelta giusta è ExcelJS.
PHP
La libreria principale è PhpSpreadsheet (l’erede della vecchia PHPExcel). Legge e scrive .xlsx e .xls, capisce formule e formati.
<?php
require "vendor/autoload.php";
use PhpOffice\PhpSpreadsheet\IOFactory;
$spreadsheet = IOFactory::load("prices.xlsx");
$rows = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
foreach (array_slice($rows, 1) as $row) { // saltiamo la riga di intestazione
echo $row["A"] . " — " . $row["B"] . " — " . $row["C"] . "\n";
}Go
In Go lo standard de facto è excelize. Legge i fogli come righe e supporta formule, stili e streaming per i file di grandi dimensioni.
package main
import (
"fmt"
"github.com/xuri/excelize/v2"
)
func main() {
f, err := excelize.OpenFile("prices.xlsx")
if err != nil {
panic(err)
}
defer f.Close()
rows, _ := f.GetRows("Listino")
for _, row := range rows[1:] {
fmt.Println(row[0], row[1], row[2])
}
}Consigli pratici
Prima di scrivere il parser conviene aprire il file con i propri occhi e capirne la struttura: dove iniziano i dati (spesso le prime righe sono occupate da intestazione e logo), se ci sono celle unite nelle intestazioni, su quale foglio stanno i dati che servono. Se l’intestazione non è standard, è più semplice indicare al parser la riga di partenza che provare a indovinarla. Date e numeri conviene normalizzarli subito dopo la lettura — portarli a un formato unico, perché nello stesso file compaiono spesso scritti in modi diversi.
Se le cartelle di lavoro sono omogenee ma con più fogli, celle unite e formule, e arrivano con regolarità, configuriamo un parsing automatico di Excel con esportazione in un database o in CSV per l’elaborazione successiva. Quando invece i report non arrivano in Excel ma impaginati per la stampa, quello è già parsing di PDF — vedi l’articolo dedicato.