ITextSharp insert text to an existing pdf
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)
How to add text to an existing pdf without overwriting the content with iText7 and C#?
Whenever you want to add something to an existing pdf, you have to not only write but also read, i.e. you need both a PdfWriter
and a PdfReader
for the PdfDocument
:
PdfReader reader = new PdfReader(source);
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdf = new PdfDocument(reader, writer);
If you furthermore don't want existing content to be covered by new content, you have to tell the objects so, e.g. if you use a Document
to add new content:
Document document = new Document(pdf);
document.Add(new AreaBreak(AreaBreakType.LAST_PAGE));
document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
document.Add(new Paragraph(rdr.ReadToEnd()));
document.Close();
Insert text in existing pdf with itextsharp
Two remarks:
- You add the text first, then you add the image. Hence the image covers the text. That's elementary logic. If you switch the order and add the image first, then the text, the text will cover the image. That's pure common sense.
- You manipulate an existing PDF by importing a
PdfImportedPage
andPdfWriter
. That proves thaf you didn't read the documentation. You should usePdfStamper
instead!
Your code is too complex. Switch to PdfStamper
and add text using the ColumnText
object. Don't use BeginText()
/ EndText()
. Also: why are you using EndLayer()
??? Do you have any idea what that method is meant for?
Adding text to existing multipage PDF document in memorystream using iTextSharp
The code below shows off a full-working example of creating a PDF in memory and then performing a second pass, also in memory. It does what @mkl says and closes all iText parts before trying to grab the raw bytes from the stream. It also uses GetOverContent()
to draw "on top" of the previous pdf. See the code comments for more details.
//Bytes will hold our final PDFs
byte[] bytes;
//Create an in-memory PDF
using (var ms = new MemoryStream()) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, ms)) {
doc.Open();
//Create a bunch of pages and add text, nothing special here
for (var i = 1; i <= 10; i++) {
doc.NewPage();
doc.Add(new Paragraph(String.Format("First Pass - Page {0}", i)));
}
doc.Close();
}
}
//Right before disposing of the MemoryStream grab all of the bytes
bytes = ms.ToArray();
}
//Another in-memory PDF
using (var ms = new MemoryStream()) {
//Bind a reader to the bytes that we created above
using (var reader = new PdfReader(bytes)) {
//Store our page count
var pageCount = reader.NumberOfPages;
//Bind a stamper to our reader
using (var stamper = new PdfStamper(reader, ms)) {
//Setup a font to use
var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
//Loop through each page
for (var i = 1; i <= pageCount; i++) {
//Get the raw PDF stream "on top" of the existing content
var cb = stamper.GetOverContent(i);
//Draw some text
cb.BeginText();
cb.SetFontAndSize(baseFont, 18);
cb.ShowText(String.Format("Second Pass - Page {0}", i));
cb.EndText();
}
}
}
//Once again, grab the bytes before closing things out
bytes = ms.ToArray();
}
//Just to see the final results I'm writing these bytes to disk but you could do whatever
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
System.IO.File.WriteAllBytes(testFile, bytes);
Related Topics
Adding Stylesheets Programmatically in ASP.NET
How to Print the Current Stack Trace in .Net Without Any Exception
How to Detect Windows Shutdown or Logoff
How to Display a Popup from a Webbrowser in Another Window I Created
Xml Serialization and Inherited Types
"A Lambda Expression with a Statement Body Cannot Be Converted to an Expression Tree"
How to Access Backing Fields Behind Auto-Implemented Properties
Get Controller and Action Name from Within Controller
How to Access an Internal Class from an External Assembly
C# (Mono) Linux Web Server Hosting with Consistent Static Variables Across Threads
Is There a Built-In Method to Compare Collections
How to Fix a Opacity Bug with Drawtobitmap on Webbrowser Control
How to Run a C# Application at Windows Startup