Wednesday, October 6, 2010

Exporting Excel Report from SilverLight 3

Hello Readers

Some of you may have faced the problem of exporting data from silverlight 3. Today, while figuring out how to do this , i found following posts : http://www.ritzcovan.com/2009/10/exporting-data-from-silverlight-to-excel/comment-page-1/
using which I was able to export data to excel.

I made small changes to it and so thought of posting it so that someone else can use it. The original post is very clear and full credit to author . Here is my attempt :

lets say you want to export data from silverlight 3 business application using Ria services. The requirement in my case was to export the data but do not need to show in datagrid. I have various radiobuttons on page and excelreport button like this :












My requirement was to get data from db on selected radiobutton and export to excel report.

1st create the template of data that you are expecting:




1) open excel and write your data like this :










2) Save it like this :














3) Open the Template.xml using notepad file and it should look like this:












4)Make changes like this :

















5) Add it to your SL App like this :

















6) Create a silverlight enabled wcf service in your web project :














7) Since I have Radiobuttons on xaml , so the code behind looks like this :

private void Radio_Click(object sender, RoutedEventArgs e)
{
RadioButton rb = (RadioButton)sender;
if (rb.IsChecked == true)
{
radioText = rb.Content.ToString();
}
if (radioText != "" && division != "" && domain != "")
{
ExportServiceClient client = new ExportServiceClient();
client.GetReportCompleted += new EventHandler(client_GetReportCompleted);
client.GetReportAsync(radioText, division, domain);
}
}
void client_GetReportCompleted(object sender, GetReportCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.ToString());
}
else
{
dgReport.ItemsSource = e.Result;
}
}


dgReport is data grid which i dont need but i have put that on xaml page in collapsed form.So, everytime a radiobutton is clicked the datagrid is populated. division and domain are the other parameters coming from combo box and so in your case , these params can be removed and wcf service function will be altered accordingly.

in you xaml the excel button looks like this :
"
"


and finally the excel click event :

private void btnExcel_Click(object sender, RoutedEventArgs e)
{

if (radioText != "" && division != "" && domain != "")
{
StringBuilder test = new StringBuilder();
string data = String.Empty;
SaveFileDialog sfd = new SaveFileDialog();
sfd.DefaultExt = "xml";
sfd.Filter = "XML Files | *.xml";

bool? resp = sfd.ShowDialog();

if (resp == true)
{
using (Stream fs = (Stream)sfd.OpenFile())
{
//get the data from the grid so we can format it into xml
IEnumerable recs = dgReport.ItemsSource as IEnumerable;

//determine what type of xml to create based on the tag property of the button that fired the event
Button btn = sender as Button;

if (btn.Tag.Equals("OfficeXML"))
data = CreateOfficeXML(recs);
else
data = CreateXML(recs);

//write it out
byte[] info = new System.Text.UTF8Encoding(true).GetBytes(data);
fs.Write(info, 0, info.Length);
fs.Close();
}


}

}
else
{
MessageBox.Show("Please select an item to generate report.");
}
}

private string CreateXML(IEnumerable records)
{
var ed = new XElement("ExportDatas",
from record in records
select
new XElement("ShipRecord",
new XElement("ServerName", record.ServerName),
new XElement("ItemValue", record.ItemValue),
new XElement("ItemStandard", record.ItemStandard),
new XElement("IsCompliant", record.IsCompliant)));

return ed.ToString();
}
private string CreateOfficeXML(IEnumerable records)
{
int count = records.Count() + 1;
StringBuilder sb = new StringBuilder();

foreach (var rec in records)
{
sb.AppendLine("");
sb.AppendFormat("{0}", rec.ServerName);
sb.AppendFormat("{0}", rec.ItemValue);
sb.AppendFormat("{0}", rec.ItemStandard);
sb.AppendFormat("{0}", rec.IsCompliant);
sb.AppendLine("
");
}

StreamResourceInfo sri = Application.GetResourceStream(new Uri("Template.xml", UriKind.Relative));
var sr = new StreamReader(sri.Stream);

string data = sr.ReadToEnd();
data = data.Replace("[ROWCOUNT]", count.ToString());
data = data.Replace("[ROWDATA]", sb.ToString());
sr.Close();

return data;
}


And thats it :)

Please let me know if anyone have any problem in understanding this and I will try to help. My email address is : khatri.vk1983@gmail.com

Thanks

No comments: