I'm working with pdfs, I'm merging them first and then creating a heading and a footer for every page of the merged pdf. I'm using one method to merge and a different one to set the header and footer.
For certain documents the header and footer overlaps with the content. I've tried to set margin for the document but it doesn't change anything.
public byte[] HeaderAndFooter(byte[] inputPdf)
{
var dest = new MemoryStream();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(inputPdf.ToMemoryStream()),
new PdfWriter(dest));
Document doc = new Document(pdfDoc);
doc.SetMargins(200,200, 200, 200); /* It doesn't matter the
numbers I set in here the document remains the same...*/
numberOfPages = pdfDoc.GetNumberOfPages();
Paragraph header = new Paragraph("This is a header for every page...")
.SetFont(PdfFontFactory.CreateFont(FontConstants.HELVETICA))
.SetFontSize(10)
.SetFontColor(Color.BLACK);
for (int i = 1; i <= numberOfPages; i++)
{
var pageSize = pdfDoc.GetPage(i).GetPageSize();
float LeftMargin = 36;
float BottomMargin = 24;
float y = pageSize.GetTop() - 72;
float center = pageSize.GetWidth() / 2;
doc.ShowTextAligned(header, LeftMargin, y, i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);
doc.ShowTextAligned(footerL, LeftMargin, BottomMargin, i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);
doc.ShowTextAligned(footerC, center, BottomMargin, i, TextAlignment.CENTER, VerticalAlignment.BOTTOM, 0);
}
doc.Close();
return dest.ToArray();
}
How could I avoid the header and footer from overlapping with the content?
Related
I have an existing PDF file, I want to insert a text at the bottom of PDF file in Red color, but the existing pdf file color must remain the same.
Thank You #mkl below code, I used which is specific for Stamp.
public static void ManipulatePdf(string src, string dest)
{
src = #"C:\CCPR Temp\TempFiles\PayStub_000106488_12282019_20200117112403.pdf";
dest = #"C:\CCPR Temp\TempFiles\PayStub_WithStamper.pdf";
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create)); // create?
int numberOfPages = reader.NumberOfPages;
Rectangle pagesize;
for (int i = 1; i <= numberOfPages; i++)
{
PdfContentByte under = stamper.GetUnderContent(i);
pagesize = reader.GetPageSize(i);
float x =40;// (pagesize.Left + pagesize.Right) / 2;
float y = pagesize.Top/4;// (pagesize.Bottom + pagesize.Top) / 2;
PdfGState gs = new PdfGState();
gs.FillOpacity = 1.0f;
under.SaveState();
under.SetGState(gs);
under.SetRGBColorFill(255,0,0);
ColumnText.ShowTextAligned(under, Element.ALIGN_BOTTOM,
new Phrase("Watermark", new Font(Font.FontFamily.HELVETICA, 20)),
x, y, 1);
under.RestoreState();
}
stamper.Close();
reader.Close();
}
Adding content to an existing PDF document without changing the existing content, is sometimes referred to as stamping. Examples are adding page numbers, adding a watermark, and adding a running head.
For your specific case:
Create a PdfDocument instance from a PdfReader (to read the input PDF) and a PdfWriter (to write the output PDF). The PdfDocument instance will be in stamping mode.
Set the red text color on a Paragraph with the footer text.
Position the text with the ShowTextAligned convenience method, based on the page size.
You may also want to take into account page rotation.
PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf"), new PdfWriter("output.pdf"));
Document doc = new Document(pdfDoc);
Paragraph footer = new Paragraph("This is a footer").SetFontColor(ColorConstants.RED);
for (int i = 1; i <= pdfDoc.GetNumberOfPages(); i++)
{
Rectangle pageSize = pdfDoc.GetPage(i).GetPageSize();
float x = pageSize.GetLeft() + pageSize.GetWidth() / 2;
float y = pageSize.GetBottom() + 20;
doc.ShowTextAligned(footer, x, y, i, TextAlignment.CENTER, VerticalAlignment.BOTTOM, 0);
}
doc.Close();
This will set the Font of your Paragraph. I am not sure about the Position.
BaseFont btnRedFooter = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
iTextSharp.text.Font fntRedFooter = FontFactory.GetFont(iTextSharp.text.Font.FontFamily.TIMES_ROMAN.ToString(), 16,
iTextSharp.text.Font.BOLD, iTextSharp.text.BaseColor.RED);
pProtocoll.Add(new Paragraph("Text in Footer", fntRedFooter));
I used the below steps and finally, got the required output. I was struggling for the font color, to apply to the newly added text.
public static void StampPdfFile(string oldFile, string newFile)
{
// open the reader
PdfReader reader = new PdfReader(oldFile);
Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
// open the writer
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
// the pdf content
PdfContentByte cb = writer.DirectContent;
// select the font properties
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetFontAndSize(bf, 8);
// write the text in the pdf content
cb.BeginText();
string text = $"Voided On - {DateTime.Now.Date.ToString("MM/dd/yyyy")}";
// put the alignment and coordinates here
cb.SetColorFill(BaseColor.RED); //Give Red color to the newly added Text only
cb.ShowTextAligned(2, text, 120, 250, 0);
cb.SetColorFill(BaseColor.BLACK); //Give Red color to the exisitng file content only
cb.EndText();
// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
document.Close();
fs.Close();
writer.Close();
reader.Close();
}
I'm trying add picture on centre(middle) of page PDF file with text, but I can't do it right. I use for image SetAbsolutePosition, but text don't stand under picture.
I need in my Pdf file next format of page:
I use next code:
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
ITextEvents ev = new ITextEvents();
writer.PageEvent = ev;
doc.Open();
var paragraph = new Paragraph();
var paragraph1 = new Paragraph();
var chunk = new Chunk("Text under picture", f14nb);
var chunk1 = new Chunk("Code of picture", f14);
img = ScaleImg(Image.GetInstance(imgNane_2));
img.SetAbsolutePosition((PageSize.A4.Width - img.ScaledWidth) / 2,
((PageSize.A4.Height - img.ScaledHeight) / 2));
paragraph.Add(img);
paragraph1.Add(chunk);
paragraph1.Add(chunk1);
doc.Add(paragraph);
doc.Add(paragraph1);
doc.Close();
private Image ScaleImg(Image img)
{
if (img.Height > img.Width)
{
//Maximum height is 800 pixels.
float percentage = 0.0f;
percentage = 640 / img.Height;
img.ScalePercent(percentage * 100);
}
else
{
//Maximum width is 600 pixels.
float percentage = 0.0f;
percentage = 500 / img.Width;
img.ScalePercent(percentage * 100);
}
return img;
}
I think, that I should use another way for solve my problem, but I don't know which.
Thank you.
I understood how do it.
This is for image with text:
public Image getWatermarkedImage(Document Doc, Image img, String watermarkText)
{
float width = img.ScaledWidth;
float height = img.ScaledHeight;
PdfTemplate template = cb.CreateTemplate(width, height);
template.AddImage(img, width, 0, 0, height, 0, 0);
ColumnText.ShowTextAligned(template, Element.ALIGN_RIGHT,
new Phrase(watermarkText, fontBold_14), width - 10, 10, 0);
return Image.GetInstance(template);
}
This is for adding text under image(main code):
var codeOfPicture = "*Code of picture* - *Код картинки*";
var chunk = new Chunk("Text under picture", font_14);
img = ScaleImg(Image.GetInstance(imgNane_1));//imgNane_2));
var tmpImg = getWatermarkedImage(doc, img, codeOfPicture);
var textY = ((PageSize.A4.Height - img.ScaledHeight) / 2) - 15;
var textX = PageSize.A4.Width / 2;
tmpImg.SetAbsolutePosition((PageSize.A4.Width - img.ScaledWidth) / 2,
((PageSize.A4.Height - img.ScaledHeight) / 2));
doc.Add(tmpImg);
ColumnText.ShowTextAligned(cb, Element.ALIGN_CENTER, new Phrase(chunk), textX, textY, 0);
I am using the following code:
PdfReader PDFReader = new PdfReader("c:\\file.pdf");
FileStream Stream = new FileStream("c:\\new.pdf", FileMode.Create, FileAccess.Write);
PdfStamper PDFStamper = new PdfStamper(PDFReader, Stream);
for (int iCount = 0; iCount < PDFStamper.Reader.NumberOfPages; iCount++)
{
iTextSharp.text.Rectangle PageSize = PDFReader.GetCropBox(iCount + 1);
PdfContentByte PDFData = PDFStamper.GetOverContent(iCount + 1);
BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
PDFData.BeginText();
PDFData.SetColorFill(CMYKColor.RED);
PDFData.SetFontAndSize(baseFont, 20);
PDFData.ShowTextAligned(PdfContentByte.ALIGN, SAMPLE DOCUMENT", (PageSize.Right + PageSize.Left) / 2, (PageSize.Top + PageSize.Bottom) / 2, 45);
PDFData.EndText();
}
PDFStamper.Close();
PDFReader.Close();
But sometimes the overlaid text exceeds the page size because I have hard coded the font as 20. So, is there any way to know if the overlaid text will exceed the page size? Because I want to use code like I will then use:
if(pagesize exceeds)
reduce font size by 1 point and check again .....
If the above doesn't work, then my next step is to use a PNG image that has the overlaid text in it and its background as transparent. then resize the image according to the pagesize and then overlay it.
however, I will prefer the first part. if not, then I will go for the second option.
After doing some minor calculations, this method should calculate the maximum font size to use for such a vertical text and apply it:
void Stamp(PdfContentByte cb, Rectangle rect, BaseFont bf, string text)
{
int altitude = Math.Max(bf.GetAscent(text), bf.GetDescent(text));
int width = bf.GetWidth(text);
double horizontalFit = Math.Sqrt(2.0) * 1000 * (rect.Left + rect.Right) / (width + 2 * altitude);
double verticalFit = Math.Sqrt(2.0) * 1000 * (rect.Bottom + rect.Top) / (width + 2 * altitude);
double fit = Math.Min(horizontalFit, verticalFit);
cb.BeginText();
cb.SetColorFill(CMYKColor.RED);
cb.SetFontAndSize(bf, (float) fit);
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, text, (rect.Right + rect.Left) / 2, (rect.Top + rect.Bottom) / 2, 45);
cb.EndText();
}
You can call it like this:
using (PdfReader reader = new PdfReader(source))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create, FileAccess.Write)))
{
for (int iCount = 0; iCount < reader.NumberOfPages; iCount++)
{
Rectangle PageSize = reader.GetCropBox(iCount + 1);
PdfContentByte PDFData = stamper.GetOverContent(iCount + 1);
BaseFont baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
Stamp(PDFData, PageSize, baseFont, "SAMPLE DOCUMENT");
}
}
(By the way, I used your BaseFont but you should be aware that iText(Sharp) will ignore BaseFont.EMBEDDED for standard 14 fonts like BaseFont.HELVETICA.)
The result looks like this:
PS: If you (as expressed in your question) really don't want to use a font size above 20, you have to Min the fit value again with 20.
I use itextsharp and i need to draw a dotted linebreak from left to right of the page(100% width) but don't know how. The doc always has a margin left right. Please help
var pageSize = PageSize.A4;
if (_pdfSettings.LetterPageSizeEnabled)
{
pageSize = PageSize.LETTER;
}
var doc = new Document(pageSize);
PdfWriter.GetInstance(doc, stream);
doc.Open();
//fonts
var titleFont = GetFont();
titleFont.SetStyle(Font.BOLD);
titleFont.Color = BaseColor.BLACK;
titleFont.Size = 16;
var largeFont = GetFont();
largeFont.SetStyle(Font.BOLD);
largeFont.Color = BaseColor.BLACK;
largeFont.Size = 18;
int ordCount = orders.Count;
int ordNum = 0;
foreach (var order in orders)
{
var addressTable = new PdfPTable(3);
addressTable.WidthPercentage = 100f;
addressTable.SetWidths(new[] { 25, 37, 37 });
// sender address
cell = new PdfPCell();
//cell.Border = Rectangle.NO_BORDER;
cell.AddElement(new Paragraph("Người Gửi", titleFont));
cell.AddElement(new Paragraph(_localizationService.GetResource("admin.orders.pdfinvoice.sender", lang.Id), smallFont));
cell.AddElement(new Paragraph(_localizationService.GetResource("admin.orders.pdfinvoice.senderaddress", lang.Id), smallFont));
cell.AddElement(new Paragraph(_localizationService.GetResource("PDFInvoice.Hotline", lang.Id), smallFont));
cell.AddElement(new Paragraph("TAKARA.VN", largeFont));
addressTable.AddCell(cell);
......
Chunk linebreak = new Chunk(new DottedLineSeparator());
doc.Add(linebreak);
doc.Add(new Paragraph(""));
....
}
Please take a look at the example FullDottedLine.
You're creating a DottedLineSeparator of which the width percentage is 100% by default. This 100% is the full available width withing the margins of the page. If you want the line to exceed the available width, you need a percentage that is higher than 100%.
In the example, the default page size (A4) and the default margins (36) are used. This means that the width of the page is 595 user units and the available width equals 595 - (2 x 36) user units. The percentage needed to span the complete width of the page equals 100 x (595 / 523).
Take a look at the resulting PDF file full_dotted_line.pdf and you'll see that the line now runs through the margins.
I am using itext sharp for creating reports in PDF format.
I want page borders. I tried some ways. I am not successful.
How can I get a page border for top, bottom, left, right using iText for .NET?
I added one image 1. I want borders like described in the image.
You can try this code for adding the image for the header manually.
//Step 1: Add the Image file
strImgPath is refer the directory Info..
Image imgLogo = Image.GetInstance(strImgPath.ToString()+"\\abcdur compe.Jpg");
imgLogo.Alignment = Image.ALIGN_CENTER;
imgLogo.ScalePercent(50f);
// Step 2:
Add this ImgLogo to the PdfPTable by use of this
PdfPCell pdfcellImage = new PdfPCell(imgLogo, true);
pdfcellImage.FixedHeight = 40f;
pdfcellImage.HorizontalAlignment = Element.ALIGN_CENTER;
pdfcellImage.VerticalAlignment = Element.ALIGN_CENTER;
pdfcellImage.Border = Rectangle.NO_BORDER;
pdfcellImage.Border = Rectangle.NO_BORDER;
pdftblImage.AddCell(pdfcellImage);
// Step 3:
Create Chunck to add Text for address or others
fntBoldComHd is a Base Font Library Object
Chunk chnCompany = new Chunk("Your CompanyName\nAddress", fntBoldComHd);
//Step 4:
Create Phrase For add the Chunks and PdfPTables
Phrase phHeader = new Phrase();
phHeader.Add(pdftblImage);
phHeader.Add(chnCompany);
// Step 5:
Assign the Phrase to PDF Header
HeaderFooter header = new HeaderFooter(phHeader, false);
header.Border = Rectangle.NO_BORDER;
header.Alignment = Element.ALIGN_CENTER;
docPDF.Header = header;
I am using one hacky way of workaround but it will create the border.Use this method.
private void CreateBorder(PdfContentByte cb, PdfWriter writer, Document doc)
{
iTextSharp.text.Rectangle r = doc.PageSize;
float left = r.Left + 30;
float right = r.Right - 30;
float top = r.Top - 30;
float bottom = r.Bottom + 30;
float width = right - left;
float height = top - bottom;
PdfPTable tab = new PdfPTable(1);
tab.TotalWidth = width;
tab.LockedWidth = true;
PdfPCell t = new PdfPCell(new Phrase(String.Empty));
t.BackgroundColor = new BaseColor(250, 235, 215);
t.FixedHeight = height;
t.BorderWidth = 3;
tab.AddCell(t);
Paragraph pa = new Paragraph();
pa.Add(tab);
float h = tab.TotalHeight;
PdfTemplate temp = cb.CreateTemplate(tab.TotalWidth, h);
tab.WriteSelectedRows(0, -1, 0.0F, h, temp);
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(temp);
img.SetAbsolutePosition(30, 30);
cb.AddImage(img);
}
If u want one more section for header create table width two rows.I hope this helps.
Are you referring to the document margins? If yes, use the Document object's ctor to specify them:
public Document(Rectangle pageSize, float marginLeft, float marginRight, float marginTop, float marginBottom);