Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

C# - Lavorare con Excel

C#

Introduzione

  • Per poter lavorare con in file Excel, occorre eseguire un paio di passi.
  • Il primo è l'aggiunta del riferimento a Excel, il secondo la definizione del namespace.
  • Primo passo, aggiungere tra i riferimenti del progetto "Microsoft.Office.Interop.Excel".
  • Per fare questo:
    • Nell'Esplora Soluzioni, click destro su "Riferimenti".
    • Click su "Aggiungi Riferimento...".
    • Selezionare sulla colonna a sinistra il tab "Estensioni".
    • Selezionare nella lista principale "Microsoft.Office.Interop.Excel".
    • Salvare e chiudere la finestra.
  • Secondo passo, definire il namaspace.
  • Per fare questo, nella sezione degli 'using', aggiungere la seguente riga:

   using Excel = Microsoft.Office.Interop.Excel;

  • Si noti l'utilizzo dell'alias 'Excel', utile per rendere il codice più leggibile nelle righe seguenti.

Gli oggetti principali

  • Ecco gli oggetti con i quali interagire per creare o modificare file Excel.
  • Tutti gli oggetti appartengono alla classe "Microsoft.Office.Interop.Excel" che negli esempi seguenti viene abbreviata dall'alias Excel (si veda l'utlizzo dello 'using' nel paragrafo precedente).
  • Excel.Application: è l'applicazione Excel stessa.
  • Excel.Workbook: è l'insieme dei fogli (sheets) di Excel.
  • Excel.Worksheet: è un foglio (sheet) di Excel.
  • Excel.Range: è un generico range di celle di Excel.

Creazione di un file
  • In questo esempio si mostra come creare un file Excel, scrivere un paio di stringhe sulle prime due celle e infine salvarlo.

   Excel.Application xApp;
   Excel.Workbook xWb;
   Excel.Worksheet xWs;
   Excel.Range xRange;
   object misValue = System.Reflection.Missing.Value;

   // Avvia Excel.
   xApp = new Excel.Application();
   xApp.Visible = true;

   // Crea un Workbook.
   xApp.SheetsInNewWorkbook = 1;
   xWb = (Excel.Workbook)(xApp.Workbooks.Add(misValue));

   // Crea un Worksheet.
   xWs = (Excel.Worksheet)xWb.ActiveSheet;
  xWs.Name = "Nuovo";
 
   // Aggiunge dati a due celle.
   xWs.Cells[1, 1] = "Hello";
   xWs.Cells[1, 2] = "World";

   // Salva il file.
   xApp.Visible = false;
   xApp.UserControl = false;
   xWb.SaveAs("c:\\temp\\test01.xlsx", Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing,
       false, false, Excel.XlSaveAsAccessMode.xlNoChange,
       Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

   // Chiude il Workbook e l'Application.
   xWb.Close();
   xApp.Quit();

  • Si noti l'utilizzo della proprietà 'SheetsInNewWorkbook', che permette di impostare il numero di fogli da creare non appena si crea un nuovo Workbook. Questo valore deve essere compreso tra 1 e 255.
  • Con la proprietà 'Name' del Worksheet, si assegna il nome allo Sheet attivo.
  • Nelle righe seguenti si mostra come aggiungere tre Sheets ed assegnargli i nomi.

   // Crea un Workbook.
   xApp.SheetsInNewWorkbook = 3;
   xWb = (Excel.Workbook)(xApp.Workbooks.Add(misValue));

   // Assegna il nome agli Sheets.
   ((Excel.Worksheet)xWb.Sheets[1]).Name = "--1--";
   ((Excel.Worksheet)xWb.Sheets[2]).Name = "--2--";
   ((Excel.Worksheet)xWb.Sheets[3]).Name = "--3--";

  • Un solo Sheet è in primo piano: è lo Sheet attivo.
  • Con l'istruzione seguente si attiva lo Sheet voluto.

   // Rende attivo il secondo Sheet.
   ((Excel.Worksheet)xWb.Sheets[2]).Select(Type.Missing);

Apertura di un file esistente
  • L'apertura e quindi la modifica di un file esistente è possibile modificando la crezione dell'oggetto Workbook.
  • Basta infatti indicare il file nel metodo Add:

   xWb = (Excel.Workbook)(xApp.Workbooks.Add("c:\\temp\\test01.xlsx"));

Aggiunta di altri Sheet
  • I fogli di lavoro (Sheets) sono indicizzati con base 1.
  • Per aggiungere Sheets, si può utilizzare l'istruzione seguente.

   xWs = xApp.Worksheets.Add(arg1, arg2, arg3, arg4);

  • I quattro argomenti sono rispettivamente:
    • arg1: lo Sheet prima del quale aggiungere i nuovi Sheets.
    • arg2: lo Sheet dopo il quale aggiungere i nuovi Sheets.
    • arg3: il numero di Sheets da aggiungere.
    • arg4: il tipo di Sheets da aggiungere.

  • Esempio, aggiunta di uno Sheet prima del primo Sheet.

   xWs = xApp.Worksheets.Add(xWb.Sheets[1], Type.Missing, 1, Type.Missing);

  • Esempio, aggiunta di uno Sheet dopo il primo Sheet.

   xWs = xApp.Worksheets.Add(Type.Missing, xWb.Sheets[1], 1, Type.Missing);

  • Il quarto argomento permette di indicare se aggiungere un foglio, un grafico o una macro. Se non è indicato, verrà aggiunto un foglio (o più di uno in base al terzo argomento).

Scrittura e formattazione di celle
  • La scrittura di celle può avvenire indicizzando le coordinate delle celle in modo tradizionale, riga e colonna.
  • La colonna può essere indicata indifferentemente con la coordinata equivalente numerica o letterale.
  • Quindi la scrittura delle prime due celle avviene con le seguenti righe:

   // Aggiunge dati cella per cella.
   xWs.Cells[1, "A"] = "Hello";
   xWs.Cells[1, "B"] = "World";

  • Oppure con le seguenti righe equivalenti:

   // Aggiunge dati cella per cella.
   xWs.Cells[1, 1] = "Hello";
   xWs.Cells[1, 2] = "World";

  • Metodo alternativo per scrivere un range di celle:

   // Crea un array con vari valori.
   string[,] saNames = new string[5, 2];
   saNames[0, 0] = "Nome_1"; saNames[0, 1] = "Cognome_1";
   saNames[1, 0] = "Nome_2"; saNames[1, 1] = "Cognome_2";
   saNames[2, 0] = "Nome_3"; saNames[2, 1] = "Cognome_3";
   saNames[3, 0] = "Nome_4"; saNames[3, 1] = "Cognome_4";
   saNames[4, 0] = "Nome_5"; saNames[4, 1] = "Cognome_5";

   // Riempie le celle A2:B6 con i valori dell'array.
   xWs.get_Range("A2", "B6").Value2 = saNames;

  • Il seguente esempio mostra come eseguire delle formattazioni a un range di celle.

   // Formatta A1:D1 grassetto e allineamento verticale al centro.
   xWs.get_Range("A1", "D1").Font.Bold = true;
   xWs.get_Range("A1", "D1").VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;


Inserimento di formule

  • Le formule si inseriscono a 'range' di celle.
  • I nomi delle formule vanno scritti in inglese. Aprendo il file Excel con la versione localizzata per esempio in italiano, le formule risulteranno in italiano.
  • Esempio di inserimento della formula: =A2 & " " & B2. Si ricordi che il carattere 'virgolette' è riservato e va quindi preceduto dal backslash.


   // Riempie le celle C2:C6 con una formula.
   xRange = xWs.get_Range("C2", "C6");
   xRange.Formula = "=A2 & \" \" & B2";

  • Esempio di inserimento della formula: =RAND()*100000.

   // Riempie le celle D2:D6 con una formula e ne imposta il formato.
   xRange = xWs.get_Range("D2", "D6");
   xRange.Formula = "=RAND()*100000";

   xRange.NumberFormat = "$0.00";


Impostare la larghezza delle colonne

  • La larghezza delle colonne può essere impostata automatica o fissa.
  • Ecco gli esempi.

   // Larghezza colonne A:D automatica.
   xRange = xWs.get_Range("A1", "D1");
   xRange.EntireColumn.AutoFit();

   // Larghezza colonne impostata con un valore fisso.
   xWs.Columns[5].ColumnWidth = 10;
   xWs.Columns[6].ColumnWidth = 20;
   xWs.Columns[7].ColumnWidth = 30;


Esempio completo

  • Di seguito, un esempio completo.
  • Si sono introdotte le seguenti modifiche:
    • La creazione dell'oggetto Workbook, viene fatta passando da un passo intermedio, che è la creazione di un oggetto Workbooks. Questo non è strettamente necessario, ma è consigliato per avere un riferimento a quest'ultimo oggetto. Infatti se qualcosa dovesse andare male durante l'esecuzione del programma, potrebbero rimanere delle risorse in memoria non rilasciabili. Per ulteriori informazioni cercare in Internet articoli riguardanti la notazione "a doppio punto".
    • La gestione degli errori comprende il finally, con il rilascio delle risorse COM. In Internet ci sono molti articoli che consigliano il rilascio forzato degli oggetti COM; ma ci sono anche altri articoli che ne sconsigliano l'uso lasciando al Garbage Collector il lavoro di pulizia degli oggetti non più utilizzati. A volte si consiglia solo di verificare l'attivazione del Garbace Collector con le seguenti righe (non è un errore, le due istruzioni sono eseguite due volte):

   GC.Collect();
   GC.WaitForPendingFinalizers();
   GC.Collect();
   GC.WaitForPendingFinalizers();


    • Infine, altri articoli consigliano sempre di impostare a null gli oggetti rilasciato.
    • Si è quindi scelto di pubblicare un esempio funzionante recependo i consigli più numerosi.


   Excel.Application xApp = null;
   Excel.Workbooks xWbs = null;
   Excel.Workbook xWb = null;
   Excel.Worksheet xWs = null;
   Excel.Range xRange = null;
   object misValue = System.Reflection.Missing.Value;

   try
   {
       // Avvia Excel.
       xApp = new Excel.Application();
       xApp.Visible = true;

       // Crea un Workbook di un file nuovo (con uno Sheet).
       xWbs = (Excel.Workbooks)xApp.Workbooks;
       xWb = (Excel.Workbook)xWbs.Add(misValue);
 
       // Crea un Worksheet.
       xWs = (Excel.Worksheet)xWb.ActiveSheet;

       // Aggiunge dati cella per cella.
       xWs.Cells[1, 1] = "Nome";
       xWs.Cells[1, 2] = "Cognome";
       xWs.Cells[1, 3] = "Nome e Cognome";
       xWs.Cells[1, 4] = "Stipendio";

       // Formatta A1:D1 grassetto e allineamento verticale al centro.
       xWs.get_Range("A1", "D1").Font.Bold = true;
       xWs.get_Range("A1", "D1").VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;

       // Crea un array con vari valori.
       string[,] saNames = new string[5, 2];
       saNames[0, 0] = "Nome_1"; saNames[0, 1] = "Cognome_1";
       saNames[1, 0] = "Nome_2"; saNames[1, 1] = "Cognome_2";
       saNames[2, 0] = "Nome_3"; saNames[2, 1] = "Cognome_3";
       saNames[3, 0] = "Nome_4"; saNames[3, 1] = "Cognome_4";
       saNames[4, 0] = "Nome_5"; saNames[4, 1] = "Cognome_5";

       // Riempie le celle A2:B6 con i valori dell'array.
       xWs.get_Range("A2", "B6").Value2 = saNames;

       // Riempie le celle C2:C6 con una formula.
       xRange = xWs.get_Range("C2", "C6");
       xRange.Formula = "=A2 & \" \" & B2";

       // Riempie le celle D2:D6 con una formula e ne imposta il formato.
       xRange = xWs.get_Range("D2", "D6");
       xRange.Formula = "=RAND()*100000";
       xRange.NumberFormat = "$0.00";

       // Larghezza colonne A:D automatica.
       xRange = xWs.get_Range("A1", "D1");
       xRange.EntireColumn.AutoFit();

       // Larghezza colonne impostata con un valore fisso.
       xWs.Columns[5].ColumnWidth = 10;
       xWs.Columns[6].ColumnWidth = 20;
       xWs.Columns[7].ColumnWidth = 30;

       // Chiude e salva.
       xApp.Visible = false;
       xApp.UserControl = false;
       xWb.SaveAs("c:\\temp\\test01.xlsx", Excel.XlFileFormat.xlWorkbookDefault, Type.Missing, Type.Missing,
           false, false, Excel.XlSaveAsAccessMode.xlNoChange,
           Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
       xWb.Close();
       xApp.Quit();
   }
   catch (Exception ex)
   {
       MessageBox.Show(ex.Message);
   }
   finally
   {
       System.Runtime.InteropServices.Marshal.ReleaseComObject(xRange);
       xRange = null;
       System.Runtime.InteropServices.Marshal.ReleaseComObject(xWs);
       xWs = null;
       System.Runtime.InteropServices.Marshal.ReleaseComObject(xWb);
       xWb = null;
       System.Runtime.InteropServices.Marshal.ReleaseComObject(xWbs);
       xWbs = null;
       System.Runtime.InteropServices.Marshal.ReleaseComObject(xApp);
       xApp = null;
   }








© 2020 Carlo Vecchio
Torna ai contenuti