HOWTO · Csharp

Scrivi su un file Excel in C#

Possiamo usare l'API di Microsoft Office per scrivere su un file Excel in C#.

In questa pagina

Per scrivere dati in una cartella di lavoro Excel da C#, usa Microsoft Office Interop quando il programma deve automatizzare l’applicazione desktop Excel installata. Interop può creare una cartella di lavoro, compilare le celle e salvare un file .xlsx nativo. Nel computer che esegue il programma deve essere installato Excel. Se Excel non è disponibile nell’ambiente di distribuzione, usa una libreria per fogli di calcolo che scriva direttamente i file delle cartelle di lavoro.

Scegliere l’approccio per scrivere in Excel più adatto all’applicazione

Microsoft Office Interop avvia Excel e comunica con il suo modello a oggetti tramite COM. Sceglilo per l’automazione desktop che dipende da Excel, ad esempio quando serve un comportamento specifico delle cartelle di lavoro. Non è una libreria autonoma per scrivere file: aggiungere un riferimento a Interop al progetto non installa Excel su un altro computer.

Per dati tabellari semplici che non richiedono fogli di lavoro, formule o formattazione, un file CSV è un’alternativa più leggera. Excel può aprire il testo CSV, ma un CSV non è una cartella di lavoro Excel e non può contenere le funzionalità di una cartella di lavoro. Gli esempi seguenti mantengono distinti questi due risultati.

Configurare Microsoft Office Interop in C#

In Visual Studio, aggiungi un riferimento COM alla Microsoft Excel Object Library dalla finestra di dialogo Riferimenti del progetto. La versione della libreria dipende dalla versione di Office installata. Con un riferimento a collegamento anticipato, importa Microsoft.Office.Interop.Excel, ad esempio con using Excel = Microsoft.Office.Interop.Excel;, per distinguere i tipi di Excel da quelli .NET con nomi simili.

L’esempio della cartella di lavoro qui sotto usa il collegamento tardivo tramite il ProgID COM di Excel, quindi non richiede quel namespace nel codice sorgente. Automatizza comunque Excel e, al momento dell’esecuzione, richiede Excel su Windows. Usa il riferimento a collegamento anticipato se vuoi tipi Excel verificati in fase di compilazione e IntelliSense; scegli il collegamento tardivo se la distribuzione controlla la versione di Excel installata e vuoi evitare un riferimento legato a una versione specifica. Il solo riferimento non rende Excel disponibile su un server o su un altro computer.

Creare una cartella di lavoro e scrivere dati nelle celle

Questo esempio con Interop avvia Excel, aggiunge una cartella di lavoro, scrive un’intestazione e due righe di dati e salva un file .xlsx nativo nella directory temporanea del sistema. Il valore di formato 51 corrisponde al formato file xlOpenXMLWorkbook di Excel. Un GUID rende univoco il nome del file di output a ogni esecuzione, così l’istanza nascosta di Excel non resta in attesa di una richiesta di conferma per sovrascrivere il file. Il codice è pensato per Windows con Excel desktop installato; non è accompagnato da un output di esecuzione. Le eventuali etichette visibili nell’esempio restano in inglese, poiché i blocchi di codice sono mantenuti identici byte per byte.

using System;
using System.IO;
using System.Runtime.InteropServices;

class Program
{
    static void Main()
    {
        if (Environment.OSVersion.Platform != PlatformID.Win32NT)
        {
            Console.WriteLine("This example requires Windows with Excel installed.");
            return;
        }

        object excelApp = null;
        object workbooks = null;
        object workbook = null;
        object worksheets = null;
        object worksheet = null;
        object cells = null;

        try
        {
            Type excelType = Type.GetTypeFromProgID("Excel.Application");
            if (excelType == null)
            {
                Console.WriteLine("Excel is not registered on this computer.");
                return;
            }

            dynamic app = Activator.CreateInstance(excelType);
            excelApp = app;
            app.Visible = false;
            workbooks = app.Workbooks;
            dynamic books = workbooks;
            workbook = books.Add();
            dynamic book = workbook;
            worksheets = book.Worksheets;
            dynamic sheets = worksheets;
            worksheet = sheets[1];
            dynamic sheet = worksheet;

            cells = sheet.Range["A1:B3"];
            dynamic dataRange = cells;
            object[,] values =
            {
                { "Name", "Age" },
                { "Ava", 28 },
                { "Liam", 31 }
            };
            dataRange.Value2 = values;

            string fileName = "example-" + Guid.NewGuid().ToString("N") + ".xlsx";
            string path = Path.Combine(Path.GetTempPath(), fileName);
            book.SaveAs(path, 51);
            Console.WriteLine("Saved " + Path.GetFileName(path));
        }
        catch (Exception ex)
        {
            Console.WriteLine("Excel operation failed: " + ex.Message);
        }
        finally
        {
            CloseWorkbook(workbook);
            ReleaseComObject(cells);
            ReleaseComObject(worksheet);
            ReleaseComObject(worksheets);
            ReleaseComObject(workbook);
            ReleaseComObject(workbooks);
            QuitExcel(excelApp);
            ReleaseComObject(excelApp);
        }
    }

    static void CloseWorkbook(object value)
    {
        if (value == null) return;
        try { ((dynamic)value).Close(false); }
        catch { }
    }

    static void QuitExcel(object value)
    {
        if (value == null) return;
        try { ((dynamic)value).Quit(); }
        catch { }
    }

    static void ReleaseComObject(object value)
    {
        if (value == null) return;
        try
        {
            if (Marshal.IsComObject(value)) Marshal.FinalReleaseComObject(value);
        }
        catch { }
    }
}

Per dati tabellari semplici, un esempio CSV separato scrive testo delimitato da virgole che Excel può aprire. Non crea una cartella di lavoro e non supporta più fogli, formule o formattazione. I valori di esempio non richiedono virgolette CSV; quando scrivi testo arbitrario, racchiudi tra virgolette i campi che contengono virgole, virgolette o interruzioni di riga e raddoppia le virgolette incorporate.

Esegui questo esempio:

using System;
using System.IO;

class Program
{
    static void Main()
    {
        string path = "example.csv";
        string contents = "Name,Age\nJohn Doe,30\n";
        File.WriteAllText(path, contents);
        Console.WriteLine("Wrote " + path);
    }
}
Wrote example.csv

Scrivere in un file Excel esistente

Apri la cartella di lavoro specificandone il percorso completo, conserva l’intervallo selezionato come riferimento COM e rilascialo durante la pulizia. Save aggiorna sul posto il file aperto; usa SaveAs se vuoi salvare con un nuovo percorso o creare una copia. Sostituisci il percorso di esempio con quello della cartella di lavoro che vuoi modificare. Questo esempio per Excel desktop su Windows non è accompagnato da un output di esecuzione.
Il codice e le etichette o gli output visibili in questa sezione restano in inglese.

using System;
using System.IO;
using System.Runtime.InteropServices;

class Program
{
    static void Main()
    {
        if (Environment.OSVersion.Platform != PlatformID.Win32NT)
        {
            Console.WriteLine("This example requires Windows with Excel installed.");
            return;
        }

        object excelApp = null;
        object workbooks = null;
        object workbook = null;
        object worksheets = null;
        object worksheet = null;
        object cells = null;
        string path = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
            "report.xlsx");

        try
        {
            if (!File.Exists(path))
                throw new FileNotFoundException("Workbook not found; update the sample path.", path);

            Type excelType = Type.GetTypeFromProgID("Excel.Application");
            if (excelType == null)
                throw new InvalidOperationException("Excel is not registered on this computer.");

            dynamic app = Activator.CreateInstance(excelType);
            excelApp = app;
            app.Visible = false;
            workbooks = app.Workbooks;
            dynamic books = workbooks;
            workbook = books.Open(path);
            dynamic book = workbook;
            worksheets = book.Worksheets;
            dynamic sheets = worksheets;
            worksheet = sheets[1];
            dynamic sheet = worksheet;
            cells = sheet.Range["B2:C2"];
            dynamic selectedCells = cells;
            selectedCells.Value2 = new object[,] { { "Reviewed", DateTime.Today.ToString("yyyy-MM-dd") } };
            book.Save();
            Console.WriteLine("Updated " + Path.GetFileName(path));
        }
        catch (Exception ex)
        {
            Console.WriteLine("Excel operation failed: " + ex.Message);
        }
        finally
        {
            CloseWorkbook(workbook);
            ReleaseComObject(cells);
            ReleaseComObject(worksheet);
            ReleaseComObject(worksheets);
            ReleaseComObject(workbook);
            ReleaseComObject(workbooks);
            QuitExcel(excelApp);
            ReleaseComObject(excelApp);
        }
    }

    static void CloseWorkbook(object value)
    {
        if (value == null) return;
        try { ((dynamic)value).Close(false); }
        catch { }
    }

    static void QuitExcel(object value)
    {
        if (value == null) return;
        try { ((dynamic)value).Quit(); }
        catch { }
    }

    static void ReleaseComObject(object value)
    {
        if (value == null) return;
        try
        {
            if (Marshal.IsComObject(value)) Marshal.FinalReleaseComObject(value);
        }
        catch { }
    }
}

Se la sorgente è un CSV, usa l’I/O su file e riscrivi le righe: il CSV non dispone di un modello a oggetti per fogli di lavoro o celle.

Chiudere Excel e gestire gli errori

Le operazioni sui file possono non riuscire se un percorso non è disponibile o se la destinazione non consente la scrittura. Anche Interop può generare errori durante l’avvio di Excel, l’apertura di una cartella di lavoro, la scrittura in una cella o il salvataggio, ad esempio quando la cartella di lavoro è in uso. Intercetta gli errori nei punti in cui l’applicazione può mostrare o registrare un messaggio utile. Inserisci la chiusura della cartella di lavoro, Quit e il rilascio dei riferimenti COM in finally: intercettare un errore, da solo, non ripulisce Excel. L’esempio protegge ogni operazione di pulizia, così un errore durante la chiusura non impedisce i successivi tentativi di pulizia.

Limita la durata dell’istanza Excel all’operazione ed evita di conservare riferimenti COM aggiuntivi, ad esempio oggetti Range non tracciati. Quando adatti l’esempio, modifica il percorso temporaneo di output scegliendo la destinazione desiderata. Per applicare la formattazione, imposta le proprietà dell’intervallo del foglio di lavoro interessato dopo aver scritto i valori; l’output CSV non può conservare tale formattazione. Se usato in un’applicazione, anche l’esempio CSV richiede la gestione degli errori di I/O su file.