Danger_Fox
Danger_Fox

Reputation: 449

Create PDF server side and open in new browser window or tab

I'm trying to create a PDF on the server and then open it in a new tab on the browser when a button is clicked. The PDF generates fine, but I can't get the browser to open it without downloading. In IE it doesn't recognize the file and in Chrome it prompts the user for a download. Any help is appreciated. My code is below:

C# Controller

public string CreateCustomReport()
{
    var doc = new Document();
    MemoryStream m = new MemoryStream();

    try
    {
        string query = "";
        PdfWriter.GetInstance(doc, m).CloseStream = false;

        SqlConnection conn = new SqlConnection(conn);
        conn.Open();

        SqlCommand cmd = new SqlCommand(query, conn);
        cmd.CommandType = CommandType.Text;
        SqlDataReader sqdr = cmd.ExecuteReader();

        doc.Open();
        PdfPTable table = new PdfPTable(4);
        PdfPCell cell = new PdfPCell(new Phrase(customTitle));
        cell.Colspan = 4;
        table.AddCell(cell);
        table.AddCell(groupBy);
        table.AddCell(col1);
        table.AddCell(col2);
        table.AddCell("Event");
        while (sqdr.Read())
        {
            table.AddCell(Convert.ToString(sqdr["GroupBy"].ToString()));
            table.AddCell(Convert.ToString(sqdr["Col1"].ToString()));
            table.AddCell(Convert.ToString(sqdr["Col2"].ToString()));
            table.AddCell(Convert.ToString(sqdr["Events"].ToString()));
        }

        doc.Add(table);
        doc.Close();
    }
    catch (Exception)
    {

    }
    return System.Convert.ToBase64String(m.ToArray());
}

jQuery

  $.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify(params),
    url: '@Url.Action("CreateCustomReport")',
    error: function(error) {
        debugger;
        alert("Search failed.");
    },

    success: function(data) {
        var openpdf = $('<a id="openpdf" download="Report.pdf" href="data:application/pdf;base64,' + data + '" target="new">');
        $('body').append(openpdf);
        document.getElementById("openpdf").click();
        $("#openpdf").remove();


    }
});

Upvotes: 2

Views: 1777

Answers (2)

Kurorion
Kurorion

Reputation: 108

Nava's answer doesn't solve OP's problem as it still downloads the file rather than opening it in a new tab. You'll need to modify the response header to make that happen.

public FileResult CreateCustomReport()
{
    ...
    Response.AppendHeader("Content-Disposition", "inline; filename=Out.pdf");
    return File(m.ToArray(), "application/pdf" );
}

And then in your view:

<a href="@Url.Action("CreateCustomReport")" target="_blank">Download PDF</a>

If you want to hide the download link after it has been clicked, you can just add an onclick to your anchor:

<a href="@Url.Action("CreateCustomReport")" target="_blank" onclick="this.style.display='none'">Download PDF</a>

Edit: I can't comment on the other answer, but reading from your comment it seems you need to pass arguments by a POST request. If you really need to do this by POST, then you could use a hidden form and target="_blank" attribute. If you can do it by GET, then you can just embbed the data into your URL and then you can just use a simple anchor tag.

Upvotes: 2

Andy T
Andy T

Reputation: 9881

You are returning a Base-64 encoded representation of the generated PDF then using that string to create a link and setting the href inline. Then you trigger a click on the link. Seems very complicated.

I would take a different approach...

Have the server return the PDF bytes (I'm assuming PdfWriter has a way to access the byte[]):

public ActionResult CreateCustomReport()
{
    byte[] contents = doc.GetBytes(); //?????
    return File(contents, "application/pdf", "test.pdf");
}

Then, do not use AJAX call and instead redirect the user to the url:

<a href="@Url.Action("CreateCustomReport")" target="_blank">Download PDF</a>

This approach does not depend on JavaScript and will work on IE or Chrome without prompting the user to download/save the file. And the PDF will display in a new browser window/tab.

Upvotes: 4

Related Questions