Skip to main content

Create Excel from SharePoint List Data and Send by email

During my daily task allocation I came across a task in which I was supposed to create excel from SharePoint list and then send the created excel via email. The procedure was to be repeated daily.

I used timer job to repeat task on daily basis. As I was unaware of the column that may exist in SharePoint list so I thought of using SharePoint views (i.e., AllItems) to get the list of fields. Also this facilitated my code to be dynamic enough to be replaces with custom created views.

Add a new class file to project:
Right click project > Add > class
Name class file: ListToExcelGenerator

namespace xxx
{
    /// <summary>
    /// Class to create Excel from Sharepoint List
    /// </summary>
    class ListToExcelGenerator
    {
        /// <summary>
        /// Sets file path as well file name.
        /// </summary>
        /// <param name="url">url of the web application/rootsite</param>
        public void ListToExcelConvertor(string url)
        {
            using (SPSite site = new SPSite(url))
            {
                using (SPWeb web = site.OpenWeb())
                {
                    string filePath = “Path of where to create file”;
                    string fileName = “file name”;
                    DirectoryInfo dir = new DirectoryInfo(filePath);
                    dir.Create();

                    FileInfo file = new FileInfo(filePath + "\\" + fileName + ".xls");
                    StreamWriter streamWriter = file.CreateText();

                    StringWriter stringWriter = new StringWriter();
                    HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);

                    string listName = “list name”;

                    Table tblData = GetListTableControl(url + "/Lists/" + listName.Trim(), listName.Trim());
                    tblData.RenderControl(htmlTextWriter);
                    streamWriter.Write(stringWriter.ToString());

                    htmlTextWriter.Close();
                    streamWriter.Close();
                    stringWriter.Close();
                }
            }
        }
        /// <summary>
        /// Creates excel from specified list
        /// </summary>
        /// <param name="strListURL">url to webapplication/rootsite</param>
        /// <param name="strListName">name of list</param>
        /// <returns></returns>
        private static Table GetListTableControl(string strListURL, string strListName)
        {
            //Table class object to get list data to Table
            Table tblListView = new Table();
            tblListView.ID = "_tblListView";
            tblListView.BorderStyle = BorderStyle.Solid;
            tblListView.BorderWidth = Unit.Pixel(1);
            tblListView.BorderColor = Color.Silver;

            using (SPSite site = new SPSite(strListURL.Trim()))
            {
                using (SPWeb web = site.OpenWeb())
                {

                    SPList list = web.Lists.TryGetList(strListName.Trim());
                    if (list != null)
                    {

                        SPView wpView = list.Views["All Items"];
                        wpView.RowLimit = 2147483647;


                        // query to find non deleted items from sharepoint list
                        SPQuery query = new SPQuery(wpView);
                        string softDeleteColumnName = “column for soft delete”;
                        query.Query = "<Where><Eq><FieldRef Name='" + softDeleteColumnName.Trim() + "'/><Value Type='bool'>false</Value></Eq></Where>";


                        SPListItemCollection items = list.GetItems(query);
                        if (items != null && items.Count > 0)
                        {
                            // Code to Create excel data format
                            DataTable tbListViewData = items.GetDataTable();
                            DataView dvListViewData = tbListViewData.DefaultView;
                            if (dvListViewData != null && dvListViewData.Count > 0)
                            {
                                tblListView.Rows.Add(new TableRow());
                                tblListView.Rows[0].BackColor = Color.Gainsboro;
                                tblListView.Rows[0].Font.Bold = true;

                                for (int i = 0; i < wpView.ViewFields.Count; i++)
                                {
                                    tblListView.Rows[0].Cells.Add(new TableCell());
                                    tblListView.Rows[0].Cells[i].Text = list.Fields.GetFieldByInternalName(wpView.ViewFields[i].ToString()).Title;
                                }

                                for (int i = 0; i < dvListViewData.Count; i++)
                                {
                                    tblListView.Rows.Add(new TableRow());

                                    for (int j = 0; j < wpView.ViewFields.Count; j++)
                                    {
                                        tblListView.Rows[i + 1].Cells.Add(new TableCell());

                                        if (tbListViewData.Columns.Contains(wpView.ViewFields[j].ToString()))
                                        {
                                            tblListView.Rows[i + 1].Cells[j].Text = dvListViewData[i][wpView.ViewFields[j].ToString()].ToString();
                                        }
                                    }
                                }
                            }
                        }
                        // excel fomrat code ends
                    }
                }
            }
            return tblListView;
        }
    }
}

Once excel is generated it’s time to send the created excel via email. I am reading the SharePoint outbound email configuration to send email. You can use SMTP if required.

Add a new class file to project:
Right click project > Add > class
Name class file: EmailSender


namespace xxx
{
    class EmailSender
    {
        /// <summary>
        /// prepares Email content
        /// </summary>
        /// <param name="url">web url</param>
        /// <returns>true if mail is send</returns>
        public bool SendEmail(string url)
        {
            string subject = string.Empty;
            string emailBody = string.Empty;
            bool output = false;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site = new SPSite(url))
                {
                    using (SPWeb web = site.OpenWeb())
                    {

                        string from = string.Empty;
                        string smtpAddress = string.Empty;

                        if (web.Site.WebApplication.OutboundMailSenderAddress != null)
                        {
                            from = web.Site.WebApplication.OutboundMailSenderAddress;
                        }
                        if (site.WebApplication.OutboundMailServiceInstance.Server.Address != null)
                        {
                            smtpAddress = site.WebApplication.OutboundMailServiceInstance.Server.Address;
                        }
                        string filePath = “file path”;
                        string fileName = “file name”;
                        Attachment attachment = new Attachment(filePath + "\\" + fileName + ".xls");

                        string to = string.Empty;

                        to = “send email to address”;

                        subject = “subject of email”
                        emailBody = “email body”;
                        string errtext = string.Empty;
                        output = SendMail(smtpAddress.Trim(), subject.Trim(), from, to.Trim(), null, null, attachment, emailBody.Trim());
                    }
                }
            });
            return output;
        }

        /// <summary>
        /// Sends email
        /// </summary>
        /// <param name="smtpAddress"></param>
        /// <param name="subject"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="cc"></param>
        /// <param name="bcc"></param>
        /// <param name="attachements"></param>
        /// <param name="body"></param>
        /// <returns></returns>
        public bool SendMail(string smtpAddress, string subject, string from, string to, string cc, string bcc, Attachment attachements, string body)
        {
            bool mailSent = false;
            SmtpClient smtpClient = null;

            smtpClient = new SmtpClient();
            smtpClient.Host = smtpAddress;


            MailMessage mailMessage = new MailMessage(from, to);//, subject, body);
            mailMessage.Subject = subject;
            if (!String.IsNullOrEmpty(cc))
            {
                MailAddress CCAddress = new MailAddress(cc);
                mailMessage.CC.Add(CCAddress);
            }
            if (!String.IsNullOrEmpty(bcc))
            {
                MailAddress BCCAddress = new MailAddress(bcc);
                mailMessage.Bcc.Add(BCCAddress);
            }
            mailMessage.Attachments.Add(attachements);

            StringBuilder eBody = new StringBuilder(body);

            mailMessage.Body = eBody.ToString();
            smtpClient.Send(mailMessage);
            mailSent = true;



            return mailSent;
        }
    }
}

The above code will return true if email is successfully send. Now it is just as to create a timer job create objects of above classes and invoke appropriate methods.

You can use following links to create a timer job.
Ref:
http://www.codeproject.com/Articles/403323/SharePoint-Create-Custom-Timer-Jobs

Regards,
Keyur Pandya

Comments

Popular posts from this blog

Identity client runtime library (IDCRL) did not get a response from the login server.

Recently I was doing some testing with a background PowerShell and encountered a weird error. “Identity client runtime library (IDCRL) did not get a response from the login server”. The error that you might encounter while working with PowerShell. This error is very misleading when it comes to identifying what could go wrong. After doing quite a good amount of research below are the probable causes for the error. Invalid Credentials MFA (Multi-Factor Authentication) Manage security defaults. Solutions Invalid Credentials Check if your credentials are wrong. Especially if you are using variables. MFA (Multi-Factor Authentication) Check if MFA is enabled on the account which you are using. These only affect you badly if you are developing PowerShell for a background Job. Go to Microsoft 365 admin center Users -> Active users -> Select the user -> Manage multifactor authentication -> Select the user -> Disable multi-factor authentication. M...

Business Data Connectivity

I came to a requirement wherein I was supposed to get data from an 3 rd party portal using API’s and then bring them to SharePoint server. The first approach that I finalized was just to make BDC solution that will get data from 3 rd party portal and will deploy it to SharePoint. How to Create BDC solution in SharePoint? I found below link that is having really great description about hot to create and deploy the BDC solution to SharePoint. http://www.c-sharpcorner.com/uploadfile/hung123/creating-business-data-connectivity-service-using-visual-studio-2010/ After creating an POC I came to know that BDC model cannot be deployed on Multi tenant farm. So what can be done next? After some amount of googling I came to know that we can create BDC solution using WCF services also. So I created a WCF service solution that acted as a wrapper that used to fetch data from the portal. We can them publish that service to IIS or Server and use the servic...

Site Design Tasks, Power Automate and Modern Sites

S harePoint Site templates are now replaced with Site designs in Modern Sites. We can create custom site designs using some json script(s). Site Design allows to create lists, create list views, apply theme, customize navigation, create content types, create site columns and so on. Click here to see JSON scheme reference for creating custom site design.  Endpoint to apply site design as a part of flow is as below. _api/Microsoft.Sharepoint.Utilities.WebTemplateExtensions.SiteScriptUtility.AddSiteDesignTaskToCurrentWeb We must use “Send Http Request to SharePoint” action to make an API call to SharePoint. SiteDesignId must be part if body, this is GUID of the SharePoint site design you need to apply. We can line up sequence of calls if we need to apply multiple site designs to a single site. We can now wait for few mins and all our sited designs will get applied or we can also check the status by making another API call with below endpoint. You just need to pass the Apply Desig...