Telerik-Kendo-UI : How to force exported PDF to open in a browser

kendo ui open export pdf in new browser

Recently, I was experimenting with Telerik Kendo UI HTML Framework and in particular, I was exploring the PDF Export feature that allows you to convert HTML content into a PDF. I wanted for generated PDF to open in a new browser tab, but all the examples I found on the web worked in such a way that the file was downloaded on your computer. After a little research, I was able to find the solution that makes the PDF open in the browser in a new tab and this is the focus of this tutorial.

The example here uses ASP.NET MVC with jQuery code on the client-side, but you should also find it useful when using other technologies.

Note:This solution will not work in the Edge browser.

Here is one example on Telerik website on how to export page content to PDF, SVG and image. The part of code for PDF is shown below. The code is using jQeury and is inside an ASP.NET MVC view:

    $(".export-pdf").click(function () {
        // Convert the DOM element to a drawing using kendo.drawing.drawDOM
        kendo.drawing.drawDOM($(".content-wrapper"))
        .then(function (group) {
            // Render the result as a PDF file
            return kendo.drawing.exportPDF(group, {
                paperSize: "auto",
                margin: { left: "1cm", top: "1cm", right: "1cm", bottom: "1cm" }
            });
        })
        .done(function (data) {
            // Save the PDF file
            kendo.saveAs({
                dataURI: data,
                fileName: "HR-Dashboard.pdf",
                proxyURL: "@Url.Action("Pdf_Export_Save")"
            });
        });
    });

Let’s examine the highlighted lines of the above code.

  • Line 3:

    kendo.drawing.drawDOM($(".content-wrapper"))
    

    With drawDOM function, we set the DOM element that contains the content we want to save as PDF.

  • Line 6:

    return kendo.drawing.exportPDF(group, {
    

    Inside exportPDF function, we set the various PDF parameters.

  • Line 13:

    kendo.saveAs({
    

    After the PDF is successfully generated, the .done function is executed and inside it, the data is saved with Kendo saveAs function. In lines 14, 15, 16, the code sets various parameters for the saveAs function, one of which is proxyURL parameter that is discussed next.

  • Line 16:

    proxyURL: "@Url.Action("Pdf_Export_Save")"
    

    The proxyURL is usually used for browsers that are not capable saving files locally, for example, Internet Explorer 9. We supply it the URL of the server proxy, that will stream the file to the end user. In the above Telerik example, proxyURL points to the ASP.NET MVC action method named Pdf_Export_Save.

Now let’s examine the code for that Pdf_Export_Save action method inside a controller. You can find this code in the Telerik example page when you click on IndexController.cs tab.

[HttpPost]
public ActionResult Pdf_Export_Save(string contentType, string base64, string fileName)
{
   var fileContents = Convert.FromBase64String(base64);

   return File(fileContents, contentType, fileName);
}

We will change the code of the above Telerik example, so that instead of saving the PDF file named HR-Dashboard.pdf on your computer, it opens the PDF in the browser in the new tab.

Changes needed for PDF to open in the browser

To force PDF to open in browser's built-in PDF viewer, we need to have the following response headers:

  • Content-Disposition: inline; filename=HR-Dashboard.pdf
  • Content-Type: application/pdf

When a browser downloads a PDF file, what we have instead is Content-Disposition: attachment. This is where the action method of proxyURL parameter comes into play. We can modify the response headers inside this method.

Forcing ProxyURL action to be called every time

As it was just mentioned, we can use the action method specified by proxyURL parameter to modify our headers, but there is a problem. If you remember, The ProxyURL parameter is only used for browsers that don’t support saving files locally, like in IE9. Luckily, kendo.saveAs method has a parameter just for this case. What we need to use is the forceProxy parameter that forces all the browsers to call the URL inside proxyURL parameter.

We add it in the list of parameters for kendo.saveAs like this (line 5):

            kendo.saveAs({
                dataURI: data,
                fileName: "HR-Dashboard.pdf",
                proxyURL: "@Url.Action("Pdf_Export_Save")",
                forceProxy: true
            });
Note: To learn more about ForceProxy parameter, check this Kendo for jQuery manual page from Telerik.

Now that the server proxy inside ProxyURL will always be called, it is time to modify the response headers.

Using ProxyURL action to insert custom response headers

We will use Response.Headers.Add method to add our custom headers. The contentType parameter already contains one necessary header Content-Type: application/pdf, so all we need to change is Content-Disposition header. Here is our modified Pdf_Export_Save method from previous section:

[HttpPost]
public ActionResult Pdf_Export_Save(string contentType, string base64, string fileName)
{
    var fileContents = Convert.FromBase64String(base64);
    Response.Headers.Add("Content-Disposition", "inline; filename=" + fileName);
    return File(fileContents, contentType);
}

The changes are as follows:

  • Line 5:

    Response.Headers.Add("Content-Disposition", "inline; filename=" + fileName);
    

    Here we set Content-Disposition header with value inline. It also contains filename.

    Note: If you get PlatformNotSupportedException exception, try using Response.AddHeader() instead.
  • Line 6:

    return File(fileContents, contentType);
    

    Here we changed the overloaded method of File to the one that accepts only two arguments. The original code used the overloaded method with three parameters, the third being the parameter for a filename.

    Note: Without the change in line 6, the File method with three parameters will send one Content-Disposition header automatically (because of the third argument) and another Content-Disposition would be added by us with Response.Headers.Add method. This causes the browsers to report the following error:

    • In firefox:

      Corrupted Content Error

      The page you are trying to view cannot be shown because an error in the data transmission was detected.

    • In Chrome:

      The page isn’t working

      ... sent an invalid response.
      ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION

So now that we made the necessary changes in our action method that opens PDF file in a browser on the same page, let’s force it to open in a new tab instead.

Forcing the ProxyURL to open in new tab

The kendo.saveAs method also has a parameter proxyTarget that gives us an option where to display the document that returns from the proxy. We add it in the list of parameters for kendo.saveAs like so (line 6):

            kendo.saveAs({
                dataURI: data,
                fileName: "HR-Dashboard.pdf",
                proxyURL: "@Url.Action("Pdf_Export_Save")",
                forceProxy: true,
                proxyTarget: "_blank"
            });

Now, the PDF will open in the browser on another tab.

Issue with Chrome pop-up blocking feature

If the PDF is not generated quickly, the Chrome browser might activate popup blocker for the new tab.
Chrome Pop-up blocker
This can be avoided, if we do the following modifications to the code:

  1. Add code that opens a new window before calling the kendo.drawing.drawDOM() function:
        $(".export-pdf").click(function () {
            // Convert the DOM element to a drawing using kendo.drawing.drawDOM
            window.open('', 'mypdftab');
            kendo.drawing.drawDOM($(".content-wrapper"))
            ....
    
  2. Change value of proxyTarget to the name of that window:
                        ...
                        forceProxy: true,
                        proxyTarget: "mypdftab"
                    });
    

The PDF should now open in a new tab on Chrome without activating the "popup blocked" feature.

Conclusion

Creating PDF files using Kendo UI HTML Framework is easy. In this tutorial, we took one such example from the Telerik website that demonstrates how to save page content to PDF file. The PDF in that example is treated as an attachment and will be downloaded to your computer. But to open the PDF in the browser's internal PDF viewer instead, all we need is to change a response header. We do that inside the action method that the proxyURL parameter points to. Finally, we can use a forceProxy parameter to open them in a new tab.

4 Comments

Click HERE to add your Comment
  1. Harry
    December 1, 2017
  2. Michele O'Dell
    December 4, 2017
    • admin
      December 5, 2017
  3. Selvakumar
    January 31, 2019

Write a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.