Why is my content overlapping with my footer? - c#

I am using itextsharp to generate pdf ...i m getting problem is my content/text coming upon footer...i want to automatically break down content to new page...if it comes upon footer..
right now i m using document.newpage()
but i want to do it automatically that my page /content automatically breakdown to new page..it should not come to header/footer of page...
FOr Information i create header/footer through this class
public class ITextEvents : PdfPageEventHelper
and i used this function
public override void OnEndPage
I m attaching also the result that i m getting right now...
please help me on this...i can share more information if you ask in comments
i want this last box to come automatically to new page.....

Assuming that you are adding the flowing content using document.add(), you have to make sure that you define a bottom margin that is sufficiently large to accommodate the footer.
You don't share the code you have in your OnEndPage method, but suppose that you have something like:
canvas.MoveTo(36, 50);
canvas.LineTo(559, 50);
canvas.Strike();
This draws a line from x = 36 to x = 559 at y = 50.
Suppose you have created your Document like this:
Document document = new Document();
In this case, you are creating a document with pages in the A4 format (595 x 842 user units) and margins of 36 user units. As the bottom margin is only 36 user units, your content risks overlapping with the line drawn at 50 user units from the bottom.
You should change the line where you create the Document like this:
Document document = new Document(PageSize.A4, 36, 36, 36, 55);
Now you have a bottom margin of 55 user units and the line you draw at 50 user units no longer overlaps.
Note: I use the term user units because that's how we define measurements in PDF. By default 1 user unit equals 1 point. The default margin is 36 user units or half an inch.

Related

Crop one inch of PDF file

I need to resize a single page PDF from 8X11 inch to 8X9 inch (or any size), without resizing the content at all.
How can I do this in C# ?
Thanks
This should be possible using any decent general purpose PDF library.
For example, to crop 1 inch from the right using iText 7:
using (PdfReader reader = new PdfReader(SOURCE_PDF))
using (PdfWriter writer = new PdfWriter(TARGET_PDF))
using (PdfDocument document = new PdfDocument(reader, writer))
{
for (int i = 1; i <= document.GetNumberOfPages(); i++)
{
PdfPage page = document.GetPage(i);
Rectangle cropBox = page.GetCropBox();
cropBox.SetWidth(cropBox.GetWidth() - 72);
page.SetCropBox(cropBox);
}
}
If, as you mention in a comment, you actually want to cut the right part of the PDF to have a PDF of 88mm of width, keeping the same height, replace
cropBox.SetWidth(cropBox.GetWidth() - 72);
by
cropBox.SetWidth(88f * 72f / 25.4f);
The crop box dimensions are given in default user space units which in turn default to 1⁄72 inch. Thus, to set a dimension given in mm one has to multiply that number by (72/25.4) first.
Two remarks:
Actually the default user space unit may differ if the page UserUnit property is set which is specified as
a positive number that shall give the size of default user space units, in multiples of 1⁄72 inch. The range of supported values shall be implementation-dependent.
Default value: 1.0 (user space unit is 1⁄72 inch).
(ISO 32000-1, Table 30 – Entries in a page object)
This property is seldom used, though, in particular because of the "The range of supported values shall be implementation-dependent" bit, so I ignored it above.
If you don't want to crop but instead to enlarge the page area, you'll probably not only need to enlarge the CropBox but also the MediaBox.
The crop, bleed, trim, and art boxes shall not ordinarily extend beyond the boundaries of the media box. If they do, they are effectively reduced to their intersection with the media box.
(ISO 32000-1, section 14.11.2.1 Page Boundaries / General)
PdfPage has analogous methods GetMediaBox and SetMediaBox that can be used for enlarging the MediaBox.

How to calculate the number of characters that can be accommodated in a page of a given font and size

I was creating a C# Console Application that fills in the details in a certificate template (pdf) file using ITextSharp. The text that needs to be filled is dynamically generated.
If the dynamically generated text exceeds a certain size the field name gets truncated. I have already thought of an algorithm to solve this problem for which I require the maximum number of characters that can be accommodated in a page with the given font and font-size. The width of the page where the text has to be accommodated is given to us already.
I used the following code:
string text = "This is the test string that needs to be accommodated";
// Registering a font
FontFactory.Register("somefont.ttf", "script");
var script = FontFactory.GetFont("script", 20f); // registers the font with the given type and size.
Phrase phrase_text = new Phrase();
phrase_text.Add(new Chunk(text, script));
ColumnText.ShowTextAligned(pbover, Element.ALIGN_CENTER, new Phrase(phrase_text), PageSize.A4.Height/2, 140, 0);
This code seems to work fine, but when I am adding a bigger text in the screen, the text gets truncated with the alignment still in the center (in the horizontal sense).
I was reading something on using the Graphics library, but could not resolve the issue.
You say that you are filling out a template. That assumes that you have at least one AcroForm field in your document. Filling out fields is explained in the answer to this question: itextsharp setting the stamper FormFlatttening=true results in no output
Usually, the field has a property that defines the font size that needs to be used, but you are right: if the text doesn't fit the rectangle defined by the form field, the text gets truncated. You can change this by setting the font size to "auto". This way, the font size will decrease if the text doesn't fit. This is explained here: Set AcroField Text Size to Auto
Or you could use a multiline field. See How to get the row count of a multiline field?
If you don't have a form field (which would be strange, because that means that you have to program the coordinates, e.g. PageSize.A4.Height/2, 140), you shouldn't use the showTextAligned() method. If there is no way you can define the location using a form field (but I can't think of any argument why you couldn't), you should take a look at the MovieAds example (taken from my book iText in Action).
I have a method AddParagraph that looks like this:
public bool AddParagraph(Paragraph p, PdfContentByte canvas,
AcroFields.FieldPosition f, bool simulate)
{
ColumnText ct = new ColumnText(canvas);
ct.SetSimpleColumn(
f.position.Left, f.position.GetBottom(2),
f.position.GetRight(2), f.position.Top
);
ct.AddElement(p);
return ColumnText.HasMoreText(ct.Go(simulate));
}
In this example, I create a ColumnText object for which I define a column. I add a paragraph, and I render that paragraph. If simulate is true, I don't add it for real, I add it virtually to see if the paragraph fits. If it fits, I call the method anew for real (with simulate = false).
I repeat this as many time as needed, decreasing the font with 0.2 user units at every try. Only if the font gets smaller than 6pt, I allow iText to truncate the content.
while (AddParagraph(CreateMovieParagraph(movie, size),
canvas, f, true) && size > 6)
{
size -= 0.2f;
}

Header and Footer in ITextSharp

I know this question has been asked a thousand times, but I am yet to find a straight forward answer. I am relatively new to ITextSharp, so please explain as if you were talking to a toddler. How can I add a simple text only header and footer to the document I am creating?
I am creating a simple pdf document with the following code:
void Button1Click(object sender, EventArgs e)
{
Document doc = new Document(iTextSharp.text.PageSize.LEDGER, 10, 10, 42, 35);
PdfWriter wri = PdfWriter.GetInstance(doc, new FileStream(#"File Path", FileMode.Create));
doc.Open();
Paragraph par1 = new Paragraph("Hello World!");
doc.Add(par1);
//Code to add header/footer
doc.Close();
MessageBox.Show("Your PDF has been created!");
}
I have done a lot of research on how to add headers and footers, but they all have to do with complicated page events. Is there an easier way? If there isn't, can you walk me through the process step by step? I would really appreciate any help that you all can give. Thanks!
You are creating your Document like this:
Document doc = new Document(iTextSharp.text.PageSize.LEDGER, 10, 10, 42, 35);
This means that you have a top margin of 42 user units and a bottom margin of 35 user units. You can use this margin to add extra content in a page event.
The official web site has plenty of examples and a comprehensive Q&A section. All examples and answers are tagged. If you click on the header tag, you can find plenty of examples.
As already indicated by others in the comments, you need to create a PdfPageEvent implementation. The easiest way to do this, is by extending the PdfPageEventHelper class.
class MyHeaderFooterEvent : PdfPageEventHelper {
Font FONT = new Font(Font.FontFamily.HELVETICA, 18, Font.BOLD);
public override void OnEndPage(PdfWriter writer, Document document) {
PdfContentByte canvas = writer.DirectContent;
ColumnText.ShowTextAligned(
canvas, Element.ALIGN_LEFT,
new Phrase("Header", FONT), 10, 810, 0
);
ColumnText.ShowTextAligned(
canvas, Element.ALIGN_LEFT,
new Phrase("Footer", FONT), 10, 10, 0
);
}
}
Important to know:
It is forbidden to add content in the OnStartPage() event. Add your header and footer when all the content has been added to the page just before iTextSharp moves to a new page. More specifically: add content in the OnEndPage() event.
It is forbidden to add content to the Document object that is passed to the event. This object can be used for read-only purposes only.
If you examine the OnEndPage() method in the MyHeaderFooterEvent class, you see that we get the DirectContent from the writer and that we add content to this canvas using ShowTextAligned methods. There are many other ways to add content, but you explicitly asked for the easiest way. This way has its limitations, but it's easy.
I used a couple of hard-coded values: I used 10 as the x value for the header and the footer. That's because you defined a left margin of 10 user units. The header and footer are left aligned with the actual content you're adding to the page. I used 810 for the y value of the header because you're creating an A4 page with a top margin of 42. The top y coordinate of your page is 842. The top y coordinate of the top margin is 842 - 42 = 800. I added 10 user units so that your header isn't glued to the actual content. The bottom y coordinate of the page is 0 in your case and the bottom y coordinate of the margin in 35. I used 10 for the base line of the footer.
You created wri and right after creating this PdfWriter instance, you open the Document instance. For the page event to take effect, you should add the following link, right before opening the Document:
wri.PageEvent = new MyHeaderFooterEvent();
Now the OnEndPage() method will be invoked every time your main process finalizes a page.
Important: you added //Code to add header/footer at the wrong place. iTextSharp will try to flush the content of a page as soon as possible. If you add code to add a header/footer after you've added content, you can not go back to add a header and footer to pages that were already flushed to the output stream.

How to add a logo in header in existing Pdf in C#

I have an existing PDF in which i am trying to add a logo in Header, I have found a good example from
How can I insert an image with iTextSharp in an existing PDF?
It is adding logo in Footer passing 0,0 in image.SetAbsolutePosition(100, 100);
but i want to add logo in Header. If anyone know about it, please suggest.
Are you creating the document from scratch?
If so,
you know the dimensions of the page. It's PageSize.A4 by default, or whatever Rectangle you passed to the Document constructor. You need to adjust the X and Y values depending on the value of that Rectangle. For instance:
image.setAbsolutePosition(rect.Left, rect.Top - image.ScaledHeight);
Where rect is the page size.
As you're adding a header, you want this header to appear on each page, hence you'll use a page event. Take a look at the OnEndPage() method in this example. Make sure you don't add the image bytes as many times as there are pages! Create the image instance outside the onEndPage method, for instance in the constructor of your page event implementation.
If not, you need to get the CropBox of every page:
rect = reader.GetCropBox(page);
If no CropBox was defined, you need to get the MediaBox:
rect = reader.GetPageSize(page);
Where page is a page number (e.g. 1). Based on the value of rect, you can define the position of the image, as shown above.
I hope you understand that your code where you've used x = 0 and y = 0 won't always show the image in the footer. You're making the assumption that the lower-left corner of each page in each PDF has the coordinate (0, 0). That assumption is wrong!

iTextSharp self-expanding page width

I'm writing a web application to generate labels. The label printer that I'm targeting utilizes 12mm tape and the customer specified that they want to limit the labels to 3.25". I know that with iTextSharp I can specify the size of the document I want to create, however it appears that I have to specify both a width and height.
Document document = new Document(new iTextSharp.text.Rectangle(234f, 33.84f));
234 is 3.25" converted to points, and 33.84 is 12mm converted to points, so this sets the document to the maximum size allowed. Is there any way to set just the height and let the document auto-expand to the amount of content? With that, is there a way to determine if the expanded width of the document exceeds to maximum allowed by the customer? Thanks in advance for any help you can offer.
No, that is not possible in iText. It's not a particularly good idea anywhere else either. As Redman said, PDF is a print-based format. It's not HTML.
There are some tricks you can do to get around this to some extent:
Create your page with the maximum legal height. 200" * 72dpi = 14400 points.
Add a "generic tag" to your paragraphs.
create a tag event handler that tracks where the bottom of your last paragraph was drawn.
Save the PDF.
Open it again with a PDFStamper
Set the bottom of the page to match the location of that last paragraph. Remember that the bottom left starts off at 0,0, and the top right will be
Save the final PDF
This trick will only work if your total output is less that 200" high. If you go over that, you'll still get a second page, and your "where the bottom is" code had better be prepared for it.
PS: I don't see what's wrong with having a number of 12mm x 3.25" pages... won't that perfectly fit the labels they want printed?
As far as I know, because PDF is a print format, the document width and height must be set.
This is why reporting tools generally default page sizes to the default printer page size.
You best bet to try and calculate the size of the content and create the PDF accordingly.
Depending on the volume and nature of the workflow, you could provide a preview for the customer to check before printing.

Categories

Resources