How to use Crystal Reports in ASP.NET MVC

Introduction

Crystal reports is a best way for show reports in project and it’s also free, so we offen uses it in our project. But the crystal reports are base on webform, how about we use it in razor view in ASP.NET MVC?

The point is use webform in mvc and call it by iframe 🙂

 

Using the code

1. For use crystal report in MVC project, we need to add below package from NuGet:

Crystal.Reports
Crystal.Reports.Essentials
CrystalDecisions.CrystalReports.Engine
CrystalDecisions.ReportAppServer

2. Add below settings in web.config

1) under <appSettings>:

<add key="CrystalImageCleaner-AutoStart" value="true" />
<add key="CrystalImageCleaner-Sleep" value="60000" />
<add key="CrystalImageCleaner-Age" value="120000" />

2) under <system.web>:

<httpHandlers>
   <add verb="GET" path="CrystalImageHandler.aspx" type="CrystalDecisions.Web.CrystalImageHandler, CrystalDecisions.Web, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" />
</httpHandlers>

3) under <system.webServer>:

 <handlers>
      <remove name="ChartImageHandler" />
      <add name="CrystalImageHandler.aspx_GET" verb="GET" path="CrystalImageHandler.aspx" type="CrystalDecisions.Web.CrystalImageHandler, CrystalDecisions.Web, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" preCondition="integratedMode" />
</handlers>

3. Because we only can use crystal report in a webform, so we have to create a webform for the report viewer at first:
Create a webform and name : ReportViewer.aspx in Reports folder and add the CrystalReportViewer as below:

in page header:

<%@ Register assembly="CrystalDecisions.Web, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" namespace="CrystalDecisions.Web" tagprefix="CR" %>

in the body:

<CR:CrystalReportViewer ID="CRViewer" runat="server"  Width="100%" Height="100%"  AutoDataBind="True" ToolPanelView="None" EnableParameterPrompt="false"  />

we need to get the parameters and call backend function to print the report in this file:

protected void Page_Load(object sender, EventArgs e)
 {
     try
     {
         //report parameters
         var paramList = Request["Params"].Trim();
         //report file(.rpt) name
         var reportName = Request["ReportName"].Trim();
         //save as to excel,pdf or word's file name
         var saveName = Request["SaveName"].Trim();
         //report type for pdf, excel, word or inline preview
         var reportType = Request["ReportType"].Trim();
         //report file path, base on ~/Reports folder
         var reportPath = Request["ReportPath"].Trim().Replace('-', '/');

         //set the report file path
         var reportFile = Server.MapPath(string.Format("~/Reports/{0}/{1}.rpt", reportPath, reportName));
         //for save report file name
         var saveFileName = saveName + DateTime.Now.ToString("_yyyy-MM-dd");

         ReportType reType = ReportType.InlineView;
         switch (reportType.ToLower())
         {
             case "pdf":
                 reType = ReportType.ToPDFFile;
                 break;
             case "excel":
                 reType = ReportType.ToExcel;
                 break;
             case "word":
                 reType = ReportType.ToWord;
                 break;
         }


         if (!IsPostBack)
         {
             if (ReportSource.Instance.ReportData != null)
             {
                 //if ReportData is not null then it will use datatable source to fill the report
                 ReportHandler.PrintDataSourceReport(CRViewer, reportName, reportFile, paramList, ReportSource.Instance.ReportData, reType, saveFileName, Page.Response);
             }
             else
             {
                 //otherwise just call the stored procedure to fill the report
                 ReportHandler.PrintSPReport(CRViewer, reportName, reportFile, paramList, reType, saveFileName, Page.Response);
             }
         }
     }
     catch (Exception ex)
     {
         //you can write error log here
         throw new Exception(ex.Message);
     }
 }

I have created a ReportHandler for connect the database for print report, you can download the source code for the details.

4. Create an action and view for testing. I just create the action name with TestingReport in Home controller, and the view file is /Home/TestingReport.cshtml. We need to call the report viwer via iframe as below in the view:

<div class="form-horizontal">
    <div class="row">
        <div class="col-md-10">
            <div class="form-group">
                <div class="col-md-2">
                    <Button id="previewBtn" class="btn btn-primary reportBtn" onclick="PrintReport('inline');">Preview Report</Button>
                </div>
                <div class="col-md-2">
                    <Button id="excelBtn" class="btn btn-info reportBtn" onclick="PrintReport('excel');">Export to Excel</Button>
                </div>
                <div class="col-md-2">
                    <Button id="pdfBtn" class="btn btn-info reportBtn" onclick="PrintReport('pdf');">Export to PDF</Button>
                </div>
                <div class="col-md-2">
                    <Button id="wordBtn" class="btn btn-info reportBtn" onclick="PrintReport('word');">Export to Word</Button>
                </div>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-md-12">
            <iframe id="ReportFrame" src="" width="100%" height="1000" style="border:none"></iframe>
        </div>
    </div>
</div>

and handle the print button event in javascript:

function PrintReport(printType) {
    if (printType == 'inline') {
        //you can add the loading.....
        // $.blockUI({ message: '<h3><img src="@Url.Content("~/Content/images/busy.gif")" /> Please wait a moment...</h3>' });
    }

    //var params = "param1=;param2=";//create the parameters for report
    var params = '';
    //load the report by iframe 
    $("#ReportFrame").attr("src", "@Url.Content("~/Reports/ReportViewer.aspx?Params=")" + params + "&ReportName=Testing&SaveName=Testing Report&ReportType=" + printType + "&ReportPath=Demo");

    $('#ReportFrame').load(function () {
        //and stop the loading after load
        // $.unblockUI();
    });
}

5. Access the action, you will see the report page:

 

6. Source code download:

https://github.com/coderblog-winson/CoderBlog.Demo.CrystalReport

42,569 total views, 64 views today

Do you like this post?
  • Fascinated
  • Happy
  • Sad
  • Angry
  • Bored
  • Afraid

winson

Leave a Reply

coder-blog-1
shares