Riporto l'articolo scritto per il sito http://www.iprogrammatori.it/articoli/programmazione/art_silverlight-esportare-un-datagrid-in-exc_1110.aspx
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 sostitzione 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.