views:

883

answers:

5

I've seen a few questions like this around SO but couldn't find anything that's right for me. The chain of events that I would like to occur is as follows:

  1. User clicks an ASP.NET button control
  2. This fires that button's onclick event, which is a function foo() in the C# codebehind
  3. foo() calls some other (unimportant) function which creates a PDF which ends up saved to the server's disk. That function returns the path to the PDF
  4. Without any other user interaction, once the PDF is generated, the print dialog box opens in the user's browser to print that PDF

What do I need to do to accomplish step 4? Ideally, it would be something I can call in foo(), passing in the path to the PDF, that will trigger the print dialog box in the user's browser (printing the PDF and not the page the from which the onclick fired).

I think that I might be able to forward to the URL of the PDF document, and embed some Javascript in the PDF that automatically prints it, but I would rather not - I don't necessarily want to print the PDF every time it's opened (in a browser). Any other good way to do this?

A: 

I did not try this, but it is an idea:

If you can read querystring parameters in javascript embedded in the PDF, then embed the javascript, and make the print function be conditional on a javascript parameter.

That way, if you redirect to, for instance, yourpdf.pdf?print, it will print, and if it is opened without the print parameter, it behaves as any other normal PDF would do.

driis
That sounds like it's going in the direction of even more complicated - it certainly could work, but I'd much rather keep the PDF independent of the behavior of the web page.
Matt Ball
A: 

If you want to go down the path of printing it as soon as it is opened:

There is a flag that you can insert into the PDF that forces it to open up the print dialog as soon as the PDF is opened. I did this ages ago using the abcpdf component in classic ASP, the code looked something like:

Set oDoc = Server.CreateObject("ABCpdf4.Doc")
oDoc.SetInfo oDoc.Root, "/OpenAction", "<< /Type /Action /S /Named /N /Print >>"

Obviously the code would look different depending on which PDF creation tool you are using...

Vdex
Would I tell the user's browser to open the PDF after it's generated by calling Response.Redirect("[url to PDF]")?
Matt Ball
Yes, or you can response.writefile it and set all the Response.ContentType and other headers for the page to serve a PDF.
Vdex
+1  A: 
Response.Clear()
Response.AddHeader("Content-Disposition", "attachment; filename=myfilename.pdf")
Response.ContentType = "application/pdf"
Response.BinaryWrite(ms.ToArray())

Where ms = a memorystream containing your file (you don't have to write it to disk in-between.)

Otherwise if you absolutely have to deal with coming from the hard disk, use:

Response.WriteFile("c:\pathtofile.pdf")
Nicholas H
I have used something similar to this and it worked great, no extra files was also a plus. Make sure to use the system path as shown above not the local web path.
corymathews
A: 

The solution I arrived at was this:

Create a new ASP.NET web form (I called mine BinaryData.aspx) to serve as a placeholder for the PDF. In the code behind, the only method should be Page_Load, which looks like:

protected void Page_Load(object sender, System.EventArgs e)
{
    //Set the appropriate ContentType.
    Response.ContentType = "Application/pdf";
    Response.AppendHeader("Pragma", "no-cache"); 
    Response.AppendHeader("Cache-Control", "no-cache");
    //Get the physical path to the file.
    string FilePath = (string)Session["fileLocation"];
    if ( FilePath != null )         
    {
        string FileName = Path.GetFileName(FilePath);

        Response.AppendHeader("Content-Disposition", "attachment; filename="+FileName);

        //Write the file directly to the HTTP content output stream.
        Response.WriteFile(FilePath);
        Response.End();
    }
}

The PDF is passed in to the page through the Session variable named "fileLocation". So, all I have to is set that variable, and then call Response.Redirect("BinaryData.aspx").

It doesn't automatically print, but it triggers the download of the PDF without leaving the current page (which is good enough for me).

Matt Ball
A: 

Thanks for the answer Vdex. Here is the iText/C# version.

PdfAction action = new PdfAction();
action.Put(new PdfName("Type"), new PdfName("Action"));
action.Put(new PdfName("S"), new PdfName("Named"));
action.Put(new PdfName("N"), new PdfName("Print"));

PdfReader reader = new PdfReader(ReportFile.FullFilePath(reportFile.FilePath));

PdfStamper stamper = new PdfStamper(reader, Response.OutputStream);
stamper.Writer.CloseStream = false;
stamper.Writer.SetOpenAction(action);
stamper.Close();
Karson