Friday, August 31, 2007

render rdlc as pdf

This article shows how to generate reports using the ASP.NET 2.0 Reportviewer server control using LocalReports with parameterized table adapters. I am using ASP.NET 2.0, Visual Studio 2005, and SQL Server 2005

The difference between Local Reports and Server Reports is that in Server Reports the client makes a report request to the server. The server generates the report and then sends it to the client. While this is more secure, it lowers performance due to transfer time from server to client.

In LocalReports, reports are generated at the client end and does not connect to the "SQL Server Reporting Services Server" .
Using the AdventureWorks database, this example will get the parameters for the table adapters as a queryString from the requesting aspx page.

You can download AdventureWorks database from

http://www.microsoft.com/downloads/thankyou.aspx?familyId=487c9c23-2356-436e-94a8-2bfb66f0abdc&displayLang=en

1. Open a new Website call it SampleReport.

2. Right click on solution in the Solution explorer. Go to Add new item and choose DataSet. Call it dsReport.xsd.

3. Open the dataset . Right click and choose Add -> TableAdapter. Open AdventureWorks DataBase and choose table Employee. Select all fields and append the "where" clause. (ex where employeeid = @employeeid)








4. Right click on solution in the Solution explorer. Go to Add new item and choose Report. Call it Report.rdlc

5. Design the report to display the EmployeeDetails. Choose Data -> show data sources from the Report Menu. Drag and drop the fields to be displayed on your designer.




6. Add new aspx page call it SampleReport.aspx. Drag and drop a ReportViewer from the toolbar . Now bind the rdlc to the reportviewer by bringing up the smart tag of the ReportViewer control and selecting "Report.rdlc" in the "Choose Report" dropdown list.





7. Now Select "Choose Data Sources" and choose an ObjectDataSource.


8. Configure the ODS to take the input parameter as a querystring. (Need to pass the parameter as a queryString in order to render as pdf)







9. Give the queryString name the same as you would use in your default.aspx page.




10. Open your default.aspx page and call the SampleReport.aspx. Add the following codeSnippet.. Note this is only an example. The default.aspx page can have a data grid listing all emplyee details. The user can click on an id and pass multiple queryString values to your SampleReport.aspx which in turn can have multiple datasets and/or table adapters.


Imports System.IO
Imports Microsoft.Reporting.WebForms
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Response.Redirect("SampleReport.aspx?employeeid=1")
End Sub
End Class


11. Add the foll code in your SampleReport.aspx.


Imports System.IO
Imports System.data
Imports Microsoft.Reporting.WebForms
Partial Class SampleReport
Inherits System.Web.UI.Page
Protected Sub Page_SaveStateComplete(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SaveStateComplete
Dim warnings As Warning() = Nothing
Dim streamids As String() = Nothing
Dim mimeType As String = Nothing
Dim encoding As String = Nothing
Dim extension As String = Nothing
Dim bytes As Byte()

Dim FolderLocation As String = "D:\SampleProjects\"
'First delete existing file
Dim filepath As String = FolderLocation & "Employee.PDF"
File.Delete(filepath)
'Then create new pdf file
bytes = ReportViewer1.LocalReport.Render("PDF", Nothing, mimeType, encoding, extension, streamids, warnings)
Dim fs As New FileStream(FolderLocation & "Employee.PDF", FileMode.Create)
fs.Write(bytes, 0, bytes.Length)
fs.Close()
'Set the appropriate ContentType.
Response.ContentType = "Application/pdf"
'Write the file directly to the HTTP output stream.
Response.WriteFile(filepath)
Response.End()
End Sub
End Class



12. Build and Run your WebSite.





9 comments:

Dan said...

The easiest way to generate a simple RDLC from a dataset is transform the schema xml into the RDLC.

The basic idea is to build rather generic RLDC file off a DataSet. You can then bind both the DataSet and the RDLC to a ReportViewer control and get your report. I generate the RDLC by transforming the DataSet XML schema into a RDLC file via and XSLT transform.

Here is a website showing the C# code and the XSLT...

http://csharpshooter.blogspot.com/2007/08/revised-dynamic-rdlc-generation.html

Dominic RajaSeelan said...

Nice..

Anonymous said...

great article.

Anonymous said...

instead of
Dim fs As New FileStream(FolderLocation & "Employee.xls", FileMode.Create)
fs.Write(bytes, 0, bytes.Length)
fs.Close()
'Set the appropriate ContentType.
Response.ContentType = "application/vnd.ms-excel"
'Write the file directly to the HTTP output stream.
Response.WriteFile(filepath)
you can use Response.AddHeader("Content-Disposition", "attachment; filename=Employee.xls"));
Response.AddHeader("Content-Length", bytes.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.BinaryWrite(bytes);

Anonymous said...

Great article!, here is the file less version in C#, put in the SampleReport.aspx (Step 11)

Jose Pons - 12/2007


Code Snippet:

protected void Page_SaveStateComplete(object sender, EventArgs e)
{
Microsoft.Reporting.WebForms.Warning[] warnings = null;
string[] streamids = null;
String mimeType = null ;
String encoding = null ;
String extension = null ;
Byte[] bytes = null ;

bytes = ReportViewer1.LocalReport.Render("PDF", "", out mimeType, out encoding, out extension, out streamids, out warnings);

Response.Clear();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.BinaryWrite(bytes);
Response.End();
}

Anonymous said...

Brilliant ! I've been trying to print directly to PDF for ages.
Thanks

Jessica Smith said...

Pons68 wraps this article up beautifully with code that allows you to render the PDF stream directly without first saving temporary files. Awesome!

Dr Hans Wetzlar said...

GREAT!!!!


you helped me a lot

thanks!

Anonymous said...

Today is 10 June 2011 and this code shows to be really useful !!!!! Thanks a lot buddy!!!