Show PDF without saving it with itext 7 and vb.net - vb.net

I currently have the following code, which opens a PDF file and has fillable fields, saves it to a path, and then displays it on the screen (Adobe Reader). What I currently want is to open the PDF, pass the data to it and just display it either in a browser or in Adobe Reader without the need to save it to the local disk.
Dim destino = "C:\generacion\ejemplo.pdf"
Dim leerpdf = "C:\plantillas\plantilla.pdf"
Dim reader As PdfReader = New PdfReader(leerpdf)
Dim writer As PdfWriter = New PdfWriter(CStr(destino))
Dim PdfDocument As PdfDocument = New PdfDocument(reader, writer)
Dim form As iText.Forms.PdfAcroForm = PdfAcroForm.GetAcroForm(PdfDocument, False)
form.GetField("dato1").SetValue(nombre)
form.GetField("dato2").SetValue(direccion)
form.GetField("dato3").SetValue(telefono)
form.FlattenFields()
PdfDocument.Close()
Process.Start(destino)

Related

itextsharp stamping form pdf onto other pdf

I'm using itextsharp in vb.net to stamp some backgrounds (ie other single page pdfs) onto another pdf.
So I have a 5 page 'blank' pdf, on which I stamp page 1 with the first page from a file called page1.pdf, then I put the first page of page2.pdf as a background to page 2 etc etc.
It's worked fine so far, but I've come across a problem with stamping a particular pdf onto my 'blank' - the issue appears to be with a file I'll call 'page4.pdf' and it seems likely it's because page4.pdf has been designed as a fillable form.
When I stamp page4 on and open up the blank file in Adobe reader, I get the message:
There was an error processing a page. There was a problem reading this document (18)
Could anyone suggest a way I can stamp a pdf with a form pdf as the source without this issue?
Thanks!
Here's an extract from the code I'm using for stamping (it does other stuff and involves a loop to go through the pages of the pdf, but I've just put the actual stamp bit below to keep things simple):
Dim background As PdfContentByte
Dim page As PdfImportedPage = Nothing
Dim reader As PdfReader = New PdfReader(sourcepdf)
Dim stamper As New itextsharp.text.pdf.PdfStamper(reader, New System.IO.FileStream(outputpdf, System.IO.FileMode.Create))
Dim s_reader As New PdfReader(backfile)
page = stamper.GetImportedPage(s_reader, 1)
background.AddTemplate(page, 0, 0)
stamper.Close()
reader.Close()
s_reader.Close()
Here's the code I've been trying out to convert the form pdf to a 'non-form', which I was hoping would eliminate the stamping problem (no success so far):
Dim pdfReader As PdfReader = New PdfReader(inputpdf)
Dim pdfStamper As itextsharp.text.pdf.PdfStamper = New PdfStamper(pdfReader, New FileStream(outputpdf, FileMode.Create))
pdfStamper.AnnotationFlattening = True
pdfStamper.FreeTextFlattening = True
pdfStamper.FormFlattening = True
pdfStamper.Close()
Issue was nothing to do with the pdf being a form, but a problem that seems to crop up when I repeatedly stamp the same output file. Solution is just to explicity delete the former output file before re-running process.

PDF fill in not merging correctly

We are using an asp.net website with iTextSharp.dll version 5.5.13
We can merge multiple PDF files into one using a stream and it works perfectly. However, when we use a PDF that was created in a "fill-in" function the new PDF file does not correctly merge into the other documents. It merges without the filled in values. However, if I open the filled in PDF that it creates the filled in data displays and prints fine.
I have tried merging the new "filled in" PDF at a later time but it still displays the template file as though the filled in data was missing.
Below code fills in the data
Dim strFileName As String = Path.GetFileNameWithoutExtension(strSourceFile)
Dim strOutPath As String = HttpContext.Current.Server.MapPath("~/Apps/Lifetime/OfficeDocs/Export/")
newFile = strOutPath & strFileName & " " & strRONumber & ".pdf"
If Not File.Exists(newFile) Then
Dim pdfReader As PdfReader = New PdfReader(strSourceFile)
Using pdfStamper As PdfStamper = New PdfStamper(pdfReader, New FileStream(newFile, FileMode.Create))
Dim pdfFormFields As AcroFields = pdfStamper.AcroFields
pdfFormFields.SetField("CUSTOMER NAME", strCustomer)
pdfFormFields.SetField("YR MK MODEL", strVehicle)
pdfFormFields.SetField("RO#", strRONumber)
pdfStamper.FormFlattening = False
pdfStamper.Dispose()
End Using
End If
Then code below here merges multiple PDF files/paths sent to it
Public Shared Sub MergePDFs(ByVal files As List(Of String), ByVal filename As String)
'Gets a list of full path files and merges into one memory stream
'and outputs it to a browser response.
Dim MemStream As New System.IO.MemoryStream
Dim doc As New iTextSharp.text.Document
Dim reader As iTextSharp.text.pdf.PdfReader
Dim numberOfPages As Integer
Dim currentPageNumber As Integer
Dim writer As iTextSharp.text.pdf.PdfWriter = iTextSharp.text.pdf.PdfWriter.GetInstance(doc, MemStream)
doc.Open()
Dim cb As iTextSharp.text.pdf.PdfContentByte = writer.DirectContent
Dim page As iTextSharp.text.pdf.PdfImportedPage
Dim strError As String = ""
For Each strfile As String In files
reader = New iTextSharp.text.pdf.PdfReader(strfile)
numberOfPages = reader.NumberOfPages
currentPageNumber = 0
Do While (currentPageNumber < numberOfPages)
currentPageNumber += 1
doc.SetPageSize(reader.GetPageSizeWithRotation(currentPageNumber))
doc.NewPage()
page = writer.GetImportedPage(reader, currentPageNumber)
cb.AddTemplate(page, 0, 0)
Loop
Next
doc.Close()
doc.Dispose()
If MemStream Is Nothing Then
HttpContext.Current.Response.Write("No Data is available for output")
Else
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.ContentType = "application/pdf"
HttpContext.Current.Response.AppendHeader("Content-Disposition", "inline; filename=" + filename)
HttpContext.Current.Response.BinaryWrite(MemStream.ToArray)
HttpContext.Current.Response.OutputStream.Flush()
HttpContext.Current.Response.OutputStream.Close()
HttpContext.Current.Response.OutputStream.Dispose()
MemStream.Close()
MemStream.Dispose()
End If
End Sub
I expect the "filled in" PDF in the list of files to retain the filled in data but it does not. Even if I try to merge the filled in file later it still comes up missing the filled in data. If I print the filled in file it looks perfect.
PdfWriter.GetImportedPage only returns you a copy of the page contents. This does not include any annotations, in particular not the widget annotations of form fields on the page at hand.
To also copy the annotations of the source pages, use the iText PdfCopy class instead. This class is designed to copy pages including all annotations. Furthermore, it includes methods to copy all pages of a source document in one step.
You have to tell the PdfCopy object to merge fields, otherwise the document-wide form structure won't be built.
As an aside, your code creates many PdfReader objects but does not close them. That may increase your memory requirements substantially.
Thus:
Public Shared Sub MergePDFsImproved(ByVal files As List(Of String), ByVal filename As String)
Using mem As New MemoryStream()
Dim readers As New List(Of PdfReader)
Using doc As New Document
Dim copy As New PdfCopy(doc, mem)
copy.SetMergeFields()
doc.Open()
For Each strfile As String In files
Dim reader As New PdfReader(strfile)
copy.AddDocument(reader)
readers.Add(reader)
Next
End Using
For Each reader As PdfReader In readers
reader.Close()
Next
HttpContext.Current.Response.Clear()
HttpContext.Current.Response.ContentType = "application/pdf"
HttpContext.Current.Response.AppendHeader("Content-Disposition", "inline; filename=" + filename)
HttpContext.Current.Response.BinaryWrite(mem.ToArray)
HttpContext.Current.Response.OutputStream.Flush()
HttpContext.Current.Response.OutputStream.Close()
HttpContext.Current.Response.OutputStream.Dispose()
End Using
End Sub
Actually I'm not sure whether it is a good idea to Close and Dispose the response output stream here, that shouldn't be the responsibility of a PDF merging method.
This is a related answer for the Java version of iText; you may want to read it for additional information. Unfortunately many links in that answer meanwhile are dead.

How to open PDF in PDFsharp where PDF is added as a resource to the project

I'm getting an error in the path because it's retrieving System.Byte[] in it. How can I access the PDF which is added in my resources?
Code:
PdfDocument = PdfSharp.Pdf.IO.PdfReader.Open(My.Resources.CANEezz_Individual.ToString, PdfDocumentOpenMode.Modify)
Dim font9 As XFont = New XFont("Arial", 8)
Dim page As PdfPage = PdfDocument.Pages(0)
Dim graph As XGraphics = XGraphics.FromPdfPage(page)
graph.DrawString("Bank Passboook", font9, XBrushes.Black, 518, 343)
Dim pdfFilename As String = "something.pdf"
PdfDocument.Save(pdfFilename)
Process.Start(pdfFilename)
Pass the byte[] to the constructor of MemoryStream and pass that memory stream to the PdfReader.Open() method.

Add a table to a PDF template using iTextSharp and VB.net

I've been stuck on this far longer than I care to admit. I'm trying to use iTextSharp to build a table that I can then insert into a PDF template (which is really just a PDF with a header and an acrofield that needs to be populated). I've currently got code that follows the same outline below:
Dim doc As New Document
Dim reader As PdfReader
Dim stamper As PdfStamper
Dim filestream As FileStream
Dim tempfile As String = My.Computer.FileSystem.GetTempFileName
filestream = New FileStream(tempfile, FileMode.Create)
PdfWriter.GetInstance(doc, filestream)
doc.Open()
generateTableForPdf(listOfData, numColumns, doc)
doc.Close()
reader = New PdfReader(pdfTemplatePath)
stamper = New PdfStamper(reader, filestream)
stamper.AcroFields.SetField("topmostSubform[0].Page1[0].headerField", "some text to go in the field")
The pdfTemplatePath is a private const that has the template's file path that I am trying to use and generateTableForPdf simply creates a dynamically sized table and puts it in doc (doc is passed by ref). I know the table is created because it displays when the page loads, however, the header in the template doesn't appear. I've looked around and found a couple of examples that use byte streams or memory streams, but my attempts at implementing those methods have failed more dramatically. Any help or guidance in better understanding how to go about this is greatly appreciated.

Including CSS file in pdf using itextsharp

I am making a pdf file using iTextSharp.
However, the external CSS that is linked in the source HTML does not shown in the PDF.
How can I include the external css file so iTextSharp renders correctly?
Dim doc As Document = New Document
PdfWriter.GetInstance(doc, New FileStream(Request.PhysicalApplicationPath + _
"\ListingDetails.pdf", FileMode.Create))
Dim content As String = File.ReadAllText(Server.MapPath("~/PDFPage.aspx"))
doc.Open()
Dim parsedHtmlElements = HTMLWorker.ParseToList(New StringReader(content), Nothing)
For Each htmlElement As Object In parsedHtmlElements
doc.Add(TryCast(htmlElement, IElement))
Next
doc.Close()