wants to just add a text to an existing pdf using itextsharp
.and so far I have done.my code =>
public FileStreamResult DownloadCertificate(string UserId)
{
//get user info using UserId from database
//UserDetail UserDetail = db.UserDetails.Where(x => x.UserId == UserId).FirstOrDefault();
string oldFile = Server.MapPath("~/Content/img/tsms/Certificate/Certificate-of-Completion-Award-Template-Blue.pdf");
string newFile = Server.MapPath("~/Content/img/tsms/Certificate/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();
// write the text in the pdf content
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();
return new FileStreamResult(fs, "application/pdf");
}
the problem is when I am trying to access the method browser showing me error like below=>
I don't know why it's giving me this kind of error.
I tried to find the solution. and I find....
FileStream "cannot access closed file"
but that is not enough for me.
and I also try to change some lines in my code. below =>
// close the streams and voilá the file should be changed :)
document.Close();
//fs.Close();
//writer.Close();
//reader.Close();
return new FileStreamResult(fs, "application/pdf");
but that change also doesn't help me. what I have done wrong in my code.(also how can I provide a download mode to the user.)
It looks to me like it's a problem with the FileStream. My educated guess would be the call to document.Close(); is also closing the FileStream.
You could try NOT reusing the same stream but rather opening up a new read-only one (which will also reset its position, by the way) and use that for the result.
Related
I am new to itextSharp. What I am doing is just editing the old file and instead of saving the new file on the server I just want it to download at the time. but unfortunately after editing the file and being downloaded, file display a message cannot open the file. It may be corrupted.
Here is my code.
public FileStreamResult export( int ? id)
{
string pathin = Server.MapPath(Url.Content("~/PDF/input.pdf"));
PdfReader reader = new PdfReader(pathin);
iTextSharp.text.Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
// open the writer
//FileStream ms = new FileStream(pathout, FileMode.Create, FileAccess.Write);
var ms = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(document, ms);
writer.CloseStream = false;
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, 18f);
// write the text in the pdf content
cb.BeginText();
string text = "this is text";
// put the alignment and coordinates here
cb.ShowTextAligned(1, text, 500, 500, 0);
cb.EndText();
cb.BeginText();
text = "this is my post";
// put the alignment and coordinates here
cb.ShowTextAligned(1, text, 600, 400, 0);
cb.EndText();
// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
ms.Position = 0;
document.Close();
//ms.Close();
writer.Close();
reader.Close();
return File(ms, "application/pdf","test.pdf");
}
Any help will be really appreciated. :)
You change the position of the memory stream before closing the document:
ms.Position = 0;
document.Close();
As the trailer of the pdf in the result stream is written during the closing of the document, your change of stream position causes the pdf trailer to be written over the pdf header and the stream position thereafter to not be at the start.
Instead first close the document and the reader (the writer implicitly is closed by closing the document) and reset the stream position thereafter:
document.Close();
reader.Close();
ms.Position = 0;
return File(ms, "application/pdf","test.pdf");
I have a method that gets a pdf and adds's lines in that pdf and then creates a new pdf and saves it in a path that's given to it. Now I don't want to save that new file in a path instead I want to convert it into bytes and send in Emails how can I do that I tried a couple of methods but it all ways look for path says no path found here is the code.
protected void CreatePDF()
{
string Oldfile = #"C:\BlankPDFt.pdf"; // Gets the Template / The actualy agreement Letter
// (new FileInfo("C:/Documents/Docs.pdf")).Directory.Create(); // Go create this folder if it's not there
string NewFile = "C:/Documents/Docs.pdf";
PdfReader reader = new PdfReader(Oldfile);
iTextSharp.text.Rectangle Size = reader.GetPageSizeWithRotation(1);
Document document = new Document(Size);
FileStream fs = new FileStream(NewFile , FileMode.Create, FileAccess.Write); // This is where it all ways look for new file path
i dont want it to save instead convert to bytes but wont work.
PdfWriter weiter = PdfWriter.GetInstance(document, fs);
document.Open();
PdfContentByte cb = weiter.DirectContent;
PdfImportedPage page = weiter.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.BLACK);
cb.SetFontAndSize(bf, 12);
cb.BeginText();
// string Signatur = "Some texts"; // adds this text to that pdf
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Here", 335, 90, 0); // Insert the signature
cb.EndText();
}
The PdfWriter.GetInstance() method accepts an InputStream as its second argument. Instead of passing a FileStream you should pass it a MemoryStream.
MemoryStream memory_stream = new MemoryStream();
PdfWriter.GetInstance(document, memory_stream );
...
document.Close();
byte[] pdf_bytes = memory_stream.ToArray();
I can add a text to an existing pdf as it is explained in the url below.
But the texts stay below the images in the pdf when I add them. How can I fix this problem?
ITextSharp insert text to an existing pdf
Edit :
public void createFromPDF(string mapPath)
{
string oldFile = mapPath.Replace("Home", "") + "Content\\Uploads\\fiyat-listesi.pdf";// "oldFile.pdf";
string newFile = mapPath.Replace("Home", "") + "Content\\Uploads\\new.pdf";//"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(Color.RED);
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);
document.NewPage();
Paragraph p = new Paragraph("aaaaaaaaaaaaaaaaaa", new Font(bf));
document.Add(p);
PdfImportedPage page2 = writer.GetImportedPage(reader, 2);
cb.AddTemplate(page2, 0, 0);
document.NewPage();
Paragraph pwe = new Paragraph("aaaaaaaaaaaaaaaaaa", new Font(bf));
document.Add(p);
cb.EndLayer();
PdfImportedPage page3 = writer.GetImportedPage(reader, 3);
cb.AddTemplate(page3, 0, 0);
// close the streams and voilá the file should be changed :)
document.Close();
fs.Close();
writer.Close();
reader.Close();
}
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 and PdfWriter. That proves thaf you didn't read the documentation. You should use PdfStamper 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?
I want to fill draft form with itexsharp on PDF. But When I run code It doesn’t work. The data hides under PDF Format. You can see below the detail code. How can I fix it?
I think Squares which in the picture might be image format.
string oldFile ="~\Document\oldFile.pdf";
string newFile ="~\Document\newFile.pdf";
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();
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.DARK_GRAY); cb.SetFontAndSize(bf, 8);
cb.BeginText();
string text = TextBox1.Text;
cb.ShowTextAligned(1, text, 350, 710, 0); // or cb.SetTextMatrix(1, text, 350, 710, 0);
cb.EndText();
cb.BeginText();
text = TextBox1.Text;
cb.ShowTextAligned(2, text, 520, 640, 0);
cb.EndText();
cb.BeginText();
text = "Signature";
cb.ShowTextAligned(3, text, 100, 200, 0);
cb.EndText();
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
document.Close();
fs.Close();
writer.Close();
reader.Close();
If this is editable form (the one which you can fill with Adobe Reader) then you should look at PdfStamper and AcroFields
Here is a good article about it http://www.codeproject.com/Articles/23112/Fill-in-PDF-Form-Fields-using-the-Open-Source-iTex
Try to put
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
before adding your own text.
You write the text on the page, then you overlap your original pdf.
This article How to bring added images using iTextSharp in C# to the forefront suggests that z-order in PDF is determined by the order of objects added to the content. So import the source page first, then draw your texts, that should solve the problem.
The squares might as well be actual form fields. If that is the case, you can open the PDF with Acrobat to find out their names (or enumerate them through iTextSharp coding if you don't have Acrobat available) and use the PdfStamper class to actually "fill them in".
I want to convert an image to PDF and add a watermark to it. I used iTextSharp to convert it. I successfully converted the image file to pdf but I'm not able to add watermark to it without creating another pdf file.
The code below creates a PDF file and also adds custom attributes,
function watermarkpdf is used to add watermark and pdfname is given as the arguement
foreach (string filenm in Images)
using (var imageStream = new FileStream(filenm, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
doc.NewPage();
iTextSharp.text.Image jpeg = iTextSharp.text.Image.GetInstance(filenm);
float width = doc.PageSize.Width;
float height = doc.PageSize.Height;
jpeg.ScaleToFit(width,height);
doc.Add(jpeg);
}
doc.AddHeader("name", "vijay");
watermarkpdf(pdfname);
The watermarkpdf function is given below.
PdfReader pdfReader = new PdfReader(txtpath.Text+"\\pdf\\" + pdfname);
FileStream stream = new FileStream(txtpath.Text + pdfname,FileMode.Open);
PdfStamper pdfStamper = new PdfStamper(pdfReader, stream);
for (int pageIndex = 1; pageIndex <= pdfReader.NumberOfPages; pageIndex++)
{
Rectangle pageRectangle = pdfReader.GetPageSizeWithRotation(pageIndex);
PdfContentByte pdfData = pdfStamper.GetUnderContent(pageIndex);
pdfData.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 40);
PdfGState graphicsState = new PdfGState();
graphicsState.FillOpacity = 0.4F;
pdfData.SetGState(graphicsState);
pdfData.SetColorFill(BaseColor.BLUE);
pdfData.BeginText();
pdfData.ShowTextAligned(Element.ALIGN_CENTER, "SRO-Kottarakkara", pageRectangle.Width / 2, pageRectangle.Height / 2, 45);
pdfData.EndText();
}
pdfStamper.Close();
stream.Close();
iTextSharp doesn't support "in-place editing" of files, only reading existing files and creating new files. The problem is that it would have to write to something that is being written to which could be very problematic.
However, instead of using a file you can create your image in a MemoryStream, grab the bytes from that and pipe that to the PdfReader, all with minimal changes to your code. All of the PDF writing functions that take files actually work with the abstract Stream class and which MemoryStream inherits from so they can be used interchangeably. Below is some basic code that should show you what I'm talking about. I don't have an IDE currently so there might be a typo or two but for the most part it should work.
//Image part
//We will dump the bytes from the memory stream to the variable below later
byte[] bytes;
using (MemoryStream ms = new MemoryStream()){
Document doc = new Document(PageSize.LETTER);
PdfWriter writer = PdfWriter.GetInstance(doc, ms);
doc.Open();
//foreach (string filenm in Images)
//...
doc.Close();
//Dump the bytes, make sure to use ToArray() and not GetBuffer()
bytes = ms.ToArray();
}
//Watermark part
//Read from our bytes
PdfReader pdfReader = new PdfReader(bytes);
FileStream stream = new FileStream(txtpath.Text + pdfname,FileMode.Open);
//...