The title sums it all.
I want to add a text to an existing PDF file using iTextSharp, however i can't find how to do it anywhere in the web...
PS: I cannot use PDF forms.
I found a way to do it (dont know if it is the best but it works)
string oldFile = "oldFile.pdf";
string newFile = "newFile.pdf";
// 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.SetColorFill(BaseColor.DARK_GRAY);
cb.SetFontAndSize(bf, 8);
// write the text in the pdf content
cb.BeginText();
string text = "Some random blablablabla...";
// put the alignment and coordinates here
cb.ShowTextAligned(1, text, 520, 640, 0);
cb.EndText();
cb.BeginText();
text = "Other random blabla...";
// put the alignment and coordinates here
cb.ShowTextAligned(2, text, 100, 200, 0);
cb.EndText();
// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
// close the streams and voilá the file should be changed :)
document.Close();
fs.Close();
writer.Close();
reader.Close();
I hope this can be usefull for someone =) (and post here any errors)
In addition to the excellent answers above, the following shows how to add text to each page of a multi-page document:
using (var reader = new PdfReader(#"C:\Input.pdf"))
{
using (var fileStream = new FileStream(#"C:\Output.pdf", FileMode.Create, FileAccess.Write))
{
var document = new Document(reader.GetPageSizeWithRotation(1));
var writer = PdfWriter.GetInstance(document, fileStream);
document.Open();
for (var i = 1; i <= reader.NumberOfPages; i++)
{
document.NewPage();
var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
var importedPage = writer.GetImportedPage(reader, i);
var contentByte = writer.DirectContent;
contentByte.BeginText();
contentByte.SetFontAndSize(baseFont, 12);
var multiLineString = "Hello,\r\nWorld!".Split('\n');
foreach (var line in multiLineString)
{
contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT, line, 200, 200, 0);
}
contentByte.EndText();
contentByte.AddTemplate(importedPage, 0, 0);
}
document.Close();
writer.Close();
}
}
This worked for me and includes using OutputStream:
PdfReader reader = new PdfReader(new RandomAccessFileOrArray(Request.MapPath("Template.pdf")), null);
Rectangle size = reader.GetPageSizeWithRotation(1);
using (Stream outStream = Response.OutputStream)
{
Document document = new Document(size);
PdfWriter writer = PdfWriter.GetInstance(document, outStream);
document.Open();
try
{
PdfContentByte cb = writer.DirectContent;
cb.BeginText();
try
{
cb.SetFontAndSize(BaseFont.CreateFont(), 12);
cb.SetTextMatrix(110, 110);
cb.ShowText("aaa");
}
finally
{
cb.EndText();
}
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
}
finally
{
document.Close();
writer.Close();
reader.Close();
}
}
Here is a method that uses stamper and absolute coordinates showed in the different PDF clients (Adobe, FoxIt and etc. )
public static void AddTextToPdf(string inputPdfPath, string outputPdfPath, string textToAdd, System.Drawing.Point point)
{
//variables
string pathin = inputPdfPath;
string pathout = outputPdfPath;
//create PdfReader object to read from the existing document
using (PdfReader reader = new PdfReader(pathin))
//create PdfStamper object to write to get the pages from reader
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(pathout, FileMode.Create)))
{
//select two pages from the original document
reader.SelectPages("1-2");
//gettins the page size in order to substract from the iTextSharp coordinates
var pageSize = reader.GetPageSize(1);
// PdfContentByte from stamper to add content to the pages over the original content
PdfContentByte pbover = stamper.GetOverContent(1);
//add content to the page using ColumnText
Font font = new Font();
font.Size = 45;
//setting up the X and Y coordinates of the document
int x = point.X;
int y = point.Y;
y = (int) (pageSize.Height - y);
ColumnText.ShowTextAligned(pbover, Element.ALIGN_CENTER, new Phrase(textToAdd, font), x, y, 0);
}
}
Here is a method To print over images:
taken from here.
Use a different layer for your text you're putting over the images, and also make sure to use the GetOverContent() method.
string oldFile = "FileWithImages.pdf";
string watermarkedFile = "Layers.pdf";
// Creating watermark on a separate layer
// Creating iTextSharp.text.pdf.PdfReader object to read the Existing PDF Document
PdfReader reader1 = new PdfReader(oldFile);
using (FileStream fs = new FileStream(watermarkedFile, FileMode.Create, FileAccess.Write, FileShare.None))
// Creating iTextSharp.text.pdf.PdfStamper object to write Data from iTextSharp.text.pdf.PdfReader object to FileStream object
using (PdfStamper stamper = new PdfStamper(reader1, fs))
{
// Getting total number of pages of the Existing Document
int pageCount = reader1.NumberOfPages;
// Create New Layer for Watermark
PdfLayer layer = new PdfLayer("Layer", stamper.Writer);
// Loop through each Page
for (int i = 1; i <= pageCount; i++)
{
// Getting the Page Size
Rectangle rect = reader1.GetPageSize(i);
// Get the ContentByte object
PdfContentByte cb = stamper.GetOverContent(i);
// Tell the cb that the next commands should be "bound" to this new layer
cb.BeginLayer(layer);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.RED);
cb.SetFontAndSize(bf, 100);
cb.BeginText();
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Some random blablablabla...", rect.Width / 2, rect.Height / 2, - 90);
cb.EndText();
// Close the layer
cb.EndLayer();
}
}
Related
I am using iTextSharp in my code to resize PDF documents and it is working very well, as shown below:
public byte[] ResizePdf(byte[] data) {
PdfReader reader = new PdfReader(data);
Document document = new Document(PageSize.A4);
MemoryStream stream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(document, stream);
document.Open();
PdfContentByte cb = writer.DirectContent;
for (int i = 1; i <= reader.NumberOfPages; i++) {
document.NewPage();
PdfImportedPage page = writer.GetImportedPage(reader, i);
cb.AddTemplate(page, 0.8, 0, 0, 0.8, 25f, 60f);
}
document.Close();
return stream.ToArray();
}
However, when a PDF document is signed, when I try to resize it, I lose the signature on my new resized document.
I've tried to create a copy of the document (follow the code) and it works fine, but I can't resize it.
public byte[] Test(byte[] data) {
PdfReader reader = new PdfReader(data);
Document document = new Document(PageSize.A4);
MemoryStream stream = new MemoryStream();
PdfCopy copy = new PdfCopy(document, stream);
document.Open();
PdfContentByte cb = copy.DirectContent;
for (int i = 1; i <= reader.NumberOfPages; i++) {
document.NewPage();
PdfImportedPage page = copy.GetImportedPage(reader, i);
cb.AddTemplate(page, 0.8, 0, 0, 0.8, 0, 0);
copy.AddPage(page);
}
document.Close();
return stream.ToArray();
}
Does anyone have any tips or anything that can help me?
Thanks in advance!
PdfReader reader = new PdfReader(FileUpload1.PostedFile.FileName);
iTextSharp.text.Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
string name = System.IO.Path.GetFileName(FileUpload1.PostedFile.FileName);
FileStream fs = new FileStream(System.IO.Path.GetFullPath(FileUpload1.PostedFile.FileName), FileMode.Open, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
byte[] data = ReadFully(FileUpload1.PostedFile.InputStream);
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.DarkGray);
cb.SetFontAndSize(bf, 8);
cb.BeginText();
string hash = string.Empty;
using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
{
hash = Convert.ToBase64String(sha1.ComputeHash(data));
}
cb.ShowTextAligned(1, hash, 400, 150, 0);
cb.EndText();
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
document.Close();
fs.Close();
writer.Close();
reader.Close();
I am trying to write a text on my pdf at specific coordinate. My text is getting in pdf but the old content is also getting lost.
please suggest solution.
thanks in advance.
i´m working at a little program.
I have a PDF with 17 pages and i want to place columntext on some of them.
But after creating the PDF i get only Page one out.
{
string newfile = "newfile.pdf";
FileStream fs = new FileStream(newfile, FileMode.Create, FileAccess.Write);
PdfReader reader = null;
PdfWriter writer = null;
PdfImportedPage page = null;
Document dc = null;
dc = new Document(reader.GetPageSizeWithRotation(1));
writer = PdfWriter.GetInstance(dc, fs);
dc.Open();
int numberOfPages = reader.NumberOfPages;
PdfContentByte cb = writer.DirectContent;
reader = new PdfReader(pdfPath);
for (int i = 1; i <= numberOfPages; i++)
{
page = writer.GetImportedPage(reader, startPage);
cb.AddTemplate(page, 0, 0);
if (startPage == 1)
{
cb.BeginText();
ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, new Phrase(new Chunk("<<NAME>>", FontFactory.GetFont("c:\\windows\\fonts\\Roboto-BoldCondensed.ttf", 15, BaseColor.BLACK)).SetSkew(0, 10)), 367.7F, 140.7F, 10);
cb.EndText();
}
startPage++;
}
dc.Close();
fs.Close();
writer.Close();
reader.Close();
}
Addition originally posted as answer
I tried to use stamper but the PDF file ist damaged. Something is wrong with my code string newfile = "newfile2.pdf";
FileStream fs = new FileStream(newfile, FileMode.Create, FileAccess.Write);
PdfReader reader = null;
reader = new PdfReader(pdfPath);
PdfStamper stamper = new PdfStamper(reader,fs);
int numberOfPages = reader.NumberOfPages;
PdfContentByte cb;
for (int i = 1; i <= numberOfPages; i++)
{
cb = stamper.GetOverContent(i);
ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, new Phrase(new Chunk("<<NAME>>", FontFactory.GetFont("c:\\windows\\fonts\\Roboto-BoldCondensed.ttf", 15, BaseColor.BLACK)).SetSkew(0, 10)), 367.7F, 140.7F, 10);
}
fs.Close();
reader.Close();
I want to change the Image position to be in the top right of the pdf as a logo , this code make my image in the top left and some text wrote on it :
string oldFile = #"D:\Source pdf\Source.pdf";
string newFile = #"D:\Result pdf\Result.pdf";
string imagepath = #"D:\Source pdf\Myiamge.jpg";
Console.WriteLine("iText Demo");
PdfReader reader = new PdfReader(oldFile);
Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
iTextSharp.text.Image instanceImg = iTextSharp.text.Image.GetInstance(imagepath);
document.Add(instanceImg);
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.DARK_GRAY);
cb.SetFontAndSize(bf, 8);
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
document.Close();
fs.Close();
writer.Close();
reader.Close();
Can any one help me that how can I cut the PDF page like as Acrobat professional?
This snippet might help you:
public static void CropDocument(string file, string oldchar, string repChar)
{
int pageNumber = 1;
PdfReader reader = new PdfReader(file);
iTextSharp.text.Rectangle size = new iTextSharp.text.Rectangle(
Globals.fX,
Globals.fY,
Globals.fWidth,
Globals.fHeight);
Document document = new Document(size);
PdfWriter writer = PdfWriter.GetInstance(document,
new FileStream(file.Replace(oldchar, repChar),
FileMode.Create, FileAccess.Write));
document.Open();
PdfContentByte cb = writer.DirectContent;
document.NewPage();
PdfImportedPage page = writer.GetImportedPage(reader,
pageNumber);
cb.AddTemplate(page, 0, 0);
document.Close();
}