0

I am attempting to download an SSRS report from a MVC C# application. I have an HttpResponseBase object and am sending it back to the client to be displayed/downloaded by the user, however, when the response is sent back to the client, I am getting symbols only.

Can some one please help clarify what I am missing upon the success of the ajax call?

I have attempted to use an option which worked with some success, however, the URL is too long when selecting certain parameters.

My controller is as follows:

[HttpPost]
public ActionResult DownloadReportData(string reportName, string reportPath, string reportParams, string repID, string book, string exportFormat)
        {
            string extension = string.Empty;
            string fileName = reportName + "_" + (book.Length > 0 ? "" + book + "_" : "") + repID;

            Dictionary<string, string> dc = new Dictionary<string, string>();
            if (reportParams.Length > 0)
            {
                string[] param = reportParams.Split(';');
                int i = 0;
                while (i < param.Length)
                {
                    dc.Add(param[i].Split('=')[0], param[i].Split('=')[1]);
                    i += 1;
                }
            }

            //PDF for pdf export, EXCEL for excel export
            byte[] bytes = autil.Reporting.ReportsManager.GenerateReport(reportPath, dc, exportFormat);

            Response.ClearContent();

            if (exportFormat.ToLower() == "pdf")
            {
                Response.ContentType = "application/pdf";
                extension = ".pdf";
                //Response.AppendHeader("Content-Disposition", "inline;filename=" + fileName + "" + extension + "");
                Response.AppendHeader("Content-Disposition", "attachment;filename=" + fileName + "" + extension + "");
            }
            else if (exportFormat.ToLower() == "excel")
            {
                //Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                Response.ContentType = "application/vnd.ms-excel";
                extension = ".xls";
                Response.AppendHeader("Content-Disposition", "attachment;filename=" + fileName + "");

            }

            //Response.AppendHeader("Content-Disposition", "inline;filename=" + fileName + "" + extension + "");
            Response.BufferOutput = true;
            Response.AddHeader("Content-Length", bytes.Length.ToString());
            Response.BinaryWrite(bytes);
            Response.End();

            //return null;
            return Json(Response);
        }

My view is as follows:

<div id="target"></div>

My javascript (ajax call) is as follows:

<script>
 $.ajax({
            type: 'POST',
            url: '@Url.Action("DownloadReportData", "Reports")',
            data:
            {
                reportName: reportName,
                reportPath: reportPath,
                reportParams: reportParams,
                book: bookCode,
                exportFormat: exportType
            }
            , success: function (data) {
                $("#target").append($("<iframe>", {
                    srcdoc: data
                }));                

                if (data.error == "none") {
                    alert("success" + data);
                }
            }


        });

</script>

I am expecting either a downloaded version of the report or a prompt to Open (inline) or Save As to appear once the call is completed.

I am currently experiencing the following to be displayed:

%PDF-1.3 1 0 obj [/PDF /Text /ImageB /ImageC /ImageI] endobj 5 0 obj << /Length 1968 /Filter /FlateDecode >> stream x��[]o7}G��DZ��{�7��REi�H�Z�!�R�]�I������kdz��i#D���{αϽ���9��7h��|5�SM6�Y��Ҍt�t�J���4�DkC�$����9������.{�����y�� =����'�������Q�j ���]��]^����E���gG�^M�c�ʨ��/�A(�<�����a��"�>y�����b/��Ś�

MTL323
  • 177
  • 3
  • 14
  • 1
    You can't put a PDF into a
    it would just be gibberish as you're seeing. You need to embed a PDF viewer into your html page or have the server return an HTML render of the PDF
    – Jon Sep 11 '19 at 15:50
  • It doesn't need to render right away. It can be an Excel or PDF download. This was just a visual of what the response is that is being sent back to the ajax call. – MTL323 Sep 11 '19 at 15:52
  • 4
    I would just point to the SSRS report location in your ajax call:window.open('ssrslink', '_blank'); and display the report. Within the SSRS server, the user can download if they want. – user10728126 Sep 11 '19 at 15:55
  • you cant use ajax to download a file in this way – jamesSampica Sep 11 '19 at 15:56
  • Unfortunately, that is not what the business wants. They don't want the users to access SSRS so I am attempting to mimic the download functionality for the user. – MTL323 Sep 11 '19 at 15:57
  • Maybe I'm overthinking this. I may look to stream the HttpResponse object instead? – MTL323 Sep 11 '19 at 16:07
  • 1
    You can get the byte array from SSRS and then write those bytes to a file location using i/o: maybe this will help: https://stackoverflow.com/questions/40338883/download-ssrs-report-and-save-in-specific-location-c-unauthorized – user10728126 Sep 11 '19 at 16:09
  • 1
    I believe you'd better return your data from the controller in base64 encoded form and then build download link on frontend using `data url`. For more on downloading files using `data url`s see here: https://stackoverflow.com/questions/3916191/download-data-url-file – Oleksandr Tyshchenko Sep 11 '19 at 17:05
  • Also you will need to return a FileResult object instead of json in your controller if you need the save as popup. – CodingSlayer Sep 12 '19 at 07:51

1 Answers1

0

I faced the same issue when I was trying to download excel from my ajax call. After many days I got the answer that you can't (I read it somewhere on SO). So I converted my ajax call to this

<div class="col-md-3">
      @Html.ActionLink("Export Report", "ExportExcel", "Training",
                        new { }, new { @class = "btn btn-danger" })
</div>

and after that my code worked. You might have to make a few changes in order for this to work. I hope this help.

Sanjay Kumar
  • 198
  • 2
  • 3
  • 12