I've generated a pdf using iTextSharp and I can preview it very well in ASP.Net but I need to send it directly to printer without a preview. I want the user to click the print button and automatically the document prints.
I know that a page can be sent directly to printer using the javascript window.print() but I don't know how to make it for a PDF.
Edit: it is not embedded, I generate it like this;
...
FileStream stream = new FileStream(Request.PhysicalApplicationPath + "~1.pdf", FileMode.Create);
Document pdf = new Document(PageSize.LETTER);
PdfWriter writer = PdfWriter.GetInstance(pdf, stream);
pdf.Open();
pdf.Add(new Paragraph(member.ToString()));
pdf.Close();
Response.Redirect("~1.pdf");
...
And here I am.
Finally I made it, but I had to use an IFRAME, I defined an IFrame in the aspx and didn't set the src property, in the cs file I made generated the pdf file and set the src property of the iFrame as the generated pdf file name, like this;
Document pdf = new Document(PageSize.LETTER);
PdfWriter writer = PdfWriter.GetInstance(pdf,
new FileStream(Request.PhysicalApplicationPath + "~1.pdf", FileMode.Create));
pdf.Open();
//This action leads directly to printer dialogue
PdfAction jAction = PdfAction.JavaScript("this.print(true);\r", writer);
writer.AddJavaScript(jAction);
pdf.Add(new Paragraph("My first PDF on line"));
pdf.Close();
//Open the pdf in the frame
frame1.Attributes["src"] = "~1.pdf";
And that made the trick, however, I think that i should implement your solution Stefan, the problem is that I'm new to asp.net and javascript and if I don't have a complete source code I could not code your suggestion but at least is the first step, I was very surprised how much code in html and javascript i need to learn. Thnx.
Is the pdf embedded in the page with embedd-tag or just opened in a frame or how are you showing it?
If its embedded, just make sure that the object is selected and then do a print().
Get the ref to the embedded document.
var x = document.getElementById("mypdfembeddobject");
x.click();
x.setActive();
x.focus();
x.print();
It's a little more tricky if you're using pdfsharp but quite doable
PdfDocument document = new PdfDocument();
PdfPage page = document.AddPage();
XGraphics gfx = XGraphics.FromPdfPage(page);
XFont font = new XFont("Verdana", 20, XFontStyle.BoldItalic);
// Draw the text
gfx.DrawString("Hello, World!", font, XBrushes.Black,
new XRect(0, 0, page.Width, page.Height),
XStringFormats.Center);
// real stuff starts here
// current version of pdfsharp doesn't support actions
// http://www.pdfsharp.net/wiki/WorkOnPdfObjects-sample.ashx
// so we got to get close to the metal see chapter 12.6.4 of
// http://partners.adobe.com/public/developer/pdf/index_reference.html
PdfDictionary dict = new PdfDictionary(document); //
dict.Elements["/S"] = new PdfName("/JavaScript"); //
dict.Elements["/JS"] = new PdfString("this.print(true);\r");
document.Internals.AddObject(dict);
document.Internals.Catalog.Elements["/OpenAction"] =
PdfInternals.GetReference(dict);
document.Save(Server.MapPath("2.pdf"));
frame1.Attributes["src"] = "2.pdf";
ALso, try this gem:
<link ref="mypdf" media="print" href="mypdf.pdf">
I havent tested it, but what I have read about it, it can be used in this way to let the mypdf.pdf be printed instead of page content whatever method you are using to print the page.
Search for media="print" to check out more.
You can embed javascript in the pdf, so that the user gets a print dialog as soon as their browser loads the pdf.
I'm not sure about iTextSharp, but the javascript that I use is
var pp = this.getPrintParams();
pp.interactive = pp.constants.interactionLevel.automatic;
this.print(pp);
For iTextSharp, check out http://itextsharp.sourceforge.net/examples/Chap1106.cs
Related
I've been attempting to find an easy solution to exporting a Canvas in my WPF Application to a PDF Document.
So far, the best solution has been to use the PrintDialog and set it up to automatically use the Microsoft Print the PDF 'printer'. The only problem I have had with this is that although the PrintDialog is skipped, there is a FileDialog to choose where the file should be saved.
Sadly, this is a deal-breaker because I would like to run this over a large number of canvases with automatically generated PDF names (well, programitically provided anyway).
Other solutions I have looked at include:
Using PrintDocument, but from my experimentation I would have to manually iterate through all my Canveses children and manually invoke the correct Draw method (of which a lot of my custom elements with transformation would be rather time consuming to do)
Exporting as a PNG image and then embedding that in a PDF. Although this works, TextBlocks within my canvas are no longer text. So this isn't an ideal situation.
Using the 3rd party library PDFSharp has the same downfall as the PrintDocument. A lot of custom logic for each element.
With PDFSharp. I did find a method fir generating the XGraphics from a Canvas but no way of then consuming that object to make a PDF Page
So does anybody know how I can skip or automate the PDF PrintDialog, or consume PDFSharp XGraphics to make
A page. Or any other ideas for directions to take this besides writing a whole library to convert each of my Canvas elements to PDF elements.
If you look at the output port of a recent windows installation of Microsoft Print To PDF
You may note it is set to PORTPROMP: and that is exactly what causes the request for a filename.
You might note lower down, I have several ports set to a filename, and the fourth one down is called "My Print to PDF"
So very last century methodology; when I print with a duplicate printer but give it a different name I can use different page ratios etc., without altering the built in standard one. The output for a file will naturally be built:-
A) Exactly in one repeatable location, that I can file monitor and rename it, based on the source calling the print sequence, such that if it is my current default printer I can right click files to print to a known \folder\file.pdf
B) The same port can be used via certain /pt (printto) command combinations to output, not just to that default port location, but to a given folder\name such as
"%ProgramFiles%\Windows NT\Accessories\WORDPAD.EXE" /pt listIN.doc "My Print to PDF" "My Print to PDF" "listOUT.pdf"
Other drivers usually charge for the convenience of WPF programmable renaming, but I will leave you that PrintVisual challenge for another of your three wishes.
MS suggest XPS is best But then they would be promoting it as a PDF competitor.
It does not need to be Doc[X]2PDF it could be [O]XPS2PDF or aPNG2PDF or many pages TIFF2PDF etc. etc. Any of those are Native to Win 10 also other 3rd party apps such as [Free]Office with a PrintTo verb will do XLS[X]2PDF. Imagination becomes pagination.
I had a great success in generating PDFs using PDFSharp in combination with SkiaSharp (for more advanced graphics).
Let me begin from the very end:
you save the PdfDocument object in the following way:
PdfDocument yourDocument = ...;
string filename = #"your\file\path\document.pdf"
yourDocument.Save(filename);
creating the PdfDocument with a page can be achieved the following way (adjust the parameters to fit your needs):
PdfDocument yourDocument = new PdfDocument();
yourDocument.PageLayout = PdfPageLayout.SinglePage;
yourDocument.Info.Title = "Your document title";
PdfPage yourPage = yourDocument.AddPage();
yourDocument.Orientation = PageOrientation.Landscape;
yourDocument.Size = PageSize.A4;
the PdfPage object's content (as an example I'm putting a string and an image) is filled in the following way:
using (XGraphics gfx = XGraphics.FromPdfPage(yourPage))
{
XFont yourFont = new XFont("Helvetica", 20, XFontStyle.Bold);
gfx.DrawString(
"Your string in the page",
yourFont,
XBrushes.Black,
new XRect(0, XUnit.FromMillimeter(10), page.Width, yourFont.GetHeight()),
XStringFormats.Center);
using (Stream s = new FileStream(#"path\to\your\image.png", FileMode.Open))
{
XImage image = XImage.FromStream(s);
var imageRect = new XRect()
{
Location = new XPoint() { X = XUnit.FromMillimeter(42), Y = XUnit.FromMillimeter(42) },
Size = new XSize() { Width = XUnit.FromMillimeter(42), Height = XUnit.FromMillimeter(42.0 * image.PixelHeight / image.PixelWidth) }
};
gfx.DrawImage(image, imageRect);
}
}
Of course, the font objects can be created as static members of your class.
And this is, in short to answer your question, how you consume the XGraphics object to create a PDF page.
Let me know if you need more assistance.
When using TheArtOfDev.HtmlRenderer.PdfSharp.PdfGenerator.GeneratePdf(); my PDF comes up blank. Edit: I believe it is not rendering the styling, but I'm unsure how to solve it. We are using .xsl classes to style the HTML, whereas the GeneratePDF(); function expects to be passed a CSS class, OR it uses the default W3 styling. In theory, it should just work because out styling is all inline anyway (See the HTML sample I've attached below).
Source: PDFGenerator
I have tried rendering the HTML straight to PDF, and also HTML to a bitmap image, then to a PDF.
PdfDocument pdf = PdfGenerator.GeneratePdf(faxBody, PageSize.Letter,20,null,null,null);
string path = HostingEnvironment.MapPath("~/App_Data/mytestpdf.pdf");
pdf.Save(path);
And/Or
PdfDocument pdf = PdfGenerator.GeneratePdf(faxBody, PageSize.Letter,20,null,null,null);
Bitmap bitmap = new Bitmap(1200, 1800);
PdfPage page = new PdfPage();
XImage img = XImage.FromGdiPlusImage(bitmap);
pdf.Pages.Add(page);
XGraphics xgr = XGraphics.FromPdfPage(pdf.Pages[0]);
xgr.DrawImage(img, 0, 0);
string path = HostingEnvironment.MapPath("~/App_Data/mytestpdf.pdf");
pdf.Save(path);
I took the second snippet from another Stackoverflow thread to try. I get the same result either way: A blank PDF. The string "faxBody" definitely contains HTML here.
If I run this in the Immediate Window:
pdf.Save(HostingEnvironment.MapPath("~/App_Data/mytestpdf.pdf"));
I get this:
"Expression has been evaluated and has no value."
PDF: mytestpdf.pdf
HTML string: HTMLsample
I have an app in C# with itextsharp that gets some PDF templates, fill some fields and export a flattened version.
Those PDF templates have some custom fonts, one font that I'm using it's DINPro-Regular.otf but after I replace the text and save it my font is being replaced to an Arial font.
I've read other threads but I couldn't find something that solve my case..
My code is:
// Open existing PDF
var pdfReader = new PdfReader(existingFileStream);
// PdfStamper, which will create
var stamper = new PdfStamper(pdfReader, newFileStream);
var form = stamper.AcroFields;
// Set some info
form.SetField("part_number", part.PartNumber.ToUpper());
...
// "Flatten" the form so it wont be editable/usable anymore
stamper.FormFlattening = true;
stamper.Close();
pdfReader.Close();
I've tried to add those lines as well but didn't make any difference:
form.GenerateAppearances = false;
stamper.FreeTextFlattening = true;
Original PDF
Generated PDF
So if anyone had a similar problem or have a clue how to solve it will be very appreciated.
I am using XMLWorker to parse an HTML string into a PDF Document, and cannot find a way to control the line spacing of the PDF being generated.
Document document = new Document(PageSize.LETTER, 72f, 72f, 108f, 90f);
MemoryStream stream1 = new MemoryStream();
PdfWriter pdfWriter = PdfWriter.GetInstance(document, stream1);
document.Open();
//parse HTML into document
XMLWorkerHelper.GetInstance().ParseXHtml(pdfWriter, document, new StringReader(summary.Content));
The "summary.Content" is an HTML string that comes from a database field.
Now, I recently upgraded our ITextSharp library to 5.5.5.0, and upgraded to the new XMLWorker library. Using the code above, the line spacing ("leading" in PDF-speak) is much smaller than the PDF's being generated previously. I am required to make sure the line spacing looks the same as it used to.
I read that I can set the leading on the Paragraphs I build, but that doesn't help me when simply calling ParseXHtml(). I read that ITextSharp defaults to a leading size of 1.5 times the font size.
I read here itextsupport documentation that I can use this line to use the default.css that ships with XML Worker.
CSSResolver cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
I thought the default CSS might generate the PDF with the same leading as my old PDF's, but the following code resulted in the same output PDF's as when I just use ParseXHtml().
var sr = new StringReader(summary.Content);
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, pdfWriter)));
XMLWorker worker = new XMLWorker(pipeline, true);
XMLParser xmlParse = new XMLParser(true, worker);
document.Open();
xmlParse.Parse(sr);
I need to control the line height (line-spacing, leading) in the PDF document I generate. Can anyone help point me in the right direction? I am trying to work through some options. Do either of these make sense?
Create a CSS file in a directory that defines line-height for different HTML tags, read that in with a stream, and pass that to parseXHtml(PdfWriter writer, Document doc, InputStream in, InputStream inCssFile).
Define a font for my document that specifies a line-height? I looked but didn't find a way to do this.
If you want to have a different line-height for different paragraphs, you have to define a different value for the line-height attribute in your CSS. I have made a very simple example with some very simple inline CSS:
As you can see, the line-height of the paragraph starting with Non eram nescius is 16pt. As I use the default font which is 12 pt Helvetica. The paragraph looks fine.
For the paragraph that starts with Contra quos omnis, I use a line-height of 25pt and you see that there are big gaps between the lines.
For the paragraph that starts with Sive enim ad, I use a line-height of 13pt which is only 1 pt more than the font height. The lines are very close together for this paragraph.
It doesn't matter where you define the line-height. Your options are to define it inline in the tag, in the <head> section of your HTML or in an external CSS file that is either referenced from the header of your HTML or loaded into XML Worker separately. Whatever you like most is OK.
I am generating a pdf using iTextSharp. If certain properties are true then I also want to insert an existing pdf with static content.
private byte[] GeneratePdf(DraftOrder draftOrder)
// create a pdf document
var document = new Document();
// set the page size, set the orientation
document.SetPageSize(PageSize.A4);
// create a writer instance
var pdfWriter = PdfWriter.GetInstance(document, new FileStream(file, FileMode.Create));
document.Open();
if(draftOrder.hasProperty){
//add these things to the pdf
var textToBeAdded = "<table><tr>....</table>";
}
FormatHtml(document, textToBeAdded , css);
if(someOtherProperty){
//add static pdf from file
document.NewPage();
var reader = new PdfReader("myPath/existing.pdf");
PdfImportedPage page;
for(var i = 0; i < reader.NumberOfPages; i++){
//It's this bit I don't really understand
//**how can I add the page read to the document being created?**
}
I can load the pdf from the source but when I iterate over the pages I can't seem to be able to add them to the document I am creating.
Cheers
Please read http://manning.com/lowagie2/samplechapter6.pdf
If you don't mind losing all interactivity, you can get the template from the writer object with the GetImportedPage() method and add it to the document with AddTemplate ().
This question has been answered many times on StackOverflow and you'll notice that I always warn about some dangers: you need to realize that the dimensions of the imported page can be different from the page size you initially defined. Because of this invisible parts of the imported page can become visible; visible parts can become invisible.
I'd prefer adding the extra page in a second ho using PdfCopy, but maybe that's just me.