Email a LocalReport as a PDF Attachment

http://www.codeproject.com/Articles/20580/Email-a-LocalReport-as-a-PDF-Attachment

Introduction

If you are using the ReportViewer or ReportingServices in your application and have ever said to yourself, "You know, it would be really nice if I could take this report and attach it as an email and send it to someone", then you are in the right spot. In my last project, we were using the ReportViewer and had many reports lying around and I found myself saying just that. I didn't want to write the PDF's to the file system of the server, then attach it to the email and then clean up after myself. I wanted to stream it directly into the email. Here is how I accomplished this task.

Background

This article assumes that you have your web site set up to use the standard SMTP settings for ASP.NET 2.0. Your web.config should have a section that looks something like this:

<!--<span class="code-comment"> SMTP Settings --></span>
    <system.net>
        <mailSettings>
            <smtp deliveryMethod="Network" from="no-reply@mywebsite.com">
                <network host="localhost" port="25" defaultCredentials="true"/>
            </smtp>
        </mailSettings>
    </system.net>

This article will assume that you also have a working report and it's associated datasource(s). It's beyond the scope of this article to explain creating the report or using the report viewer. There are plenty of tutorials just on doing that. This will focus on creating the report in memory and streaming it into an email as an attachment.

Using the Code

Make sure that you have all the namespaces that you are going to need in your code. We will be using the following:

  • System.Net.Mail
  • Microsoft.Reporting.WebForms
  • System.IO

So in order to begin setting up our report as an attachment, the first thing that you must do is, get the report and it's data sources set up correctly.

LocalReport lr = new LocalReport();
lr.ReportPath = HttpContext.Current.Server.MapPath("~/Reports/myReport.rdlc");

The code above creates a new LocalReport in memory and sets the path to the actual report definition local client (.rdlc) file. The next step in the process is to get the datasources for the report setup. We do this by using table adapters and adding them to the local reports datasource collection. For this example, we will say that we have two data sources in our report, perhaps there is a sub-report that is displayed.

MyFirstDataSetTableAdapters.MyFirstTableAdapter ta1 = 
        new MyFirstDataSetTableAdapters.MyFirstTableAdapter();
MySecondDataSetTableAdapters.MySecondTableAdapter ta2 = 
        new MySecondDataSetTableAdapters.MySecondTableAdapter();

ReportDataSource ds1 = new ReportDataSource
    ("MyFirstDataSet_MyFirstTableAdapter", ta1.GetData(myParam1, myParam2));
ReportDataSource ds2 = new ReportDataSource
    ("MySecondDataSet_MySecondTableAdapter", ta2.GetData(myParam3));

You can see in the code above that we create our table adapters, ta1 and ta2. We then create two instances of a ReportDataSource using our table adapters' GetData method as the dataSourceValue. You might have to pass a couple of parameters to the table adapter method as we did here - it all depends on your architecture. Here we just showed what it would look like by passing a couple of pseudo parameters to our GetData method.

The critical part here is making sure that the name of the datasource is EXACTLY the same as it is in the report. You can get this information by looking at the datasources in the report designer and basically copying and pasting the values. If you get the names incorrect, the report will not generate at all.

We then add each ReportDataSource to the LocalReport datasources collection by calling the Add method and passing in the appropriate variables.

lr.DataSources.Add(ds1);
lr.DataSources.Add(ds2); 

So from this point, we should have a LocalReport, with two datasources that are mapped to a couple of tables from our datasets, all set and ready to go. The next step will be to set up the email attachment. To do this, we will need to render the LocalReport into a stream that we can use for the email attachment. Step one is to set up all the variables that the Render method of the LocalReport needs and then render the report into memory.

Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string extension;

byte[] bytes = lr.Render("PDF", null, out mimeType, 
        out encoding, out extension, out streamids, out warnings);

You can see here that we set the format that we want out of the report to PDF. We could also use Excel or another valid type of output here if we wanted to. We also sent in null as the value for deviceInfo. If you wanted to, you could send in a string with the properly formatted XML device information. The rest of the parameters are output parameters as you can see. For this application, we don't use any of them. Once we execute this code, we now have a localReport, stored as a string of bytes in memory. We are now ready to stream these bytes into our email as an attachment.

MemoryStream s = new MemoryStream(bytes);
s.Seek(0, SeekOrigin.Begin); 

Here we create a MemoryStream from our string of bytes and set the position to the beginning of the stream by seeking there. If we did not seek the beginning of the stream, when we go to create the attachment, we would be at the end of the stream and nothing would get added in our attachment.

Attachment a = new Attachment(s, "myReport.pdf"); 

We create a new email Attachment and pass in our MemoryStream (which was the string of bytes we got from executing the Render method of our LocalReport) and a name for the attachment. We are now ready to create an email, add our attachment and send the report on it's way to our lucky recipient.

MailMessage message = new MailMessage(
    "my_friend@herEmail.com", "me@myEmail.com", 
    "A report for you!", "Here is a report for you");
message.Attachments.Add(a);
SmtpClient client = new SmtpClient();
client.Send(message);

First we create the mail message and add in the from, to, subject and body string parameters. We then add the attachment to the messages attachments collection by executing the Add method and passing our memory stream as the parameter. We then get a new SmtpClient and Send the message on it's way.

Points of Interest

The nice thing about creating the report as a stream and attaching it to the email this way is that it is all done in memory. There's no file creation and cleanup work that has to be done. Any report you create for use in the ReportViewer can be used here as well.

History

  • Sept. 20, 2007 - First Revision

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值