I have created a console app that uses a memory stream to create a pdf file, to encrypt it and the add it as an attachment.
using (Stream output = new MemoryStream())
{
Document document = new Document();
using (var stream = new MemoryStream())
{
PdfWriter.GetInstance(document, stream);
document.Open();
var image = Image.GetInstance(renderedPayslip);
image.ScaleToFit(600, 820);
image.SetAbsolutePosition(2, 10);
document.Add(image);
using (var newTestStream = new MemoryStream())
{
stream.CopyTo(newTestStream);
newTestStream.Position = 0;
document.Close();
PdfReader reader = new PdfReader(stream.ToArray());
PdfStamper stamper = new PdfStamper(reader, newTestStream);
PdfEncryptor.Encrypt(reader, newTestStream, true, "secret", "secret", PdfWriter.ALLOW_PRINTING);
reader.Close();
}
//return sm.ToArray();
}
The problem is that it keeps on giving the message PDF Header not found.
Can some one help, please?
Related
Help please. I'm trying to get a "deferred" digital signature and embed it in a PDF document. On the server (.net core 3.1) I create a test pdf and add an empty container for the signature. To do this, I use the iTextSharp package (version 5.5.13.3):
public static byte[] GetPdfBytesToSign(byte[] unsignedPdf, string signatureFieldName)
{
//unsignedPdf - source PDF
using (PdfReader reader = new PdfReader(unsignedPdf))
{
//looking for existing signatures
int existingSignaturesNumber = reader.AcroFields.GetSignatureNames().Count;
using (MemoryStream tempPdf = new MemoryStream())
{
//add an empty container for a new signature
using (PdfStamper st = PdfStamper.CreateSignature(reader, tempPdf, '\0', null, true))
{
PdfSignatureAppearance appearance = st.SignatureAppearance;
appearance.SetVisibleSignature(new Rectangle(205, 700, 390, 800), reader.NumberOfPages,
//set the name of the field, it will be needed later to insert a signature
$"{signatureFieldName}{existingSignaturesNumber + 1}");
ExternalBlankSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
MakeSignature.SignExternalContainer(appearance, external, BufferSize);
//get a stream that contains the sequence we want to sign
using (Stream contentStream = appearance.GetRangeStream())
{
MemoryStream memoryStream = new MemoryStream();
contentStream.CopyTo(memoryStream);
byte[] bytesToSign = memoryStream.ToArray();
return bytesToSign;
}
}
}
}
}
And here is the problem!!! For some reason, iText can't read the PDF it created with an empty signature container (to embed the received signature from the client).
public static byte[] GetSignedPdf(byte[] unsignedPdfWithContainer, byte[] signature)
{
using var pdfReader = new PdfReader(unsignedPdfWithContainer);//<--throwing an exception here
using var output = new MemoryStream();
var external = new MyExternalSignatureContainer(signature);
MakeSignature.SignDeferred(pdfReader, SignatureFieldName, output, external);
return output.ToArray();
}
I am getting the following exception:
iTextSharp.text.exceptions.InvalidPdfException: "Unexpected '>>' at file pointer 1432"
Test(source) pdf is created like this:
public static byte[] CreatePdf()
{
using (MemoryStream ms = new MemoryStream())
{
Document document = new Document(PageSize.A4, 25, 25, 30, 30);
PdfWriter writer = PdfWriter.GetInstance(document, ms);
document.Open();
document.Add(new Paragraph("Hello World!"));
document.Close();
writer.Close();
return ms.ToArray();
}
}
I have a pdf document (created by iTextSharp - free version 4.1.6) and I want to add text / table at the top of this pdf. I have tried to create two memory streams from iTextSharp Documents and combine them to one, see my code below. But the new PDF file cannot be opened. Any ideas what I am doing wrong? Any other ideas to add text / table at the top of an existing PDF? Thanks in advance!
public void CreateTestPDF(string _pathOfOriginalPDF, string _pathOfModifiedPDF)
{
string oldFile = _pathOfOriginalPDF;
string newFile = pathOfModifiedPDF;
byte[] bytesHeader;
byte[] bytesBody;
byte[] bytesCombined;
using (MemoryStream ms = new MemoryStream())
{
Document doc = new Document();
doc.Open();
doc.Add(new Paragraph("This is my header paragraph"));
if (doc.IsOpen())
{
doc.Close();
}
bytesHeader = ms.ToArray();
}
using (MemoryStream ms = new MemoryStream())
{
Document doc = new Document();
//doc.Open();
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(oldFile, FileMode.Create));
if (doc.IsOpen())
{
doc.Close();
}
bytesBody = ms.ToArray();
}
IEnumerable<byte> iCombined = bytesHeader.Concat(bytesBody);
bytesCombined = iCombined.ToArray();
string testFile = _pathOfModifiedPDF;
using (FileStream fs = File.Create(testFile))
{
fs.Write(bytesBody, 0, (int)bytesBody.Length);
}
}
I have a controller with the get method and when accessing this controller I need to enter some data from the existing pdf file (template) to return this file. When I return this pdf file to the request, I get an error:
ObjectDisposedException: Cannot access a closed Stream
PdfReader reader = new PdfReader(templateFilePath);
Rectangle rect = reader.GetPageSize(1);
var fs = new MemoryStream();
using (PdfStamper stamper = new PdfStamper(reader, fs))
{
// modify the pdf content
PdfContentByte cb = stamper.GetOverContent(1);
cb.SetColorStroke(iTextSharp.text.BaseColor.GREEN);
cb.SetLineWidth(5f);
cb.Circle(rect.GetLeft(1) + 30, rect.GetBottom(1) + 30, 20f);
cb.Stroke();
}
reader.Close();
fs.Position = 0;
return File(fs, "application/pdf", "newFile");
var reader = new PdfReader(templatePath);
var ms = new MemoryStream();
var pageSize = reader.GetPageSize(1);
byte[] bytes;
using (var stamper = new PdfStamper(reader, ms))
{
var canvas = stamper.GetOverContent(1);
var bf = BaseFont.CreateFont(fontPath, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
//Date
canvas.BeginText();
canvas.SetFontAndSize(bf, 10);
canvas.ShowTextAligned(PdfContentByte.ALIGN_RIGHT,
$"10/30/2018",
pageSize.GetRight(Utilities.MillimetersToPoints(26)),
pageSize.GetTop(Utilities.MillimetersToPoints(20.
canvas.EndText();
stamper.Close();
bytes = ms.ToArray();
}
return File(bytes, "application/pdf", "payment.pdf");
I am using Visual Studio 2013, c# Windows Application, iTextSharp:
I can easily create/save a pdf file and write to it but is there a way to just use a pdf file and write to it without first saving it? I don't want to be creating a temporary pdf file every-time someone runs a report. Thanks in Advance !!
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10,10,42,35);
PdfWriter wri = PdfWriter.GetInstance(doc, new FileStream("Test.pdf",
FileMode.Create));
doc.Open();
\\\\ Then I do a bunch of stuff, then do a close
doc.Close();
You can use a MemoryMappedFile and write to it and it is not disk based.
using (MemoryMappedFile mmf = MemoryMappedFile.CreateNew("INMEMORYPDF.pdf", 1000000))
{
PDFPageMargins margins = new PDFPageMargins(10, 10, 10, 10);
var document = new Document((_pageWidth > 540) ? PageSize.A4.Rotate() : PageSize.A4, margins.Left, margins.Right, margins.Top, margins.Bottom);
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
PdfWriter.GetInstance(document, stream);
document.Open();
//MODIFY DOCUMENT
document.Close();
}
byte[] content;
using (MemoryMappedViewStream stream = mmf.CreateViewStream())
{
BinaryReader rdr = new BinaryReader(stream);
content = new byte[mmf.CreateViewStream().Length];
rdr.Read(content, 0, (int)mmf.CreateViewStream().Length);
}
return content;
}
am using the below code for replace image and text on pdf, its is good working on the image replace part, but i dont know the how can write the text replace in same code.
private void AddAnImage()
{
string qrfile = qrcode();
using (var inputPdfStream = new FileStream(Server.MapPath("PDF/input.pdf"), FileMode.Open))
using (var inputImageStream = new FileStream(qrfile, FileMode.Open))
using (var outputPdfStream = new FileStream(Server.MapPath("PDF/output.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(50, 75);
pdfContentByte.AddImage(image);
PdfContentByte canvas = stamper.GetOverContent(2);
ColumnText.ShowTextAligned(canvas, Element.ALIGN_LEFT, new Phrase(DateTime.Now.ToShortDateString()), 0, 0, 0);
stamper.Close();
}
}