Replacing Specific Text Inside PDF Using iTextSharp ASP.NET - c#

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

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");

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

Related

Replacing text in merged pdf file

i have a pdf file. There is a footer on each page. now i want to replace a static text exist on footer with some other text. Please Help me.....
I have tried with following case but not success
PdfReader readere = new PdfReader(#"D:\MergedOutput.pdf");
for (int i = 1; i < readere.NumberOfPages; i++)
{
byte[] contentBytes = PdfEncodings.ConvertToBytes(PdfTextExtractor.GetTextFromPage(readere, i), PdfObject.TEXT_PDFDOCENCODING);
byte[] searchStringArray = PdfEncodings.ConvertToBytes("Side", PdfObject.TEXT_PDFDOCENCODING);
byte[] replacedByString = PdfEncodings.ConvertToBytes("Hello", PdfObject.TEXT_PDFDOCENCODING);
string searchString = PdfEncodings.ConvertToString(searchStringArray, PdfObject.TEXT_PDFDOCENCODING);
string contentString = PdfEncodings.ConvertToString(contentBytes, PdfObject.TEXT_PDFDOCENCODING);
string replaceString = PdfEncodings.ConvertToString(replacedByString, PdfObject.TEXT_PDFDOCENCODING);
if (contentString.Contains(searchString))
{
contentString = contentString.Replace(searchString, replaceString);
}
readere.SetPageContent(i, PdfEncodings.ConvertToBytes(contentString, PdfObject.TEXT_PDFDOCENCODING));
}
Suppose you have a byte array of PDF data or any PDF files. First convert this file to byte array.. after that we have to apply below code section. its working fine for me...
iTextSharp.text.Font blackFont = FontFactory.GetFont("Seoge UI", 10, iTextSharp.text.Font.NORMAL, new BaseColor(Color.FromArgb(97, 102, 116)));
//Path to where you want the file to output
string outputFilePath = "MergedOutputt.pdf";
//Path to where the pdf you want to modify is
//string inputFilePath = "D:\\MergedOutput.pdf";
try
{
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
var reader = new PdfReader(MergedOutputStream.ToArray());
//Creates a stamper to put an image on the original pdf
var stamper = new PdfStamper(reader, outputPdfStream) { FormFlattening = true, FreeTextFlattening = true };
for (int i = 1; i <= reader.NumberOfPages; i++)
{
//Creates an image that is the size i need to hide the text i'm interested in removing
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(new Bitmap(120, 20), BaseColor.WHITE);
//Sets the position that the image needs to be placed (ie the location of the text to be removed)
image.SetAbsolutePosition(reader.GetPageSize(i).Width - 120, 42);
//Adds the image to the output pdf
stamper.GetOverContent(i).AddImage(image, true);
//Creates the first copy of the outputted pdf
PdfPTable table = new PdfPTable(1);
float[] width = new float[] { 38 };
table.SetTotalWidth(width);
PdfContentByte pb;
//Get PdfContentByte object for first page of pdf file
pb = stamper.GetOverContent(i);
cellSequenceNumber = new PdfPCell(new Phrase(new Chunk("Side " + i.ToString(), blackFont)));
cellSequenceNumber.Border = 0;
table.AddCell(cellSequenceNumber);
table.WriteSelectedRows(0, table.Rows.Count, reader.GetPageSize(i).Width - 82, 54, pb);
}
stamper.Close();
//Opens our outputted file for reading
var reader2 = new PdfReader(outputPdfStream2);
reader2.Close();
}
}
It will generate a pdf file named as "MergedOutputt.pdf"

Creating a PDF file?

I looked into iTextSharp and SharpPDF and Report.Net as well as PDFSharp.
None of these open source projects have good documentation OR do not work with VS 2012.
Does anyone have a recommended solution or can show me the documentation?
My employer blocks many sites and although Google is not blocked, some of the results are.
I plan on using C# with WinForms and obtaining my data from an Access DB
Hey #Cocoa Dev get this a complete example with diferent functions.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using iTextSharp.text.pdf;
using System.Data;
using System.Text;
using System.util.collections;
using iTextSharp.text;
using System.Net.Mail;
public partial class PDFScenarios : System.Web.UI.Page
{
public string P_InputStream = "~/MyPDFTemplates/ex1.pdf";
public string P_InputStream2 = "~/MyPDFTemplates/ContactInfo.pdf";
public string P_InputStream3 = "~/MyPDFTemplates/MulPages.pdf";
public string P_InputStream4 = "~/MyPDFTemplates/CompanyLetterHead.pdf";
public string P_OutputStream = "~/MyPDFOutputs/ex1_1.pdf";
//Read all 'Form values/keys' from an existing multi-page PDF document
public void ReadPDFformDataPageWise()
{
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream3));
AcroFields form = reader.AcroFields;
try
{
for (int page = 1; page <= reader.NumberOfPages; page++)
{
foreach (KeyValuePair<string, AcroFields.Item> kvp in form.Fields)
{
switch (form.GetFieldType(kvp.Key))
{
case AcroFields.FIELD_TYPE_CHECKBOX:
case AcroFields.FIELD_TYPE_COMBO:
case AcroFields.FIELD_TYPE_LIST:
case AcroFields.FIELD_TYPE_RADIOBUTTON:
case AcroFields.FIELD_TYPE_NONE:
case AcroFields.FIELD_TYPE_PUSHBUTTON:
case AcroFields.FIELD_TYPE_SIGNATURE:
case AcroFields.FIELD_TYPE_TEXT:
int fileType = form.GetFieldType(kvp.Key);
string fieldValue = form.GetField(kvp.Key);
string translatedFileName = form.GetTranslatedFieldName(kvp.Key);
break;
}
}
}
}
catch
{
}
finally
{
reader.Close();
}
}
//Read and alter form values for only second and
//third page of an existing multi page PDF doc.
//Save the changes in a brand new pdf file.
public void ReadAlterPDFformDataInSelectedPages()
{
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream3));
reader.SelectPages("1-2"); //Work with only page# 1 & 2
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(Server.MapPath(P_OutputStream), FileMode.Create)))
{
AcroFields form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
//Replace Address Form field with my custom data
if (fieldKey.Contains("Address"))
{
form.SetField(fieldKey, "MyCustomAddress");
}
}
//The below will make sure the fields are not editable in
//the output PDF.
stamper.FormFlattening = true;
}
}
//Extract text from an existing PDF's second page.
private string ExtractText()
{
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream3));
string txt = PdfTextExtractor.GetTextFromPage(reader, 2, new LocationTextExtractionStrategy());
return txt;
}
//Create a brand new PDF from scratch and without a template
private void CreatePDFNoTemplate()
{
Document pdfDoc = new Document();
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, new FileStream(Server.MapPath(P_OutputStream), FileMode.OpenOrCreate));
pdfDoc.Open();
pdfDoc.Add(new Paragraph("Some data"));
PdfContentByte cb = writer.DirectContent;
cb.MoveTo(pdfDoc.PageSize.Width / 2, pdfDoc.PageSize.Height / 2);
cb.LineTo(pdfDoc.PageSize.Width / 2, pdfDoc.PageSize.Height);
cb.Stroke();
pdfDoc.Close();
}
private void fillPDFForm()
{
string formFile = Server.MapPath(P_InputStream);
string newFile = Server.MapPath(P_OutputStream);
PdfReader reader = new PdfReader(formFile);
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create)))
{
AcroFields fields = stamper.AcroFields;
// set form fields
fields.SetField("name", "John Doe");
fields.SetField("address", "xxxxx, yyyy");
fields.SetField("postal_code", "12345");
fields.SetField("email", "johndoe#xxx.com");
// flatten form fields and close document
stamper.FormFlattening = true;
stamper.Close();
}
}
//Helper functions
private void SendEmail(MemoryStream ms)
{
MailAddress _From = new MailAddress("XXX#domain.com");
MailAddress _To = new MailAddress("YYY#a.com");
MailMessage email = new MailMessage(_From, _To);
Attachment attach = new Attachment(ms, new System.Net.Mime.ContentType("application/pdf"));
email.Attachments.Add(attach);
SmtpClient mailSender = new SmtpClient("Gmail-Server");
mailSender.Send(email);
}
private void DownloadAsPDF(MemoryStream ms)
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment;filename=abc.pdf");
Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
Response.OutputStream.Flush();
Response.OutputStream.Close();
Response.End();
ms.Close();
}
//Working with Memory Stream and PDF
public void CreatePDFFromMemoryStream()
{
//(1)using PDFWriter
Document doc = new Document();
MemoryStream memoryStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream);
doc.Open();
doc.Add(new Paragraph("Some Text"));
writer.CloseStream = false;
doc.Close();
//Get the pointer to the beginning of the stream.
memoryStream.Position = 0;
//You may use this PDF in memorystream to send as an attachment in an email
//OR download as a PDF
SendEmail(memoryStream);
DownloadAsPDF(memoryStream);
//(2)Another way using PdfStamper
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream2));
using (MemoryStream ms = new MemoryStream())
{
PdfStamper stamper = new PdfStamper(reader, ms);
AcroFields fields = stamper.AcroFields;
fields.SetField("SomeField", "MyValueFromDB");
stamper.FormFlattening = true;
stamper.Close();
SendEmail(ms);
}
}
//Burst-- Make each page of an existing multi-page PDF document
//as another brand new PDF document
private void PDFBurst()
{
string pdfTemplatePath = Server.MapPath(P_InputStream3);
PdfReader reader = new PdfReader(pdfTemplatePath);
//PdfCopy copy;
PdfSmartCopy copy;
for (int i = 1; i < reader.NumberOfPages; i++)
{
Document d1 = new Document();
copy = new PdfSmartCopy(d1, new FileStream(Server.MapPath(P_OutputStream).Replace(".pdf", i.ToString() + ".pdf"), FileMode.Create));
d1.Open();
copy.AddPage(copy.GetImportedPage(reader, i));
d1.Close();
}
}
//Copy a set of form fields from an existing PDF template/doc
//and keep appending to a brand new PDF file.
//The copied set of fields will have different values.
private void AppendSetOfFormFields()
{
PdfCopyFields _copy = new PdfCopyFields(new FileStream(Server.MapPath(P_OutputStream), FileMode.Create));
_copy.AddDocument(new PdfReader(a1("1")));
_copy.AddDocument(new PdfReader(a1("2")));
_copy.AddDocument(new PdfReader(new FileStream(Server.MapPath("~/MyPDFTemplates/Myaspx.pdf"), FileMode.Open)));
_copy.Close();
}
//ConcatenateForms
private byte[] a1(string _ToAppend)
{
using (var existingFileStream = new FileStream(Server.MapPath(P_InputStream), FileMode.Open))
using (MemoryStream stream = new MemoryStream())
{
// Open existing PDF
var pdfReader = new PdfReader(existingFileStream);
var stamper = new PdfStamper(pdfReader, stream);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
form.RenameField(fieldKey, fieldKey + _ToAppend);
}
// "Flatten" the form so it wont be editable/usable anymore
stamper.FormFlattening = true;
stamper.Close();
pdfReader.Close();
return stream.ToArray();
}
}
//Working with Image
private void AddAnImage()
{
using (var inputPdfStream = new FileStream(#"C:\MyInput.pdf", FileMode.Open))
using (var inputImageStream = new FileStream(#"C:\img1.jpg", FileMode.Open))
using (var outputPdfStream = new FileStream(#"C:\MyOutput.pdf", FileMode.Create))
{
PdfReader reader = new PdfReader(inputPdfStream);
PdfStamper stamper = new PdfStamper(reader, outputPdfStream);
PdfContentByte pdfContentByte = stamper.GetOverContent(1);
var image = iTextSharp.text.Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(1, 1);
pdfContentByte.AddImage(image);
stamper.Close();
}
}
//Add Company Letter-Head/Stationary to an existing pdf
private void AddCompanyStationary()
{
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream2));
PdfReader s_reader = new PdfReader(Server.MapPath(P_InputStream4));
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(Server.MapPath(P_OutputStream), FileMode.Create)))
{
PdfImportedPage page = stamper.GetImportedPage(s_reader, 1);
int n = reader.NumberOfPages;
PdfContentByte background;
for (int i = 1; i <= n; i++)
{
background = stamper.GetUnderContent(i);
background.AddTemplate(page, 0, 0);
}
stamper.Close();
}
}
Try this example:
using iTextSharp.text;
// Set up the fonts to be used on the pages
private Font _largeFont = new Font(Font.FontFamily.HELVETICA, 18, Font.BOLD, BaseColor.BLACK);
private Font _standardFont = new Font(Font.FontFamily.HELVETICA, 14, Font.NORMAL, BaseColor.BLACK);
private Font _smallFont = new Font(Font.FontFamily.HELVETICA, 10, Font.NORMAL, BaseColor.BLACK);
public void Build()
{
iTextSharp.text.Document doc = null;
try
{
// Initialize the PDF document
doc = new Document();
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc,
new System.IO.FileStream(System.IO.Directory.GetCurrentDirectory() + "\\ScienceReport.pdf",
System.IO.FileMode.Create));
// Set margins and page size for the document
doc.SetMargins(50, 50, 50, 50);
// There are a huge number of possible page sizes, including such sizes as
// EXECUTIVE, LEGAL, LETTER_LANDSCAPE, and NOTE
doc.SetPageSize(new iTextSharp.text.Rectangle(iTextSharp.text.PageSize.LETTER.Width,
iTextSharp.text.PageSize.LETTER.Height));
// Add metadata to the document. This information is visible when viewing the
// document properities within Adobe Reader.
doc.AddTitle("My Science Report");
doc.AddCreator("M. Lichtenberg");
doc.AddKeywords("paper airplanes");
// Add Xmp metadata to the document.
this.CreateXmpMetadata(writer);
// Open the document for writing content
doc.Open();
// Add pages to the document
this.AddPageWithBasicFormatting(doc);
this.AddPageWithInternalLinks(doc);
this.AddPageWithBulletList(doc);
this.AddPageWithExternalLinks(doc);
this.AddPageWithImage(doc, System.IO.Directory.GetCurrentDirectory() + "\\FinalGraph.jpg");
// Add page labels to the document
iTextSharp.text.pdf.PdfPageLabels pdfPageLabels = new iTextSharp.text.pdf.PdfPageLabels();
pdfPageLabels.AddPageLabel(1, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "Basic Formatting");
pdfPageLabels.AddPageLabel(2, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "Internal Links");
pdfPageLabels.AddPageLabel(3, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "Bullet List");
pdfPageLabels.AddPageLabel(4, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "External Links");
pdfPageLabels.AddPageLabel(5, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "Image");
writer.PageLabels = pdfPageLabels;
}
catch (iTextSharp.text.DocumentException dex)
{
// Handle iTextSharp errors
}
finally
{
// Clean up
doc.Close();
doc = null;
}
}
You can always just create an html page and then convert that to pdf using wkhtmltopdf. This has the benefit of you not having to construct the pdf with a library such as iText. You just make a text file (html) and then pass it to the wkhtmltopdf executable.
See Calling wkhtmltopdf to generate PDF from HTML for more info.

PDF Merging by ItextSharp

How would I merge several pdf pages into one with iTextSharp which also supports merging pages having form elements like textboxes, checkboxes, etc.
I have tried so many by googling, but nothing has worked well.
See my answer here Merging Memory Streams. I give an example of how to merge PDFs with itextsharp.
For updating form field names add this code that uses the stamper to change the form field names.
/// <summary>
/// Merges pdf files from a byte list
/// </summary>
/// <param name="files">list of files to merge</param>
/// <returns>memory stream containing combined pdf</returns>
public MemoryStream MergePdfForms(List<byte[]> files)
{
if (files.Count > 1)
{
string[] names;
PdfStamper stamper;
MemoryStream msTemp = null;
PdfReader pdfTemplate = null;
PdfReader pdfFile;
Document doc;
PdfWriter pCopy;
MemoryStream msOutput = new MemoryStream();
pdfFile = new PdfReader(files[0]);
doc = new Document();
pCopy = new PdfSmartCopy(doc, msOutput);
pCopy.PdfVersion = PdfWriter.VERSION_1_7;
doc.Open();
for (int k = 0; k < files.Count; k++)
{
for (int i = 1; i < pdfFile.NumberOfPages + 1; i++)
{
msTemp = new MemoryStream();
pdfTemplate = new PdfReader(files[k]);
stamper = new PdfStamper(pdfTemplate, msTemp);
names = new string[stamper.AcroFields.Fields.Keys.Count];
stamper.AcroFields.Fields.Keys.CopyTo(names, 0);
foreach (string name in names)
{
stamper.AcroFields.RenameField(name, name + "_file" + k.ToString());
}
stamper.Close();
pdfFile = new PdfReader(msTemp.ToArray());
((PdfSmartCopy)pCopy).AddPage(pCopy.GetImportedPage(pdfFile, i));
pCopy.FreeReader(pdfFile);
}
}
pdfFile.Close();
pCopy.Close();
doc.Close();
return msOutput;
}
else if (files.Count == 1)
{
return new MemoryStream(files[0]);
}
return null;
}
Here is my simplified version of Jonathan's Merge code with namespaces added, and stamping removed.
public IO.MemoryStream MergePdfForms(System.Collections.Generic.List<byte[]> files)
{
if (files.Count > 1) {
using (System.IO.MemoryStream msOutput = new System.IO.MemoryStream()) {
using (iTextSharp.text.Document doc = new iTextSharp.text.Document()) {
using (iTextSharp.text.pdf.PdfSmartCopy pCopy = new iTextSharp.text.pdf.PdfSmartCopy(doc, msOutput) { PdfVersion = iTextSharp.text.pdf.PdfWriter.VERSION_1_7 }) {
doc.Open();
foreach (byte[] oFile in files) {
using (iTextSharp.text.pdf.PdfReader pdfFile = new iTextSharp.text.pdf.PdfReader(oFile)) {
for (i = 1; i <= pdfFile.NumberOfPages; i++) {
pCopy.AddPage(pCopy.GetImportedPage(pdfFile, i));
pCopy.FreeReader(pdfFile);
}
}
}
}
}
return msOutput;
}
} else if (files.Count == 1) {
return new System.IO.MemoryStream(files[0]);
}
return null;
}
to merge PDF see "Merging two pdf pages into one using itextsharp"
Below is my code for pdf merging.Thanks Jonathan for giving suggestion abt renaming fields,which resolved the issues while merging pdf pages with form fields.
private static void CombineAndSavePdf(string savePath, List<string> lstPdfFiles)
{
using (Stream outputPdfStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
Document document = new Document();
PdfSmartCopy copy = new PdfSmartCopy(document, outputPdfStream);
document.Open();
PdfReader reader;
int totalPageCnt;
PdfStamper stamper;
string[] fieldNames;
foreach (string file in lstPdfFiles)
{
reader = new PdfReader(file);
totalPageCnt = reader.NumberOfPages;
for (int pageCnt = 0; pageCnt < totalPageCnt; )
{
//have to create a new reader for each page or PdfStamper will throw error
reader = new PdfReader(file);
stamper = new PdfStamper(reader, outputPdfStream);
fieldNames = new string[stamper.AcroFields.Fields.Keys.Count];
stamper.AcroFields.Fields.Keys.CopyTo(fieldNames, 0);
foreach (string name in fieldNames)
{
stamper.AcroFields.RenameField(name, name + "_file" + pageCnt.ToString());
}
copy.AddPage(copy.GetImportedPage(reader, ++pageCnt));
}
copy.FreeReader(reader);
}
document.Close();
}
}

Changing font of PDF using iTextSharp

How can I change the font of a existing PDF file with iTextSharp in C#?
I want to change the whole documents font into one e.g. Arial
Finally I solved the problem.
The following code will open an existing Pdf file and will change all its font to 'Braille' as per my expectation.
private static void ChangeFont()
{
string strFile = #"E:\\xyz.pdf";
string OutputFile = #"E:\\xyz1.pdf";
PdfReader pdfReader = new PdfReader(strFile);
//Get first page,Generally we get font information on first page,however we can loop throw pages e.g for(int i=0;i<=pdfReader.NumberOfPages;i++)
PdfDictionary cpage = pdfReader.GetPageN(1);
if (cpage == null)
return;
PdfDictionary dictFonts = cpage.GetAsDict(PdfName.RESOURCES).GetAsDict(PdfName.FONT);
if (dictFonts != null)
{
foreach (var font in dictFonts)
{
var dictFontInfo = dictFonts.GetAsDict(font.Key);
if (dictFontInfo != null)
{
foreach (var f in dictFontInfo)
{
//Get the font name-optional code
var baseFont = dictFontInfo.Get(PdfName.BASEFONT);
string strFontName = System.Text.Encoding.ASCII.GetString(baseFont.GetBytes(), 0,
baseFont.Length);
//
//Remove the current font
dictFontInfo.Remove(PdfName.BASEFONT);
//Set new font eg. Braille, Areal etc
dictFontInfo.Put(PdfName.BASEFONT, new PdfString("Braille"));
break;
}
}
}
}
//Now create a new document with updated font
using (FileStream FS = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document Doc = new Document())
{
using (PdfCopy writer = new PdfCopy(Doc, FS))
{
Doc.Open();
for (int j = 1; j <= pdfReader.NumberOfPages; j++)
{
writer.AddPage(writer.GetImportedPage(pdfReader, j));
}
Doc.Close();
}
}
}
pdfReader.Close();
}

iTextSharp RAM (memory) overflow

I'm generating a PDF document based on template. The document has multiple pages. The document can have about 5000 pages. When creating the 500-th page I get an overflow RAM (memory). Any idea?
public static void CreateBankBlank2012Year(string pdfTemplatePath, string directoryOutPdf, string nameOutPdf, AnnualReportsFilterParameters filterParametrs, string serverPath)
{
// Get details salary
IEnumerable<SalayDetailsForPdf> dataSalaryDetails = (IEnumerable<SalayDetailsForPdf>) GetSalaryData(filterParametrs);
String fontPath = Path.Combine(serverPath + "\\Fonts", "STSONG.ttf");
Font font = FontFactory.GetFont(fontPath, BaseFont.IDENTITY_H, 8);
using (Document document = new Document())
{
using (PdfSmartCopy copy = new PdfSmartCopy(
document, new FileStream(directoryOutPdf + nameOutPdf, FileMode.Create))
)
{
document.Open();
foreach (var data in dataSalaryDetails)
{
PdfReader reader = new PdfReader(pdfTemplatePath + #"\EmptyTemplateBankBlank_2012.pdf");
using (var ms = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(reader, ms))
{
stamper.AcroFields.AddSubstitutionFont(font.BaseFont);
AcroFields form = stamper.AcroFields;
form.SetField("t1_address1", data.Address1);
form.SetField("t1_name", data.NameHieroglyphic);
// Other field ...
stamper.FormFlattening = true;
}
reader = new PdfReader(ms.ToArray());
copy.AddPage(copy.GetImportedPage(reader, 1));
}
}
}
}
}
p.s
I'm trying resolve my problem as follow:
generating empty pages based on template
private static void GeneratePdfFromTemplate(string directoryOutPdf, string nameOutPdf, string pdfTemplatePath, int countPages)
{
using (Document document = new Document())
{
using (PdfSmartCopy copy = new PdfSmartCopy(
document, new FileStream(directoryOutPdf + nameOutPdf, FileMode.Create))
)
{
document.Open();
PdfReader reader = new PdfReader(pdfTemplatePath + #"\EmptyTemplateBankBlank_2012.pdf");
for (int i = 0; i < countPages; i++)
{
copy.AddPage(copy.GetImportedPage(reader, 1));
}
reader.Close();
copy.Close();
}
document.Close();
}
GC.Collect();
}
But after a generating I can't set values to the fields.
I'm found solution for my problem, if anyone else would be interested :
private static void SettingFieltValue(Font font, IEnumerable<SalayDetailsForPdf> dataSalaryDetails, int selectedYear, string directoryOutPdf, string nameOutPdf, string pdfTemplatePath)
{
string pdfTemplate = pdfTemplatePath + #"\EmptyTemplateBankBlank_2012.pdf";
string newFile = directoryOutPdf + nameOutPdf;
var fs = new FileStream(newFile, FileMode.Create);
var conc = new PdfConcatenate(fs, true);
foreach (var data in dataSalaryDetails)
{
var reader = new PdfReader(pdfTemplate);
using (var ms = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(reader, ms))
{
stamper.AcroFields.AddSubstitutionFont(font.BaseFont);
AcroFields form = stamper.AcroFields;
form.SetField("t1_name", data.NameHieroglyphic);
//Other field
stamper.FormFlattening = true;
stamper.Close();
}
reader = new PdfReader(ms.ToArray());
ms.Close();
}
conc.AddPages(reader);
reader.Close();
}
conc.Close();
}

Categories

Resources