Reputation: 9
I am trying to replace a particular text inside a PDF using iTextSharp but i am not able to replace it, what my code does is just copy the same file as it is in the destination location. Can anyone help me with this. Following is my code
string src = Server.MapPath("~/Name.pdf");
string dest = Server.MapPath("~/2.pdf");
PdfReader reader = new PdfReader(src);
PdfDictionary dict = reader.GetPageN(1);
PdfObject obj = dict.GetDirectObject(PdfName.CONTENTS);
PRStream stream = (PRStream)obj;
byte[] data = PdfReader.GetStreamBytes(stream);
string dd = new string(System.Text.Encoding.UTF8.GetString(data).ToCharArray());
dd = dd.Replace("@Name", "John Smith");
stream.SetData(System.Text.Encoding.UTF8.GetBytes(dd));
PdfStamper stamper = new PdfStamper(reader, new System.IO.FileStream(dest, System.IO.FileMode.Create));
stamper.Close();
reader.Close();
Upvotes: 0
Views: 6374
Reputation: 93
What about using the following approach:
string formFile = <Your pdf filepath goes here>;
PdfReader reader = new PdfReader(formFile);
MemoryStream stream = new MemoryStream();
PdfStamper stamper = new PdfStamper(reader, stream);
AcroFields fields = stamper.AcroFields;
fields.SetField("{{FirstName}}", objUser.FirstName);
fields.SetField("{{ContactNumber}}", objUser.EmailId);
fields.SetField("{{Address1}}", objUser.AddressLine1);
fields.SetField("{{Address2}}", objUser.AddressLine2);
fields.SetField("{{Qualification}}", objUser.Education);
fields.SetField("{{AppNumber}}", "01A2021"+objUser.UserId.ToString());
stamper.Writer.CloseStream = false;
stamper.FormFlattening = true;
stamper.Close();
stream.Position = 0;
And use that stream as you like
Upvotes: 0
Reputation: 109
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using System.Drawing;
using iTextSharp.text;
namespace pdf_edit_work
{
/// <summary>
/// Replace the text in PDF
/// </summary>
public class PDFEdit
{
/// <summary>
/// Find the text and replace in PDF
/// </summary>
/// <param name="sourceFile">The source PDF file where text to be searched</param>
/// <param name="descFile">The new destination PDF file which will be saved with replaced text</param>
/// <param name="textToBeSearched">The text to be searched in the PDF</param>
/// <param name="textToBeReplaced">The text to be replaced with</param>
public void ReplaceTextInPDF(string sourceFile, string descFile, string textToBeSearched, string textToBeReplaced)
{
ReplaceText(textToBeSearched, textToBeReplaced, descFile, sourceFile);
}
private void ReplaceText(string textToBeSearched, string textToAdd, string outputFilePath, string inputFilePath)
{
try
{
using (Stream inputPdfStream = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream outputPdfStream = new FileStream(outputFilePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
using (Stream outputPdfStream2 = new FileStream(outputFilePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
{
//Opens the unmodified PDF for reading
PdfReader reader = new PdfReader(inputPdfStream);
//Creates a stamper to put an image on the original pdf
PdfStamper stamper = new PdfStamper(reader, outputPdfStream); //{ FormFlattening = true, FreeTextFlattening = true };
for (var i = 1; i <= reader.NumberOfPages; i++)
{
var tt = new MyLocationTextExtractionStrategy(textToBeSearched);
var ex = PdfTextExtractor.GetTextFromPage(reader, i, tt); // ex will be holding the text, although we just need the rectangles [RectAndText class objects]
foreach (var p in tt.myPoints)
{
//Creates an image that is the size i need to hide the text i'm interested in removing
Bitmap transparentBitmap = new Bitmap((int)p.Rect.Width, (int)p.Rect.Height);
transparentBitmap.MakeTransparent();
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(transparentBitmap, new BaseColor(255, 255, 255));
//Sets the position that the image needs to be placed (ie the location of the text to be removed)
image.SetAbsolutePosition(p.Rect.Left, (p.Rect.Top - 8));
//Adds the image to the output pdf
stamper.GetOverContent(i).AddImage(image, true); // i stands for the page no.
PdfContentByte cb = stamper.GetOverContent(i);
// select the font properties
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.BLACK);
cb.SetFontAndSize(bf, 7);
// write the text in the pdf content
cb.BeginText();
// put the alignment and coordinates here
cb.ShowTextAligned(1, textToAdd, p.Rect.Left + 10, p.Rect.Top - 6, 0);
cb.EndText();
}
}
//Creates the first copy of the outputted pdf
stamper.Close();
}
}
catch (Exception ex)
{
}
}
public class RectAndText
{
public iTextSharp.text.Rectangle Rect;
public String Text;
public RectAndText(iTextSharp.text.Rectangle rect, String text)
{
this.Rect = rect;
this.Text = text;
}
}
public class MyLocationTextExtractionStrategy : LocationTextExtractionStrategy
{
//Hold each coordinate
public List<RectAndText> myPoints = new List<RectAndText>();
//The string that we're searching for
public String TextToSearchFor { get; set; }
//How to compare strings
public System.Globalization.CompareOptions CompareOptions { get; set; }
public MyLocationTextExtractionStrategy(String textToSearchFor, System.Globalization.CompareOptions compareOptions = System.Globalization.CompareOptions.None)
{
this.TextToSearchFor = textToSearchFor;
this.CompareOptions = compareOptions;
}
//Automatically called for each chunk of text in the PDF
public override void RenderText(TextRenderInfo renderInfo)
{
base.RenderText(renderInfo);
//See if the current chunk contains the text
var startPosition = System.Globalization.CultureInfo.CurrentCulture.CompareInfo.IndexOf(renderInfo.GetText(), this.TextToSearchFor, this.CompareOptions);
//If not found bail
if (startPosition < 0)
{
return;
}
//Grab the individual characters
var chars = renderInfo.GetCharacterRenderInfos().Skip(startPosition).Take(this.TextToSearchFor.Length).ToList();
//Grab the first and last character
var firstChar = chars.First();
var lastChar = chars.Last();
//Get the bounding box for the chunk of text
var bottomLeft = firstChar.GetDescentLine().GetStartPoint();
var topRight = lastChar.GetAscentLine().GetEndPoint();
//Create a rectangle from it
var rect = new iTextSharp.text.Rectangle(bottomLeft[Vector.I1], bottomLeft[Vector.I2], topRight[Vector.I1], topRight[Vector.I2]);
//Add this to our main collection
this.myPoints.Add(new RectAndText(rect, this.TextToSearchFor));
}
}
}
}
usage of PDFEdit class
string sourceFile = @"C:\original.pdf";
string descFile = @"C:\original_with_text_replaced.pdf";
PDFEdit pdfObj = new PDFEdit();
pdfObj.ReplaceTextInPDF(sourceFile, descFile, "text_to_be_searched", "text_to_be_replaced_with");
Upvotes: 0