Hi I have a pdf I created using itextsharp.
Using pdfreader I am reading the created pdf into a pdfstamper.
Now I am trying to use the pdfstamper to add a black rectangle the size of the page on all pages. How do i do this?
Also I cannot use document to add the rectangle because the stream is close!
MemoryStream stream = new MemoryStream();
PdfReader pdfReader = new PdfReader(output.ToArray());
PdfStamper stamper = new PdfStamper(pdfReader, stream);
for (int x = 0; x < stamper.Reader.NumberOfPages; x++)
{
Rectangle rectangle = document.PageSize;
rectangle.BackgroundColor = new BaseColor(0, 0, 0);
//stamper.Writer.AcroForm.
//document.Add(rectangle);
}
output.Close();
pdfReader.Close();
stamper.Close();
If you want to draw using the PdfStamper then you need to use the PdfContentByte which you can get by calling stamper.GetOverContent(pageNum). There's a specific command on that object called Rectangle which does exactly what you want it to do. Also, remember that pages within a PDF start numbering at one and not zero.
Below is a full working C# 2010 WinForm app targeting iTextSharp 5.1.1.0 that should do what you're looking for, I think. You'll need to modify it to support the MemoryStream but that should be pretty easy.
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string inputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "input.pdf");
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "output.pdf");
PdfReader pdfReader = new PdfReader(inputFile);
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (PdfStamper stamper = new PdfStamper(pdfReader, fs))
{
int PageCount = pdfReader.NumberOfPages;
for (int x = 1; x <= PageCount; x++)
{
PdfContentByte cb = stamper.GetOverContent(x);
iTextSharp.text.Rectangle rectangle = pdfReader.GetPageSizeWithRotation(x);
rectangle.BackgroundColor = BaseColor.BLACK;
cb.Rectangle(rectangle);
}
}
}
this.Close();
}
}
}
Related
I have the code for my pdf merge application but I need help on how to make this all work. I need help on the winforms Design. Obviously its just a blank screen right now without the design.
Below you will see my form code which is labeled form1.cs and program.cs which is below
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
form1.cs
using System;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Folder that we'll work from
string workingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
string pdf1 = Path.Combine(workingFolder, "pdf1.pdf");//PDF with solid red background color
string pdf2 = Path.Combine(workingFolder, "pdf2.pdf");//PDF with text
string pdf3 = Path.Combine(workingFolder, "pdf3.pdf");//Merged PDF
//Create a basic PDF filled with red, nothing special
using (FileStream fs = new FileStream(pdf1, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document doc = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
{
doc.Open();
PdfContentByte cb = writer.DirectContent;
cb.SetColorFill(BaseColor.RED);
cb.Rectangle(0, 0, doc.PageSize.Width, doc.PageSize.Height);
cb.Fill();
doc.Close();
}
}
}
//Create a basic PDF with a single line of text, nothing special
using (FileStream fs = new FileStream(pdf2, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document doc = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
{
doc.Open();
doc.Add(new Paragraph("This is a test"));
doc.Close();
}
}
}
//Create a basic PDF
using (FileStream fs = new FileStream(pdf3, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document doc = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
{
doc.Open();
//Get page 1 of the first file
PdfImportedPage imp1 = writer.GetImportedPage(new PdfReader(pdf1), 1);
//Get page 2 of the second file
PdfImportedPage imp2 = writer.GetImportedPage(new PdfReader(pdf2), 1);
//Add the first file to coordinates 0,0
writer.DirectContent.AddTemplate(imp1, 0, 0);
//Since we don't call NewPage the next call will operate on the same page
writer.DirectContent.AddTemplate(imp2, 0, 0);
doc.Close();
}
}
}
this.Close();
}
private void Form1_Load_1(object sender, EventArgs e)
{
}
}
}
I expect the output to be a working Pdf Merge/combine to where it has two buttons asking which file to upload for the parent pdf and then another button for child pdf and then something that shows the child pdf merged into the parent pdf.
I am getting a pfd using the older version of itextsharp with this code
string Oldfile = #"C:/test.pdf"; // Gets the Template
(new FileInfo("C:/C:/test.pdf")).Directory.Create(); // Go create this folder if it's not there
string NewFile = "C:/test.pdf";
PdfReader reader = new PdfReader(Oldfile);
iTextSharp.text.Rectangle Size = reader.GetPageSizeWithRotation(1);
Document document = new Document(Size);
// MemoryStream memory_stream = new MemoryStream();
FileStream fs = new FileStream(NewFile, FileMode.Create, FileAccess.Write);
PdfWriter weiter = PdfWriter.GetInstance(document, fs);
document.Open();
PdfContentByte cb = weiter.DirectContent;
PdfImportedPage page = weiter.GetImportedPage(reader, 1);
//PdfImportedPage page2 = weiter.GetImportedPage(reader, 2);
cb.AddTemplate(page, 0, 0);
The problem I am having is when it gets that file it has 2 pages in that pdf but it only gets the 1st page and adds lines and saves the only 1st page of the pdf I want to be able to grab both of them or is there a way to merge them after wards
I bet you need to iterate all pages.
using System;
using System.IO;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace TestAnything
{
class Program
{
static void Main(string[] args)
{
List<string> filesToMerge = new List<string> { #"c:\temp\1.pdf", #"c:\temp\2.pdf" };
FileInfo destinationFile = new FileInfo(#"c:\temp\merge.pdf");
if (File.Exists(destinationFile.FullName))
File.Delete(destinationFile.FullName);
MergeFiles(filesToMerge, destinationFile);
}
public static void MergeFiles(List<string> sourceFiles, FileInfo destinationFile)
{
if (sourceFiles == null || sourceFiles.Count == 0)
throw new ArgumentNullException("blahhh.");
PdfReader reader = new PdfReader(sourceFiles[0]);
Document document = new Document(reader.GetPageSizeWithRotation(1));
PdfCopy writer = new PdfCopy(document, new FileStream(destinationFile.FullName, FileMode.Create));
document.Open();
try
{
foreach (string sourceFile in sourceFiles)
{
reader = new PdfReader(sourceFile);
reader.ConsolidateNamedDestinations();
for (int x = 1; x <= reader.NumberOfPages; x++)
writer.AddPage(writer.GetImportedPage(reader, x));
PRAcroForm form = reader.AcroForm;
if (form != null)
writer.CopyAcroForm(reader);
}
}
finally
{
if (document.IsOpen())
document.Close();
}
}
}
}
I am trying to merge PDF documents and add extra pages to some of them. The merge part is working fine and now I am trying to figure out how to add an extra page by passing a link to the preexisting PDF page. How can I pass a link to a PDF page to targetDoc.AddPage(LINK)?
public static void MergePDFs(string targetPath, DataTable pdfs)
{
try
{
using (PdfSharp.Pdf.PdfDocument targetDoc = new PdfSharp.Pdf.PdfDocument())
{
foreach (DataRow pdf in pdfs.Rows)
{
using (PdfSharp.Pdf.PdfDocument pdfDoc = PdfSharp.Pdf.IO.PdfReader.Open(pdf["link"].ToString(), PdfDocumentOpenMode.Import))
{
for (int i = 0; i < pdfDoc.PageCount; i++)
{
targetDoc.AddPage(pdfDoc.Pages[i]);
}
}
}
targetDoc.Save(targetPath);
}
}
catch(Exception ex)
{
Console.Write(ex);
}
}
Stamping method
using (Stream pdfStream = new FileStream(sourceFileName, FileMode.Open))
{
using (Stream newpdfStream = new FileStream(newFileNameWithPath, FileMode.Create, FileAccess.ReadWrite))
{
iTextSharp.text.pdf.PdfReader pdfReader = new iTextSharp.text.pdf.PdfReader(pdfStream);
PdfStamper pdfStamper = new PdfStamper(pdfReader, newpdfStream);
PdfContentByte pdfContentByte = pdfStamper.GetOverContent(pageNumber);
BaseFont baseFont = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, BaseFont.NOT_EMBEDDED);
pdfContentByte.SetColorFill(BaseColor.RED);
pdfContentByte.SetFontAndSize(baseFont, 12);
pdfContentByte.BeginText();
pdfContentByte.ShowTextAligned(PdfContentByte.ALIGN_CENTER, inputText, Convert.ToInt32(xCoordinate), Convert.ToInt32(yCoordinate), 0);
pdfContentByte.EndText();
pdfStamper.Close();
}
}
To create a new, empty page call AddPage() without parameters.
targetDoc.AddPage();
You might need Clone() to create multiple copies of an existing imported page (also add (PdfPage)):
targetDoc.AddPage((PdfPage)pdfDoc.Pages[i].Clone());
The following code is used for watermarking pdf :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WaterDocument
{
class Program
{
static void Main(string[] args)
{
string FileLocation = "C:\\Users\\Desktop\\Hello.pdf";
// string watermarkedFile = "Watermarked.pdf";
// Creating watermark on a separate layer
// Creating iTextSharp.text.pdf.PdfReader object to read the Existing PDF Document
PdfReader reader1 = new PdfReader(FileLocation);
using (FileStream fs = new FileStream(FileLocation.Replace(".pdf","[temp][file].pdf"), FileMode.Create))
// 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("WatermarkLayer", 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.GetUnderContent(i);
// Tell the cb that the next commands should be "bound" to this new layer
cb.BeginLayer(layer);
cb.SetFontAndSize(BaseFont.CreateFont(
BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 50);
PdfGState gState = new PdfGState();
gState.FillOpacity = 0.25f;
cb.SetGState(gState);
cb.SetColorFill(BaseColor.BLACK);
cb.BeginText();
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Confidential", rect.Width / 2, rect.Height / 2, 45f);
cb.EndText();
// Close the layer
cb.EndLayer();
}
stamper.Close();
}
File.Delete(FileLocation); //error on this line
File.Move(FileLocation.Replace(".pdf", "[temp][file].pdf"), FileLocation);
}
}
}
On this line I am getting the error
File.Delete(FileLocation);
It is throwing me the following error
The process cannot access the file 'C:\Users\Desktop\Hello.pdf' because it is being used by another process.
How can I find the problem in my code?
You're not calling Close on the PdfReader object reader1, add this before the File.Delete call:
reader1.Close()
You should also consider adding a curly brace after this line:
using (FileStream fs = new FileStream(FileLocation.Replace(".pdf","[temp][file].pdf"), FileMode.Create))
There's a risk you add a line directly below that line and your code will stop working as the using statement is terminated directly on the row below.
How can i set an image to a pdf field in existing pdf file?
I'm using the iTextSharp object.
Setting the text field is working fine. No problem in it.
pdfFormFields.SetField("Firstname", "Mujeeb");
Please help.
Remove the Text field and replace it with a Pushbutton field of the same size and position. If you set the Pushbutton to READ_ONLY then it can't be pressed and it will look like a static image. This keeps the image you're trying to add as a field annotation instead of adding it to the page content.
void ConvertTextFieldToImage(string inputFile, string fieldName, string imageFile, string outputFile)
{
using (PdfStamper stamper = new PdfStamper(new PdfReader(inputFile), File.Create(outputFile)))
{
AcroFields.FieldPosition fieldPosition = stamper.AcroFields.GetFieldPositions(fieldName)[0];
PushbuttonField imageField = new PushbuttonField(stamper.Writer, fieldPosition.position, fieldName);
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.Image = iTextSharp.text.Image.GetInstance(imageFile);
imageField.ScaleIcon = PushbuttonField.SCALE_ICON_ALWAYS;
imageField.ProportionalIcon = false;
imageField.Options = BaseField.READ_ONLY;
stamper.AcroFields.RemoveField(fieldName);
stamper.AddAnnotation(imageField.Field, fieldPosition.page);
stamper.Close();
}
}
To the best of my knowledge you can't technically set a standard PDF field as an image (although you might be able to do this with XFA).
The workaround, however, is to just create a standard iTextSharp image and scale it to the form field's dimensions and place it where the field is.
Below is a full working C# 2010 WinForms app targeting iTextSharp 5.1.1.0 that shows how to do this. It starts by creating a very simple PDF with a single form field on it called "firstName". The second part of the program then gets the position and dimensions of that field and places an image there scaled appropriately. See the comments in the code for further details.
using System;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string baseFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "StartFile.pdf");
string secondFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "SecondFile.pdf");
string TestImage = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.jpg");
//Create a very simple PDF with a single form field called "firstName"
using (FileStream fs = new FileStream(baseFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (Document doc = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs))
{
doc.Open();
writer.AddAnnotation(new TextField(writer, new iTextSharp.text.Rectangle(0, 0, 100, 100), "firstName").GetTextField());
doc.Close();
}
}
}
//Create a second file "filling out" the form above
using (FileStream fs = new FileStream(secondFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
using (PdfStamper stamper = new PdfStamper(new PdfReader(baseFile), fs))
{
//GetFieldPositions returns an array of field positions if you are using 5.0 or greater
//This line does a lot and should really be broken up for null-checking
iTextSharp.text.Rectangle rect = stamper.AcroFields.GetFieldPositions("firstName")[0].position;
//Create an image
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(TestImage);
//Scale it
img.ScaleAbsolute(rect.Width, rect.Height);
//Position it
img.SetAbsolutePosition(rect.Left, rect.Bottom);
//Add it to page 1 of the document
stamper.GetOverContent(1).AddImage(img);
stamper.Close();
}
}
this.Close();
}
}
}
This is the answer that works for placing an image in a specific location. `
using (PdfStamper stamper = new PdfStamper(new PdfReader(fromFilePath), File.Create("toFilePath")))
{
AcroFields.FieldPosition fieldPosition = stamper.AcroFields.GetFieldPositions("btn1")[0];
PushbuttonField imageField = new PushbuttonField(stamper.Writer, fieldPosition.position, "btn1Replaced");
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.Image = iTextSharp.text.Image.GetInstance(ImageLocationPath);
imageField.ScaleIcon = PushbuttonField.SCALE_ICON_ALWAYS;
imageField.ProportionalIcon = false;
imageField.Options = BaseField.READ_ONLY;
stamper.AcroFields.RemoveField("btn1");
stamper.AddAnnotation(imageField.Field, fieldPosition.page);
stamper.Close();
}