Silverlight: esportare un datagrid in Excel VB.Net e C#

Vedremo una tecnica su come esportare il contenuto di un controllo datagrid in Excel.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

Introduzione

Vedremo com esportare il contenuto di un controllo datagrid in formato exel 2007 il tutto tramite il linguaggio di programmazione VB.Net e C#

Creazione del progetto

Si crea un nuovo progetto in Silverlight, in riferimento al linguaggio di proprio interesse.
Dopo aver creato un nuovo progetto, aggiungete nella form, un controllo datagrid.
Prima, di lavorare sulla pagina, si crea una classe, che sarà utilizzata come contenitore di dati, per valorizzare il nostro controllo griglia.
Da esplora soluzione, si crea una nuova classe. Chiamata Persona.
Questa classe, contiene due proprietà nome e cognome.
Qui di seguito si riporta il codice di tale operazione

VB.Net
Public Class Persona
    Property Nome As String
    Property Cognome As String
End Class
C#
    public class Persona
    {
        string _nome;
        string _cognome;
         public string Cognome
        {
            get { return _cognome; }
            set { _cognome = value; }
        }
        public string Nome
        {
            get { return _nome; }
            set { _nome = value; }
        }
    }



 

Terminata la creazione della classe persona si passa alla pagina contenente il nostro controllo datagrid.
Ricordiamo di tenere a false, la proprietà autogeneratecolumns.
Aggiungiamo un pulsante, che ci permetta di visualizzare una finestra di dialogo per poter salvare il nostro file.

Creazione del file di excel

Apriamo un documento Excel, ed impostiamo le colonne, una denominata cognome e l’altra nome, nella riga successiva, impostare i valori, il tutto come illustrato in figura 1.

 

 

Figura 1



Salviamo il file in formato excel 2003 xml, ossia formato excel 2003 xml come mostrato in figura 2.






Figura 2


Aprite il file xml in

<Styles>
  <Style ss:ID="Default" ss:Name="Normal">
   <Alignment ss:Vertical="Bottom"/>
   <Borders/>
   <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
   <Interior/>
   <NumberFormat/>
   <Protection/>
  </Style>
 </Styles>
 <Worksheet ss:Name="Foglio1">
  <Table ss:ExpandedColumnCount="2" ss:ExpandedRowCount="2" x:FullColumns="1"
   x:FullRows="1" ss:DefaultRowHeight="15">
   <Row>
    <Cell><Data ss:Type="String">Cognome</Data></Cell>
    <Cell><Data ss:Type="String">Nome</Data></Cell>
   </Row>
   <Row>
    <Cell><Data ss:Type="String">Mat</Data></Cell>
    <Cell><Data ss:Type="String">Ema</Data></Cell>
   </Row>
  </Table>
  <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
   <PageSetup>
    <Header x:Margin="0.3"/>
    <Footer x:Margin="0.3"/>
    <PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
   </PageSetup>
   <Selected/>
   <Panes>
    <Pane>
     <Number>3</Number>
     <ActiveRow>1</ActiveRow>
     <ActiveCol>2</ActiveCol>
    </Pane>
   </Panes>
   <ProtectObjects>False</ProtectObjects>
   <ProtectScenarios>False</ProtectScenarios>
  </WorksheetOptions>
 </Worksheet>



Modifichiamo due parti relative al foglio 1, la prima è il campo ss:ExpandedRowCount="2" in
ss:ExpandedRowCount="[TotaleRecord]"

La seconda di sostituire la parte relative  alle righe dei dati ossia questa

<Row>
    <Cell><Data ss:Type="String">Mat</Data></Cell>
    <Cell><Data ss:Type="String">Ema</Data></Cell>
   </Row>


In
[RigaDati]
In pratica il frammento di codce sarà come riportato qui di seguito

<Styles>
  <Style ss:ID="Default" ss:Name="Normal">
   <Alignment ss:Vertical="Bottom"/>
   <Borders/>
   <Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="11" ss:Color="#000000"/>
   <Interior/>
   <NumberFormat/>
   <Protection/>
  </Style>
 </Styles>
 <Worksheet ss:Name="Foglio1">
  <Table ss:ExpandedColumnCount="2" ss:ExpandedRowCount="[TotaleRecord]" x:FullColumns="1"
   x:FullRows="1" ss:DefaultRowHeight="15">
   <Row>
    <Cell><Data ss:Type="String">Cognome</Data></Cell>
    <Cell><Data ss:Type="String">Nome</Data></Cell>
   </Row>
  [RigaDati]
  </Table>
  <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
   <PageSetup>
    <Header x:Margin="0.3"/>
    <Footer x:Margin="0.3"/>
    <PageMargins x:Bottom="0.75" x:Left="0.7" x:Right="0.7" x:Top="0.75"/>
   </PageSetup>
   <Selected/>
   <Panes>
    <Pane>
     <Number>3</Number>
     <ActiveRow>1</ActiveRow>
     <ActiveCol>2</ActiveCol>
    </Pane>
   </Panes>
   <ProtectObjects>False</ProtectObjects>
   <ProtectScenarios>False</ProtectScenarios>
  </WorksheetOptions>
 </Worksheet>




 

La modifica al modello del file excel, è stata modificata, non ci resta, che aggiungerla al progetto.
Facciamo tasto destro sul nostro progetto, nella finestra esplora soluzione, ed aggiungiamo come elemento esistente.

 

Stesura di codice

Passiamo in modalità codice della nostra applicazione SiLverlight, aggiungiamo lo spazio dei nomi per la gestione delle classi dei file, stream e risorse.
Qui di seguito si riporta il codice delle suddette operazioni per entrambi i linguaggi.


VB.Net
Imports System.IO
Imports System.Text
Imports System.Windows.Resources
C#
using System.IO;
using System.Text;
using System.Windows.Resources;

Nell’evento load della nostra pagina, carichiamo i dati nella griglia.
Qui di seguito si riporta il codice delle suddette operazioni per entrambi i linguaggi
 

VB.Net
    Private Sub LayoutRoot_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles LayoutRoot.Loaded
        Dim listPersona As New List(Of Persona)
        Dim per As New Persona
        per.Cognome = "Mattei"
        per.Nome = "Emanuele"
        listPersona.Add(per)
        per = New Persona()
        per.Cognome = "Mat"
        per.Nome = "Ema"
        listPersona.Add(per)
        'carico i dati
        DataGrid1.ItemsSource = listPersona
    End Sub
C#
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
        {
            List<Persona> listPersona = new List<Persona>();
            Persona per = new Persona();
            per.Cognome = "Mattei";
            per.Nome = "Emanuele";
            listPersona.Add(per);
            per = new Persona();
            per.Cognome = "Mat";
            per.Nome = "Ema";
            listPersona.Add(per);
            //carico i dati
            dataGrid1.ItemsSource = listPersona;
        }


Si crea una funzione, che permette il salvataggio dei dati in formato excel.
La funzione prende il modello del file excel creato in precedenza e lo manipola.
Qui di seguito si riporta il codice di tale operazione.

 

VB.Net
Private Function CreaFileExcelXml(dati As IEnumerable(Of Persona2))
        Dim TotaleRecord As Integer = dati.Count() + 1
        Dim sb As New StringBuilder
        For Each elemento In dati
            sb.AppendLine("<Row>")
            sb.AppendFormat("<Cell><Data ss:Type=""String"">" & elemento.Cognome & "</Data></Cell>")
            sb.AppendFormat("<Cell><Data ss:Type=""String"">" & elemento.Nome & "</Data></Cell>")
            sb.AppendLine("</Row>")
        Next
        Dim streamRisorsa As StreamResourceInfo = Application.GetResourceStream(New Uri("FileExcel2.xml", UriKind.Relative))
        Dim StreamReaderDati As New StreamReader(streamRisorsa.Stream)
        Dim streamFile As String = StreamReaderDati.ReadToEnd()
        streamFile = streamFile.Replace("[TotaleRecord]", TotaleRecord.ToString())
        streamFile = streamFile.Replace("[RigaDati]", sb.ToString())
        StreamReaderDati.Close()
        Return streamFile
    End Function
C#
private string CreaFileExcelXml(IEnumerable<Persona> dati)
        {
            int TotaleRecord = dati.Count() + 1;
            StringBuilder sb = new StringBuilder();
            foreach (var elemento in dati)
            {
                sb.AppendLine("<Row>");
                sb.AppendFormat("<Cell><Data ss:Type=\"String\">{0}</Data></Cell>", elemento.Cognome);
                sb.AppendFormat("<Cell><Data ss:Type=\"String\">{0}</Data></Cell>", elemento.Nome);
                sb.AppendLine("</Row>");
            }
            StreamResourceInfo streamRisorsa = Application.GetResourceStream(new Uri("FileExcel2.xml", UriKind.Relative));
            var StreamReaderDati = new StreamReader(streamRisorsa.Stream);
            string streamFile = StreamReaderDati.ReadToEnd();
            streamFile = streamFile.Replace("[TotaleRecord]", TotaleRecord.ToString());
            streamFile = streamFile.Replace("[RigaDati]", sb.ToString());
            StreamReaderDati.Close();
            return streamFile;
        }



Ora non ci resta che creare il codice da utilizzare nel pulsante di esportazione, che rileverà i dati del controllo datagrid e li esporta in excel

Qui di seguito si riporta delle suddette operazioni.

 VB.Net
    Private Sub BtnEsporta_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles BtnEsporta.Click
        Dim data As String = String.Empty
        Dim SaveDialog As New SaveFileDialog()
        SaveDialog.DefaultExt = "xml"
        SaveDialog.Filter = "XML Files | *.xml"
        Dim scelta As Boolean? = SaveDialog.ShowDialog()
        Dim testo As String = SaveDialog.SafeFileName
        If scelta = True Then
            Using fs As Stream = CType(SaveDialog.OpenFile(), Stream)
                'Ottengo i dati contenuti nel controllo datagrid
                Dim listPersone As IEnumerable(Of Persona2) = CType(DataGrid1.ItemsSource, IEnumerable(Of Persona2))
                'rilevo lo stream dati relativo al file excel da generare
                data = CreaFileExcelXml(listPersone)
                'scrivo il file excel
                Dim FileByte As Byte() = New System.Text.UTF8Encoding(True).GetBytes(data)
                fs.Write(FileByte, 0, FileByte.Length)
                fs.Close()
            End Using
        End If
    End Sub
C#
private void BtnEsporta_Click(object sender, RoutedEventArgs e)
        {
            string data = String.Empty;
            SaveFileDialog SaveDialog = new SaveFileDialog();
            SaveDialog.DefaultExt = "xml";
            SaveDialog.Filter = "XML Files | *.xml";
            bool? scelta = SaveDialog.ShowDialog();
            string testo = SaveDialog.SafeFileName;
            if (scelta == true)
            {
                using (Stream fs = (Stream)SaveDialog.OpenFile())
                {
                    //Ottengo i dati contenuti nel controllo datagrid
                    IEnumerable<Persona> listPersona = dataGrid1.ItemsSource as IEnumerable<Persona>;
                    //rilevo lo stream dati relativo al file excel da generare
                    data = CreaFileExcelXml(listPersona);
                    //scrivo il file excel
                    byte[] FileByte = new System.Text.UTF8Encoding(true).GetBytes(data);
                    fs.Write(FileByte, 0, FileByte.Length);
                    fs.Close();
                }
            }
        }
 

Conclusioni

L'articolo ha voluto fornire una tecnica di come esportare il contenuto di una fonte dati, e precisamente di un controllo datagrid, in formato Excel. Tecnica che può tornare utile qualora si devono gestire particolare dati, soprattutto in riferimento ad una intranet.