Itext PDF Image - c#

I am trying to add a signature to the 2nd page of a PDF Form. The PDF was created outside of IText, but it has fields that were populated using IText in C#/MVC. That part works fine.
The issue is getting the signature image to the 2nd page. I can get the image onto the 1st page and position it, but cannot get it to the 2nd page.
I have tried to using the var PdfDocument class' GetPage(x) method without any luck. I have also tried to use GetLastPage(). No luck.
I tried the above approach before flattening the fields and after but no luck.
PdfReader reader = new PdfReader(fileSource);
System.IO.MemoryStream m = new System.IO.MemoryStream();
PdfWriter writer = new PdfWriter(m);
PdfDocument pdf = new PdfDocument(reader, writer);
Document document = new Document(pdf);
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true);
String imageFile = "C:/Temp/signature.png";
ImageData data = ImageDataFactory.Create(imageFile);
Image img = new Image(data);
img.SetFixedPosition(50, 50);
pdf.GetPage(2);
document.Add(img);
form.FlattenFields();
document.Close();
pdf.Close();
pdfBytes = m.ToArray();
return new FileContentResult(pdfBytes, "application/pdf");
Any help would be appreciated.

Related

How to insert barcode into PDF created by IText7 HtmlConverter.ConvertToDocument method

I'm using IText 7 to convert my HTML file into PDF and auto download the file when users click a button.
Currently I'm planning to insert a barcode using IText7 into the PDF file, however I encountered some error. Btw, it works fine without the 'barcode code'.
This is the error : 'iText.Kernel.PdfException: 'Pdf indirect object belongs to other PDF document. Copy object to current pdf document.''
How can I add a barcode at the end of my pdf file?
public MemoryStream GetCovidFormPdfByAccessionNumber(string htmlFile, string accessionNumber)
{
var workStream = new MemoryStream();
using (var pdfWriter = new PdfWriter(workStream))
{
pdfWriter.SetCloseStream(false);
var pdfDoc = new PdfDocument(pdfWriter);
using (var document = HtmlConverter.ConvertToDocument(htmlFile, pdfWriter))
{
document.Add(CreateBarcode(accessionNumber, pdfDoc));
}
}
workStream.Position = 0;
return workStream;
}
private static Image CreateBarcode(string code, PdfDocument pdfDoc)
{
Barcode39 barcode = new Barcode39(pdfDoc);
barcode.SetCode(code);
//Create barcode object to put it to the cell as image
PdfFormXObject barcodeObject = barcode.CreateFormXObject(ColorConstants.BLACK, ColorConstants.BLACK, pdfDoc);
var image = new Image(barcodeObject);
image.SetWidth(250);
return image;
}

Can I attach an image to a signed pdf document using itext 7?

I have attached an image into a signed pdf document using itext7, but the signature became invalid. Is there any solution for this
string source = #"D:\SampleProjects\itext\file\test.pdf";
string target = #"D:\SampleProjects\itext\file\tests.pdf";
string img = #"D:\SampleProjects\itext\file\sign_valid.png";
PdfDocument pdfDocument = new PdfDocument(new PdfReader(source), new PdfWriter(target));
// Document to add layout elements: paragraphs, images etc
Document document = new Document(pdfDocument);
var noofpages = pdfDocument.GetNumberOfPages();
// Load image from disk
ImageData imageData = ImageDataFactory.Create(img);
// Create layout image object and provide parameters. Page number = 1
Image image = new Image(imageData).ScaleAbsolute(100, 100).SetFixedPosition(1, 25, 25);
document.Add(image);
document.Close();
It's a feature that the signature becomes invalid when the document is changed.
So I would say the answer to your question is no.
I recommend you attach the image before the document is signed.

How to reduce content of exists PDF page in C#?

I convert HTML to PDF, but when i look PDF it has 2 page because content is a bit longer for one page. But i want to fit content to one page.
I tried this but it doesn't help me.
PdfDocument pdf = new PdfDocument();
pdf.LoadFromFile(pdfPath);
PdfDocument newPdf = new PdfDocument();
foreach (PdfPageBase page in pdf.Pages)
{
PdfPageBase newPage = newPdf.Pages.Add(PdfPageSize.A1, new Spire.Pdf.Graphics.PdfMargins(0));
PdfTextLayout loLayout = new PdfTextLayout();
loLayout.Layout = PdfLayoutType.OnePage;
page.CreateTemplate().Draw(newPage, new PointF(0, 0), loLayout);
}
newPdf.SaveToFile(newPdfPath);

Printing InnerHtml to Printer with formating intact in vb.net/C#

In vb.net I need to print the contents showing in a browser control to printer.
I have used Gecko web-browser control in winform application and there is no direct way to print the page's contents.
Either way to print direct using InnerHtml or converting that html to pdf and then printing the pdf document.
currently I am using a third party library `ItextSharpe' but it gives errors.
public byte[] GetPDF(string pHTML) {
byte[] bPDF = null;
MemoryStream ms = new MemoryStream();
TextReader txtReader = new StringReader(pHTML);
// 1: create object of a itextsharp document class
Document doc = new Document(PageSize.A4, 25, 25, 25, 25);
// 2: we create a itextsharp pdfwriter that listens to the document and directs a XML-stream to a file
PdfWriter oPdfWriter = PdfWriter.GetInstance(doc, ms);
// 3: we create a worker parse the document
HTMLWorker htmlWorker = new HTMLWorker(doc);
// 4: we open document and start the worker on the document
doc.Open();
htmlWorker.StartDocument();
// 5: parse the html into the document
htmlWorker.Parse(txtReader);
// 6: close the document and the worker
htmlWorker.EndDocument();
htmlWorker.Close();
doc.Close();
bPDF = ms.ToArray();
return bPDF;
}
Byte[] bytes;
bytes = GetPDF(browse.Document.Body.InnerHtml);
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
System.IO.File.WriteAllBytes(testFile, bytes);
but throws errors while parsing.
Unable to cast object of type 'iTextSharp.text.html.simpleparser.CellWrapper' to type 'iTextSharp.text.Paragraph'.
I have seen different examples over web but this is totally different, the examples or duplicate answer is about to export panels or grids but this is dynamic HTML and i need to convert it to PDF or print directly the client area.

PDF generated with iTextSharp always prompts to save changes when closing. And has missing pages when viewed with non-Acrobat PDF readers

I've recently used iTextSharp to create a PDF by importing the 20 pages from an existing PDF and then adding a dynamically generated link to the bottom of the last page. It works fine... kind of. Viewing the generated PDF in Acrobat Reader on a windows PC displays everything as expected although when closing the document it always asks "Do you want to save changes?". Viewing the generated PDF on a Surface Pro with PDF Reader displays the document without the first and last pages. Apparently on a mobile device using Polaris Office the first and last pages are also missing.
I'm wondering if when the new PDF is generated it's not getting closed off quite properly and that's why it asks "Do you want to save changes?" when closing it. And maybe that's also why it doesn't display correctly in some PDF reader apps.
Here's the code:
using (var reader = new PdfReader(HostingEnvironment.MapPath("~/app/pdf/OriginalDoc.pdf")))
{
using (
var fileStream =
new FileStream(
HostingEnvironment.MapPath("~/documents/attachments/DocWithLink_" + id + ".pdf"),
FileMode.Create, FileAccess.Write))
{
var document = new Document(reader.GetPageSizeWithRotation(1));
var writer = PdfWriter.GetInstance(document, fileStream);
using (PdfStamper stamper = new PdfStamper(reader, fileStream))
{
var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252,
BaseFont.NOT_EMBEDDED);
Font linkFont = FontFactory.GetFont("Arial", 12, Font.UNDERLINE, BaseColor.BLUE);
document.Open();
for (var i = 1; i <= reader.NumberOfPages; i++)
{
document.NewPage();
var importedPage = writer.GetImportedPage(reader, i);
// Copy page of original document to new document.
var contentByte = writer.DirectContent;
contentByte.AddTemplate(importedPage, 0, 0);
if (i == reader.NumberOfPages) // It's the last page so add link.
{
PdfContentByte cb = stamper.GetOverContent(i);
//Create a ColumnText object
var ct = new ColumnText(cb);
//Set the rectangle to write to
ct.SetSimpleColumn(100, 30, 500, 90, 0, PdfContentByte.ALIGN_LEFT);
//Add some text and make it blue so that it looks like a hyperlink
var c = new Chunk("Click here!", linkFont);
var congrats = new Paragraph("Congratulations on reading the eBook! ");
congrats.Alignment = PdfContentByte.ALIGN_LEFT;
c.SetAnchor("http://www.domain.com/pdf/response/" + encryptedId);
//Add the chunk to the ColumnText
congrats.Add(c);
ct.AddElement(congrats);
//Tell the system to process the above commands
ct.Go();
}
}
}
}
}
I've looked at these posts with similar issues but none seem to quite provide the answer I need:
iTextSharp-generated PDFs cause save dialog when closing
Using iTextSharp to write data to PDF works great, but Acrobat Reader asks 'Do you want to save changes' when closing file
(Or they refer to memory streams instead of writing to disk etc)
My question is, how do I modify the above so that when closing the generated PDF in Acrobat Reader there's no "Do you want to save changes?" prompt. The answer to that may solve the problems with missing pages on Surface Pro etc but if you know anything else about what might be causing that I'd like to hear about it.
Any suggestions would be very welcome! Thanks!
At first glance (and without much coffee yet) it appears that you're using a PdfReader in three different contexts, as a source to a PdfStamper, as a source for Document and as for a source for importing. So you are essentially importing a document into itself that you're also writing to.
To give you a quick overview, the following code will essentially clone the contents of source.pdf into dest.pdf:
using (var reader = new PdfReader("source.pdf")){
using (var fileStream = new FileStream("dest.pdf", FileMode.Create, FileAccess.Write)){
using (PdfStamper stamper = new PdfStamper(reader, fileStream)){
}
}
}
Since that does all of the cloning for you you don't need to import pages or anything.
Then, if the only thing that you want to do is add some text to the last page, you can just use the above and ask the PdfStamper for a PdfContentByte using GetOverContent() and telling it what page number you're interested. Then you can just use the rest of your ColumnText logic.
using (var reader = new PdfReader("Source.Pdf")) {
using (var fileStream = new FileStream("Dest.Pdf"), FileMode.Create, FileAccess.Write) {
using (PdfStamper stamper = new PdfStamper(reader, fileStream)) {
//Get a PdfContentByte object
var cb = stamper.GetOverContent(reader.NumberOfPages);
//Create a ColumnText object
var ct = new ColumnText(cb);
//Set the rectangle to write to
ct.SetSimpleColumn(100, 30, 500, 90, 0, PdfContentByte.ALIGN_LEFT);
//Add some text and make it blue so that it looks like a hyperlink
var c = new Chunk("Click here!", linkFont);
var congrats = new Paragraph("Congratulations on reading the eBook! ");
congrats.Alignment = PdfContentByte.ALIGN_LEFT;
c.SetAnchor("http://www.domain.com/pdf/response/" + encryptedId);
//Add the chunk to the ColumnText
congrats.Add(c);
ct.AddElement(congrats);
//Tell the system to process the above commands
ct.Go();
}
}
}

Categories