7

I have an ASPX page with many fields that generate PDF documents when I click an "export to PDF" button.

I'd now like to have a "print PDF" button in JavaScript that does something like this:

w = window.open(?);
w.print();
w.close();

where "?" will perform the same postback as my "export to PDF" button.

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Serge
  • 6,554
  • 5
  • 30
  • 56

3 Answers3

2

If you need to submit (postback) your form to new window you can try to change form target to fake, like:

var form = $("form");
form.attr("target", "__foo");

Submit a form.

form.submit();

And remove the target (setitmeout(,1) - pot the event in end of js "event-queue", in our case - after form submitting):

setTimeout(function () { form.removeAttr("target");  }, 1);

Also, before submit you can try to open window with __foo id for more styling, and the form will submitted (postback) in this window instead of a new one:

 var wnd = window.open('', '__foo', 'width=450,height=300,status=yes,resizable=yes,scrollbars=yes');

But I have no idea how to handle the submitted window and catch the onload or jquery's ready event. If you can do it share the workaround please and call the wnd.print(); You can play with iframes inside this wnd and maybe you will find a solution.

Updated:

Try to have a look in this prototype [tested in Chrome]:

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.0.min.js"></script>
    <script type="text/javascript">
        function PrintResult() {
            var wnd, checker, debug;

            debug = true;

            // create popup window
            wnd = window.open('about:blank', '__foo', 'width=700,height=500,status=yes,resizable=yes,scrollbars=yes');

            // create "watermark" __loading.
            wnd.document.write("<h1 id='__loading'>Loading...</h1>");

            // submit form to popup window
            $("form").attr("target", "__foo");
            setTimeout(function() { $("form").removeAttr("target"); }, 1);

            if (debug)
            {
                $("#log").remove();
                $("body").append($("<div id='log'/>"));
            }

            // check for watermark
            checker =
                setInterval(function () {
                    if (debug) $("#log").append('. ');

                    try {
                        
                        if (wnd.closed) { clearInterval(checker); return; }

                        // if watermark is gone
                        if (wnd.document == undefined || wnd.document.getElementById("__loading") == undefined) {
                            if (debug) $("#log").append(' printing.');
                            //stop checker
                            clearInterval(checker);

                            // print the document
                            setTimeout(function() {
                                wnd.print();
                                wnd.close();
                            }, 100);
                        }
                    } catch (e) {
                        // ooops...
                        clearInterval(checker);
                        if (debug) $("#log").append(e);
                    }
                }, 10);
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button runat="server" ID="ReportButton" OnClick="ReportRenderClick" Text="Export to PDF" OnClientClick="PrintResult()"/>
        <asp:Button runat="server" Text="Just a button."/>
    </div>
    </form>
</body>
</html>

And here is .cs file:

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void ReportRenderClick(object sender, EventArgs e)
    {
        Response.Clear();
        Thread.Sleep(2000);
        Response.ContentType = "application/pdf";
        Response.WriteFile("d:\\1.pdf");

        //Response.ContentType = "image/jpeg";
        //Response.WriteFile("d:\\1.jpg");

        //Response.Write("Hello!");
        Response.End();
    }
}
Community
  • 1
  • 1
Anton Levshunov
  • 408
  • 2
  • 9
  • I was close to that solution but sadly, a PDF need to be embed inside an html body to be printed through javascript. So in the end of the day, I still need to be able to have a url equivalent to the postback. – Serge Feb 26 '14 at 11:27
  • What kind of browsers you planning to support? – Anton Levshunov Feb 26 '14 at 14:03
  • The usual, Chrome, FireFox etc. – Serge Feb 26 '14 at 15:43
  • I add the example, maybe this prototype will helpful for you. I tested it in latest Chrome and it worked. But not sure about FF and etc. – Anton Levshunov Feb 26 '14 at 15:46
  • I had to read again my question to see your answer is correct. Yet my problem isn't solved, since I need a "url" that performs the postback. But I didn't know that for sure when I wrote the question. – Serge Feb 26 '14 at 15:57
  • I not 100% sure thet this is correct solution. It's just a direction and worked (tested in Chrome) example. And if you need an url it's looks like it is impossible, because postback is http post request. Best way is to store the pdf during postback at server side and render a link (or js script with opening of this link) to this pdf file (or to http handler with pdf id). And then manipulating with this link. – Anton Levshunov Feb 26 '14 at 16:03
  • I think the solution could lie in usage of JQuery's ajaxform but then, I have no idea how to make the (binary) result a src for the required embeded (pdf) element. – Serge Feb 26 '14 at 16:16
1

In your question tag you have the asp.net tag, so I guess you have access to some kind of ASP.NET server technology.

I would suggest to do it like this:

  1. Create a HttpHandler or an ASP.NET MVC action that returns a FileContentResult
  2. In your page, use this code to download and print the file (actually found it here, pasting it for future reference!)

    <a href="/path/to/file.pdf" onClick="window.print();return false">Click here to download the printable version</a>

There are some good tutorials on writing the server side:

Community
  • 1
  • 1
Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
  • It doesn't answer the "postback" issue. But thank you for the effort. – Serge Feb 26 '14 at 09:14
  • @Serge: well, it does. When removing this from ASPX, moving it to a `HttpHandler` will prevent any postback. – Patrick Hofman Feb 26 '14 at 09:15
  • @Serge: I would be glad to help you out. Tell me what your problem is at the moment and I will try to help. – Patrick Hofman Feb 26 '14 at 19:25
  • To print a PDF using javascript, it apparently needs to be embeded. To get the proper PDF the form's data need to be posted to the server. So I need a way to 1) send a full request to the server 2) put the result in an embeded element 3) print it – Serge Feb 27 '14 at 08:17
1

Open the pdf window with IFrame and you could do this:

Parent Frame content

<script>
window.onload=function() {
  window.frames["pdf"].focus();
  window.frames["pdf"].print();
}
</script>
<iframe name="pdf" src="url/to/pdf/generation"></iframe>

Inspired from this https://stackoverflow.com/a/9616706

Community
  • 1
  • 1
palanik
  • 3,601
  • 1
  • 13
  • 10
  • How do I get "url/to/pdf/generation"?? It requires data sent by the aspx page's form (postback). – Serge Feb 25 '14 at 13:00