Generate a PDF that automatically prints
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.
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.
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;
}
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.
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));
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);
}
}
精彩评论