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.
Related
I have a SQL Server table as my data source and I want to export the rows into a PDF document. I have defined a template in Word or Excel:
Each row of the SQL Server table should be a PDF Page. Do you know a good approach to get it? I thought, I can use the OpenOffice libraries and for each row, I can duplicate the template page, fill the data of the row and at the end I can convert the final document in PDF.
Another approach could be having a pdf template and fill the data directly into the pdf.
Do you know an easier approach to get it? Using ITextSharp could be quite difficult and in this context is unnecessary.
You can use PDFStamper to write your data into a PDF template.
Just place some placeholder fields to a PDF Template.
string pdfTemplate = "C:\\Temp\\Template.pdf";
string newFile = "C:\\Temp\\TemplateFilled.pdf";
//create a new PDF reader based on the PDF template document
PdfReader reader = new PdfReader(pdfTemplate);
// add content to existing PDF document with PdfStamper
PdfStamper formFiller = new PdfStamper(reader, new FileStream(newFile, FileMode.Create));
if (formFiller == null)
{
return false;
}
AcroFields formFields = formFiller.AcroFields;
formFields.SetField("Field1", sqlfield1);
formFields.SetField("Field2", sqlfield2);
formFiller.Close();
return true;
Bye Nu
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 trying to fill up a form with ITextsharp, and trying out the following code to get all the fields in the pdf:
string pdfTemplate = #"c:\Temp\questionnaire.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
StringBuilder sb = new StringBuilder();
foreach (var de in pdfReader.AcroFields.Fields)
{
sb.Append(de.Key.ToString() + Environment.NewLine);
}
But the foreach loop is always null count. Do I need to do something to file itself as I have tried the example from here and it works fine... this is an example of pdf I am trying to fill
any ideas?
Edit ::
As it turned out, the PDF "form" to fill in actually wasn't a form (in PDF terms) at all. Thus, your have two choices:
You add the text to the page contents directly using hardcoded or configured "field" positions and dimensions as described by #tschmit007 in comments to his answer.
You add actual PDF form fields to your PDF to generate a true PDF form which you take as template to fill in later.
You can add actual form fields either using some graphical tool allowing that, e.g. Adobe Acrobat, or you can use iText(Sharp). Have a look at chapter 8 of iText in Action ā 2nd Edition and the samples available here for Java and here for .Net.
Those samples mostly add form fields to newly generated PDF documents. You can virtually use the same code, though, for adding form fields to a PdfStamper which exposes its inner PdfWriter using stamper.getWriter() in Java and the stamper.Writer in C#. Instead of writer.addAnnotation(field) you have to use stamper.addAnnotation(field, page), though.
try:
using (FileStream outFile = new FileStream("result.pdf", FileMode.Create)) {
PdfReader pdfReader = new PdfReader("file.pdf");
PdfStamper pdfStamper = new PdfStamper(pdfReader, outFile);
AcroFields fields = pdfStamper.AcroFields;
//rest of the code here
//fields.SetField("nĀ°1", "value");
//...
pdfStamper.Close();
pdfReader.Close();
}
I'm not sure that this is possible but I figured it would be worth asking. I have figured out how to set the font of a formfield using the pdfstamper and acrofields methods but I would really like to be able to set the font of different parts of the text in the same field. Here's how I'm setting the font of the form fields currently:
// Use iTextSharp PDF Reader, to get the fields and send to the
//Stamper to set the fields in the document
PdfReader pdfReader = new PdfReader(fileName);
// Initialize Stamper (ms is a MemoryStream object)
PdfStamper pdfStamper = new PdfStamper(pdfReader, ms);
// Get Reference to PDF Document Fields
AcroFields pdfFormFields = pdfStamper.AcroFields;
//create a bold font
iTextSharp.text.Font bold = FontFactory.GetFont(FontFactory.COURIER, 8f, iTextSharp.text.Font.BOLD);
//set the field to bold
pdfFormFields.SetFieldProperty(nameOfField, "textfont", bold.BaseFont, null);
//set the text of the form field
pdfFormFields.SetField(nameOfField, "This: Will Be Displayed In The Field");
// Set the flattening flag to false, so the document can continue to be edited
pdfStamper.FormFlattening = true;
// close the pdf stamper
pdfStamper.Close();
What I'd like to be able to do where I set the text above is set the "This: " to bold and leave the "Will Be Displayed In The Field" non-bolded. I'm not sure this is actually possible but I figured it was worth asking because it would really be helpful in what I'm currently working on.
Thanks in advance!
Yes, kinda. PDF fields can have a rich text value (since acrobat 6/pdf1.5) along with a regular value.
The regular value uses the font defined in the default appearances... a single font.
The rich value format (which iText doesn't support directly, at least not yet), is described in chapter 12.7.3.4 of the PDF Reference. <b>, <i>, <p>, and quite a few css2 text attributes. It requires a with various attributes.
To enable rich values, you have to set bit 26 of the field flags (PdfName.FF) for a text field. PdfFormField doesn't have a "setRichValue", but they're dictionaries, so you can just:
myPdfFormField.put(PdfName.RV, new PdfString( richTextValue ) );
If you're trying to add rich text to an existing field that doesn't already support it:
AcroFields fields = stamper.getAcroFields();
AcroFields.Item fldItem = fields.getFieldItem(fldName);
PdfDictionary mergedDict = item.getMerged(0);
int flagVal = mergedDict.getAsNumber(PdfName.FF).intValue();
flagVal |= (1 << 26);
int writeFlags = AcroFields.Item.WRITE_MERGED | AcroFields.Item.WRITE_VALUE;
fldItem.writeToAll(PdfName.FF, new PdfNumber(flagVal), writeFlags);
fldItem.writeToAll(PdfName.RV, new PdfString(richTextValue), writeFlags);
I'm actually adding rich text support to iText (not sharp) as I type this message. Hurray for contributors on SO. Paulo's been good about keeping iTextSharp in synch lately, so that shouldn't be an issue. The next trunk release should have this feature... so you'd be able to write:
myPdfFormField.setFieldFlags( PdfFormField.FF_RICHTEXT );
myPdfFormField.setRichValue( richTextValue );
or
// note that this will fail unless the rich flag is set
acroFields.setFieldRichValue( richTextValue );
NOTE: iText's appearance generation hasn't been updated, just the value side of things. That would take considerably more work. So you'll want to acroFields.setGenerateAppearances(false) or have JS that resets the field value when the form its opened to force Acrobat/Reader to build the appearance[s] for you.
It took me some time to figure out after richtextfield did not work the way it was suppose too with
acrofields and most of the cases were the pdf was not editable with different fonts at runtime.
I worked out way of setting different fonts in acrofields and passing values and editing at runtime with itextsharp and I thought it will be useful for others.
Create pdf with a text field in PDF1.pdf (I hope you know how to create field in pdf)
e.g., txtComments
Go to the property section and Set the property to richtext,Mulitiline
Format the text content in word or pdf by adding the fonts and colors.
If done in word, copy and paste the content in pdf - txtcomments field.
Note:
If you want to add dynamic content. Set the parameter ā{0}ā to the txtComment field in the pdf.
using string format method you can set values to it.This is shown in the code below.
e.g., "Set different parts of a form field to have different fonts using {0}"
Add the following code in a button (this is not specific) event by reference in the itextsharp.dll 5.4.2
Response.ContentType = "application/pdf";
Response.AddHeader("Content-disposition","attachment; filename=your.pdf");
PdfReader reader = new PdfReader(#"C:\test\pdf1.pdf");
PdfStamper stamp = new PdfStamper(reader, Response.OutputStream);
AcroFields field = pdfStamp.AcroFields;
string comments = field .GetFieldRichValue("txtcomments");
string Name = "Test1";
string value = string.Format(comments,Name);
field.SetField("txtComment", value );
field.GenerateAppearances = false;//Pdf knows what to do;
stamp.FormFlattening = false;//available for edit at run time
stamp.FreeTextFlattening = true;
stamp.Close();
reader.Close()
Hope this helps.
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