Generate a PDF that automatically prints
Asked Answered
P

5

11

I have a ASP.NET Web application that generates a PDF. I am using iTextSharp. What happens is that you click a button and it downloads. My employer want to be able to click the button and have it open with the print dialog.

Pilsner answered 29/5, 2011 at 13:31 Comment(8)
I'm pretty sure this isn't possible. I'd recommend not generating a PDF, but a web page that triggers window.print() as soon as it's loaded.Pegeen
@Samir The problem is that it really needs to be a pdf because it is label that is printed by a zebra printer.Pilsner
@Joe Tyman: Can it be an image? A PNG or something? You could put that on the web page.Pegeen
@Samir the only worry I have would be scaling. Since I am working with barcodes that could be a huge issue.Pilsner
@Joe: Scaling what? If you're worried about dpi, I believe you can customize that when creating PNGs independently of the image size.Pegeen
@Samir I worried about the distortion, or the header on printing HTML page. It is hard when you want to print 2.65x1 inch label.Pilsner
@Joe: The header will get you. I have no idea how to make that go away.Pegeen
Have a look at [this post for printing pdf][1] [1]: #16016094Sweeping
B
13

Method 1: Using embedded javascript inside your PDF files You can try creating an iText PDFAction object with a javascript call this.print(false) (you can use new PdfAction(PdfAction.PRINTDIALOG) for this), and associate it with the OpenAction event of your pdf file.

The code in iText Java should look like this:

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("file.pdf"));
...
PdfAction action = new PdfAction(PdfAction.PRINTDIALOG);
writer.setOpenAction(action);
...

It should not be too diferent in C#.

As a side note, this is also possible with Amyuni PDF Creator .Net by setting the attribute "AutoPrint" to TRUE in the document class (usual disclaimer applies).

acPDFCreatorLib.Initialize();
acPDFCreatorLib.SetLicenseKey("Amyuni Tech.", "07EFCDA00...BC4FB9CFD");
Amyuni.PDFCreator.IacDocument document = pdfCreator1.Document;

// Open a PDF document from file
System.IO.FileStream file1 = new System.IO.FileStream("test_input.pdf", FileMode.Open, FileAccess.Read, FileShare.Read);

IacDocument document = new IacDocument(null);

if (document.Open(file1, ""))
{
    //Set AutoPrint
    document.Attribute("AutoPrint").Value = true;

    //Save the document
    System.IO.FileStream file2 = new System.IO.FileStream("test_output.pdf", System.IO.FileMode.Create, System.IO.FileAccess.Write);
    document.Save(file2, Amyuni.PDFCreator.IacFileSaveOption.acFileSaveView);
}

// Disposing the document before closing the stream clears out any data structures used by the Document object
document.Dispose();

file1.Close();

// terminate library to free resources
acPDFCreatorLib.Terminate();

This approach requires the PDF file to be opened in a reader that will take care of printing, and it has the drawback that if the file is saved locally, every time the file is opened later on it will show the print dialog.

Method 2: Using javascript from the browser to communicate with the reader that shows the file.
I found this other approach in this SO question that might worth trying:

<html>
<script language="javascript">
timerID = setTimeout("exPDF.print();", 1000);
</script>
<body>
<object id="exPDF" type="application/pdf" data="111.pdf" width="100%" height="500"/>
</body>
</html>

The idea is to use javascript in the browser to instruct the PDF reader to print the file. This approach will work on PDF files embedded in a HTML page.

Billie answered 29/5, 2011 at 13:51 Comment(4)
I will try this on Tuesday(long weekend) and see if that works. The code is not that different than C#.Pilsner
I am glad it worked!. Please be aware that this approach will only work if javascript is enabled on the PDF Reader installed on the client side.Billie
It is a very controlled environment that is using this program, so that is really not an issue. I'll make everybody install PDF X-Change, which what I used to test this application.Pilsner
Perfect !! Method 1. this is robust solution.Nonintervention
U
4

Another solution on this site... I use this solution and work great

I have a PDF Stream from Crystal report, and i add the openaction with pdfsharp

link : http://www.vo1dmain.info/pdfsharp-howto-inject-javascript-into-pdf-autoprinting-functionality#comments

public static MemoryStream AddAutoPrint(Stream pdfStream, bool ShowPrintDialog = true, int NumCopies = 1)
{
  PdfSharp.Pdf.PdfDocument doc = PdfSharp.Pdf.IO.PdfReader.Open(pdfStream, PdfSharp.Pdf.IO.PdfDocumentOpenMode.Import);
  PdfSharp.Pdf.PdfDocument outputDocument = new PdfSharp.Pdf.PdfDocument();

  for (int idx = 0; idx < doc.PageCount; idx++)
  {
    PdfSharp.Pdf.PdfPage p = doc.Pages[idx];
    outputDocument.AddPage(p);
  }

  outputDocument.Info.Author = "author name";

  string JSScript = string.Empty;
  JSScript += "var pp = this.getPrintParams(); ";

  if(NumCopies > 0)
  {
    JSScript += "pp.NumCopies = " + NumCopies.ToString() + "; ";
  }

  if(!ShowPrintDialog)
  {
     JSScript += "pp.interactive = pp.constants.interactionLevel.automatic; ";
  }


  JSScript += "this.print({printParams: pp}); ";


  PdfSharp.Pdf.PdfDictionary dictJS = new PdfSharp.Pdf.PdfDictionary();
  dictJS.Elements["/S"] = new PdfSharp.Pdf.PdfName("/JavaScript");
  //dictJS.Elements["/JS"] = new PdfSharp.Pdf.PdfStringObject(outputDocument, "print(true);");
  //dictJS.Elements["/JS"] = new PdfSharp.Pdf.PdfStringObject(outputDocument, "this.print({bUI: false, bSilent: true, bShrinkToFit: true});");
  //dictJS.Elements["/JS"] = new PdfSharp.Pdf.PdfStringObject(outputDocument, "var pp = this.getPrintParams(); pp.NumCopies = 2; pp.interactive = pp.constants.interactionLevel.automatic; this.print({printParams: pp});");
  dictJS.Elements["/JS"] = new PdfSharp.Pdf.PdfStringObject(outputDocument, JSScript);


  outputDocument.Internals.AddObject(dictJS);

  PdfSharp.Pdf.PdfDictionary dict = new PdfSharp.Pdf.PdfDictionary();
  PdfSharp.Pdf.PdfArray a = new PdfSharp.Pdf.PdfArray();
  dict.Elements["/Names"] = a;
  a.Elements.Add(new PdfSharp.Pdf.PdfString("EmbeddedJS"));
  a.Elements.Add(PdfSharp.Pdf.Advanced.PdfInternals.GetReference(dictJS));

  outputDocument.Internals.AddObject(dict);

  PdfSharp.Pdf.PdfDictionary group = new PdfSharp.Pdf.PdfDictionary();
  group.Elements["/JavaScript"] = PdfSharp.Pdf.Advanced.PdfInternals.GetReference(dict);

  outputDocument.Internals.Catalog.Elements["/Names"] = group;

  MemoryStream ms = new MemoryStream();

  outputDocument.Save(ms, false);

  return ms;
}
Unwearied answered 18/7, 2013 at 19:43 Comment(0)
N
3

As mentioned by yms, you can generate a PDF that has JavaScript or a "Named" PDF action that shows the Print dialog when the document is opened. We have demonstrated this using our product Gnostice PDFOne .NET in the article Create an Auto-Print PDF. You could do the same in iText I guess. If Adobe Reader is registered as PDF plugin in the browser, then both options will work.

HTML Javascript option seems to work only in IE.

DISCLAIMER: I work for Gnostice.

Noe answered 30/5, 2011 at 4:50 Comment(0)
S
2

In iTextSharp do:

PdfDocument = pdfDoc = new Document(PageSize.LETTER);
// create and open the new pdf document for writing
FileStream fspdfDoc = new FileStream(pdfDocFileName, FileMode.Create, 
FileAccess.ReadWrite);
PdfWriter pdfW = PdfWriter.GetInstance(pdfDoc, fspdfDoc);
pdfDoc.Open();
pdfW.AddJavaScript(PdfAction.JavaScript("this.print(true);\r", pdfW));
Smuts answered 29/11, 2018 at 14:42 Comment(0)
S
0

HOW about good old fashion OLE? It is still supported by most all document layers I am aware of... IN C# I normally do something like this.. where PDF, RTF, DOC, XLS... does not matter... they all print..

public void HandlePresentation(string fullFilePath, bool viewOnScreen, bool autoPrint)
{
    ProcessStartInfo info = new ProcessStartInfo(fullFilePath);
    if (autoPrint)
    {
        info.Verb = "Print";
        info.WindowStyle = ProcessWindowStyle.Hidden; // not normally required
        Process.Start(info);
        info.Verb = string.Empty;
    }

    if (viewOnScreen)
    {
        info.WindowStyle = ProcessWindowStyle.Normal;
        Process.Start(info);
    }
}
Stakhanovism answered 5/3, 2017 at 14:39 Comment(2)
The original questions specifies "ASP.NET Web application". Ole does not help in this scenario since you do not have access to it on a web page.Billie
Thanks for that clarification... perfectly correct 'from web page' where scripting is assumed application layer... however using ASP.NET Web Application does imply managed code... making OLE a possibility (depending on ACL)Stakhanovism

© 2022 - 2024 — McMap. All rights reserved.