iTextSharp Resize each page to fit the pagesize - c#

I have a .pdf document which has for example 7 pages. I split this document into 7 .pdf document, so it means that each document has only one page. But mainly I need to make fit the content of pages. So delete whitespaces, margins, resize. Have you got some simple advice? I add links for images and also code for split pdf document. Thank you for your response.
INPUT:
DESIRED OUTPUT:
CODE:
public void PdfSplitDocument(string filename)
{
String path = "C:/Doc/" + filename;
String result = "d:/output/result";
PdfCopy copy;
PdfReader reader = new PdfReader(path);
for (int i = 1; i <= reader.NumberOfPages; i++)
{
Document document = new Document(PageSize.A4, 0, 0, 0, 0);
copy = new PdfCopy(document, new FileStream(result + i + ".pdf", FileMode.Create));
document.Open();
copy.AddPage(copy.GetImportedPage(reader, i));
document.Close();
}
}

Take a look at the ShowTextMargins example. It uses the TextMarginFinder class to find the margins within which text is found. In this example, taken from my book "iText in Action - Second Edition", I use this class to draw a rectangle:
public void addMarginRectangle(String src, String dest)
throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT));
TextMarginFinder finder;
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
finder = parser.processContent(i, new TextMarginFinder());
PdfContentByte cb = stamper.getOverContent(i);
cb.rectangle(finder.getLlx(), finder.getLly(),
finder.getWidth(), finder.getHeight());
cb.stroke();
}
stamper.close();
reader.close();
}
In your case, you want to crop the pages based on the rectangle. You have a finder object that allows you to get the coordinate of the lower-left corner (llx and lly) and the coordinate of the upper-right corner (urx and ury). You can use these coordinates to crop pages as is done in the CropPages example:
public void manipulatePdf(String src, String dest)
throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
int n = reader.getNumberOfPages();
PdfDictionary pageDict;
PdfRectangle rect = new PdfRectangle(llx, lly, urx, ury);
for (int i = 1; i <= n; i++) {
pageDict = reader.getPageN(i);
pageDict.put(PdfName.CROPBOX, rect);
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();
}
Another option is to change the media box instead of the crop box:
pageDict.put(PdfName.MEDIABOX, rect);
The C# version of these examples can be found here:
ShowTextMargins
CropPages

Related

Draw Horizontal/Vertical line in pdf on a specific page using iTextSharp in .NET

I'm trying to draw a horizontal/Vertical line in pdf on a specific page number(let say on page number 3 out of 8 pages). But, I'm only able to draw a line on the first and last page.
Here's my code:
Step 1:
public ActionResult CreatePDF(string id)
{
// Create the iTextSharp document.
Document doc = new Document();
// Set the document to write to memory.
MemoryStream memStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc, memStream);
writer.CloseStream = false;
doc.Open();
DrawThickLine(writer, 36f, 519f, 806f, 519f);//Horizontal Line
DrawThickLine(writer, 36f, 280f, 36f, 521f);//Vertical Line
// Close and get the resulted binary data.
doc.Close();
// Send the binary data to the browser.
return BinaryContentData(memStream, "", "", d1.formnumber.Value);//External Binary Content method
}
Step 2:
private static void DrawThickLine(PdfWriter writer, float x1, float y1, float x2, float y2)
{
PdfContentByte contentByte = writer.DirectContent;
contentByte.SetLineWidth(4.0f); // Make a bit thicker than 1.0 default
contentByte.SetColorStroke(Color.BLACK);
contentByte.MoveTo(x1, y1);
contentByte.LineTo(x2, y2);
contentByte.Stroke();
}
Any help would be appreciated!!
After working an hour, here's my solution.
Step 1:
public ActionResult CreatePDF(string id)
{
// Create the iTextSharp document.
Document doc = new Document();
// Set the document to write to memory.
MemoryStream memStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc, memStream);
writer.CloseStream = false;
doc.Open();
// DrawThickLine(writer, 36f, 519f, 806f, 519f);//Horizontal Line
// DrawThickLine(writer, 36f, 280f, 36f, 521f);//Vertical Line
// Close and get the resulted binary data.
doc.Close();
// Send the binary data to the browser.
return BinaryContentData(memStream, "", "", id);//External Binary Content method
}
Step 2:
protected ActionResult BinaryContentData(MemoryStream pdf, string UserPwd, string OwnerPwd, string uid)
{
PdfReader reader = new PdfReader(pdf);
MemoryStream output = new MemoryStream();
PdfStamper pdfStamper = new PdfStamper(reader, output);
pdfStamper.Writer.CloseStream = false;
for (int pageIndex = 1; pageIndex <= reader.NumberOfPages; pageIndex++)
{
if (pageIndex == 3)//Page 3
{
DrawThickLine(pdfStamper, pageIndex, 36f, 519f, 806f, 519f);//Horizontal Line
DrawThickLine(pdfStamper, pageIndex, 36f, 280f, 36f, 521f);//Vertical Line
}
}
............//some code goes here
return new BinaryContentResult(buffer, "application/pdf", uid);
}
Step 3:
private static void DrawThickLine(PdfStamper pdfStamper, int pageIndex, float x1, float y1, float x2, float y2)
{
PdfContentByte cb = pdfStamper.GetOverContent(pageIndex);
cb.SetLineWidth(4.0f); // Make a bit thicker than 1.0 default
cb.SetColorStroke(Color.BLACK);
cb.MoveTo(x1, y1);
cb.LineTo(x2, y2);
cb.Stroke();
}

Insert text in Red Color at the bottom of existing pdf file with itextsharp

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();
}

How to maintain cropped information in pdf page after page extraction with itextsharp?

I am using acrobat 8.0 professional for cropping text from a PDF.
One page of Original pdf is
After cropping pdf above page is
In mine project i am using cropped pdf and extract individual pages from it by following code
private void ExtractPages(string inputFile, string outputFile, int start, int end)
{
// get input document
PdfReader inputPdf = new PdfReader(inputFile);
// retrieve the total number of pages
int pageCount = inputPdf.NumberOfPages;
if (end < start || end > pageCount)
{
end = pageCount;
}
//var pgSize = new iTextSharp.text.Rectangle(myWidth, myHeight);
//var doc = new iTextSharp.text.Document(pgSize, leftMargin, rightMargin, topMargin, bottomMargin);
// load the input document
Document inputDoc = new Document(inputPdf.GetPageSizeWithRotation(1));
// create the filestream
using (FileStream fs = new FileStream(outputFile, FileMode.Create))
{
// create the output writer
PdfWriter outputWriter = PdfWriter.GetInstance(inputDoc, fs);
inputDoc.Open();
PdfContentByte cb1 = outputWriter.DirectContent;
// copy pages from input to output document
for (int i = start; i <= end; i++)
{
inputDoc.SetPageSize(inputPdf.GetPageSizeWithRotation(i));
inputDoc.NewPage();
PdfImportedPage page = outputWriter.GetImportedPage(inputPdf, i);
int rotation = inputPdf.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb1.AddTemplate(page, 0, -1f, 1f, 0, 0, inputPdf.GetPageSizeWithRotation(i).Height);
}
else
{
cb1.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
}
inputDoc.Close();
}
}
Problem is that after page extraction cropping information is not retained in extracted pdf. Extracted pdf is same as original pdf with extra text in it.
How to retained cropped information in extracted pdf ?

How to bottom align text in a textbox control in pdf file using itextsharp

I need to bottom align text which I'm getting from TextBox in PDF file.
I'm using below code to get text from TextBox in pdf.
for (int i = 1; i <= reader.NumberOfPages; i++)
{
iTextSharp.text.pdf.PdfArray array = reader.GetPageN(i).GetAsArray(iTextSharp.text.pdf.PdfName.ANNOTS);
if (array == null) continue;
for (int j = 0; j < array.Size; j++)
{
iTextSharp.text.pdf.PdfDictionary annot = array.GetAsDict(j);
iTextSharp.text.pdf.PdfString text = annot.GetAsString(iTextSharp.text.pdf.PdfName.CONTENTS);
}
}
I'm using ItextSharp Library. Error screenshot
PdfReader reader = new PdfReader(SOURCE);
PdfStamper stamper = new PdfStamper(reader, TARGET);
TextField tf = new TextField(stamper.getWriter(), new Rectangle(300, 400,
500, 420), text);
stamper.addAnnotation(tf.getTextField(), 1);
PdfContentByte overContent = stamper.getOverContent(1);
BaseFont baseFont = BaseFont.createFont();
overContent.setFontAndSize(baseFont, 12);
overContent.beginText();
overContent.showTextAligned(PdfContentByte.ALIGN_BOTTOM, text, 300,
405, 0);
overContent.endText();
stamper.close ();
or try this also
using (PdfStamper stamper = new PdfStamper(new PdfReader(inputFile), File.Create(outputFile)))
{
TextField tf = new TextField(stamper.Writer, new iTextSharp.text.Rectangle(0, 0, 100, 300), "Vertical");
stamper.AddAnnotation(tf.GetTextField(), 1);
}

add page number to pdf document (itextsharp)

I want to add page numbers to the footer of the itextsharp pdf file.Im generating pdf from html (asp.net repeater).And Im using XMLWorkerHelper to parse the html content.I searched a lot but cant find anything useful to achive this.
You'll have to open the PDF with iTextSharp and add the page numbers yourself. I did something like this a while back, here's my function that might give you a start.
The function adds the current page to the lower left, so you might have to place it somewhere else that fits your needs.
public static byte[] AddPageNumbers(byte[] pdf)
{
MemoryStream ms = new MemoryStream();
// we create a reader for a certain document
PdfReader reader = new PdfReader(pdf);
// we retrieve the total number of pages
int n = reader.NumberOfPages;
// we retrieve the size of the first page
Rectangle psize = reader.GetPageSize(1);
// step 1: creation of a document-object
Document document = new Document(psize, 50, 50, 50, 50);
// step 2: we create a writer that listens to the document
PdfWriter writer = PdfWriter.GetInstance(document, ms);
// step 3: we open the document
document.Open();
// step 4: we add content
PdfContentByte cb = writer.DirectContent;
int p = 0;
Console.WriteLine("There are " + n + " pages in the document.");
for (int page = 1; page <= reader.NumberOfPages; page++)
{
document.NewPage();
p++;
PdfImportedPage importedPage = writer.GetImportedPage(reader, page);
cb.AddTemplate(importedPage, 0, 0);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.BeginText();
cb.SetFontAndSize(bf, 10);
cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, +p + "/" + n, 7, 44, 0);
cb.EndText();
}
// step 5: we close the document
document.Close();
return ms.ToArray();
}
Something like this should work:
var sourceFileList = new List<string>();
//add files to merge
int sourceIndex = 0;
PdfReader reader = new PdfReader(sourceFileList[sourceIndex]);
int sourceFilePageCount = reader.NumberOfPages;
Document doc = new Document(reader.GetPageSizeWithRotation(1));
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(destinationFileName, FileMode.Create));
doc.Open();
PdfImportedPage page;
PdfContentByte contentByte = writer.DirectContent;
int rotation;
while (sourceIndex < sourceFileList.Count)
{
int pageIndex = 0;
while (pageIndex < sourceFilePageCount)
{
pageIndex++;
doc.SetPageSize(reader.GetPageSizeWithRotation(pageIndex));
doc.NewPage();
page = writer.GetImportedPage(reader, pageIndex);
rotation = reader.GetPageRotation(pageIndex);
if (rotation.Equals(90 | 270))
contentByte.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(pageIndex).Height);
else
contentByte.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
sourceIndex++;
if (sourceIndex < sourceFileList.Count)
{
reader = new PdfReader(sourceFileList[sourceIndex]);
sourceFilePageCount = reader.NumberOfPages;
}
}
doc.Close();

Categories