iText 7 .NET - 'System.NullReferenceException' when flattening a form - vb.net

In order to duplicate a form in a PDF, I'm doing the following (used this code as reference):
Dim pdfDocumentR As PdfDocument
Dim writer As PdfWriter = New PdfWriter(DEST)
writer.SetSmartMode(True)
Dim pdfDocumentW As New PdfDocument(writer)
Dim tmp As ByteArrayOutputStream
Dim form As PdfAcroForm
Dim fields As IDictionary(Of String, PdfFormField)
Dim tf As PdfFormField
For Each documento As Documento In documentos
tmp = New ByteArrayOutputStream()
pdfDocumentR = New PdfDocument(New PdfReader(SRC), New PdfWriter(tmp))
form = PdfAcroForm.GetAcroForm(pdfDocumentR, False)
fields = form.GetFormFields()
documento.campos.remove("templateID")
Dim keys As Dictionary(Of String, String).KeyCollection = documento.campos.Keys
For Each key As String In keys
Dim value As String
documento.campos.TryGetValue(key, value)
fields.TryGetValue(key, tf)
tf.SetValue(value)
Next
form.FlattenFields()
pdfDocumentR.Close()
pdfDocumentR = New PdfDocument(New PdfReader(New MemoryStream(tmp.GetBuffer())))
pdfDocumentR.CopyPagesTo(1, pdfDocumentR.GetNumberOfPages(), pdfDocumentW, New PdfPageFormCopier())
pdfDocumentR.Close()
Next
pdfDocumentW.Close()
I'm getting 'System.NullReferenceException' when it tries to flatten the form - form.FlattenFields().
Could someone help me?

Related

adding multiple text files to gridview (devexpress) in vb.net

I have a folder with multiple text files in it, each text files has about 14 lines of text.
I would like to add all text files in that folder to a gridcontrol/gridview in vb.net.
My current code only adds 1 text file instead of adding all. any help would be greatly appreciated.
Dim path As String = "C:\Plan\"
For Each i As String In System.IO.Directory.GetFiles(path)
Dim a, b, c As String
a = System.IO.Path.GetFileNameWithoutExtension(i)
b = System.IO.Path.GetFileName(i)
c = System.IO.Path.GetFullPath(i)
Dim LINE_pair As String = IO.File.ReadLines(i).ElementAtOrDefault(0)
Dim LINE1_details As String = IO.File.ReadLines(i).ElementAtOrDefault(1)
Dim LINE2_outlookcombo As String = IO.File.ReadLines(i).ElementAtOrDefault(2)
Dim LINE3_rsicombo As String = IO.File.ReadLines(i).ElementAtOrDefault(3)
Dim LINE4_macdcombo As String = IO.File.ReadLines(i).ElementAtOrDefault(4)
Dim LINE4_ratio As String = IO.File.ReadLines(i).ElementAtOrDefault(5)
Dim LINE5_pattern As String = IO.File.ReadLines(i).ElementAtOrDefault(6)
Dim LINE6_none As String = IO.File.ReadLines(i).ElementAtOrDefault(7)
Dim LINE7_timeframecomvo As String = IO.File.ReadLines(i).ElementAtOrDefault(8)
Dim LINE7_date As String = IO.File.ReadLines(i).ElementAtOrDefault(9)
Dim LINE8_trade As String = IO.File.ReadLines(i).ElementAtOrDefault(10)
Dim LINE9_currentprice As String = IO.File.ReadLines(i).ElementAtOrDefault(11)
Dim LINE10_tp As String = IO.File.ReadLines(i).ElementAtOrDefault(12)
Dim LINE11_sl As String = IO.File.ReadLines(i).ElementAtOrDefault(13)
Dim NewItem As New ListViewItem(a)
Dim dt As New DataTable()
dt.Columns.AddRange(New DataColumn(13) {New DataColumn("Pair"), New DataColumn("Outlook"), New DataColumn("RSI"), New DataColumn("MACD"), New DataColumn("Pattern"), New DataColumn("Misc"), New DataColumn("Rato"), New DataColumn("Time Frame"), New DataColumn("Date"), New DataColumn("File name"), New DataColumn("Trade Status"), New DataColumn("CP"), New DataColumn("TP"), New DataColumn("SL")})
dt.Rows.Add(New String() {LINE_pair, LINE2_outlookcombo, LINE3_rsicombo, LINE4_macdcombo, LINE5_pattern, LINE6_none, LINE4_ratio, LINE7_timeframecomvo, LINE7_date, a, LINE8_trade, LINE9_currentprice, LINE10_tp, LINE11_sl})
GridControl1.DataSource = dt
It is not necessary to declare the DataColumn array explicitly. It is created internally from the items in the braces.
You are throwing away your NewItem on each iteration. Why not add them to a list and add them all at once to a ListView.
You are reading the file over and over as you assign the LINE_ data. Read it once and use the resulting lines array.
You never use b and c in this code so I deleted them
I tested in with a .net DataGridView. The file io methods and the DataTable are the same.
Private Sub OPCode()
Dim path As String = "C:\Plan\"
Dim dt As New DataTable()
Dim lstListViewItems As New List(Of ListViewItem)
dt.Columns.AddRange({New DataColumn("Pair"), New DataColumn("Outlook"), New DataColumn("RSI"), New DataColumn("MACD"), New DataColumn("Pattern"), New DataColumn("Misc"), New DataColumn("Rato"), New DataColumn("Time Frame"), New DataColumn("Date"), New DataColumn("File name"), New DataColumn("Trade Status"), New DataColumn("CP"), New DataColumn("TP"), New DataColumn("SL")})
For Each i As String In System.IO.Directory.GetFiles(path)
Dim a = System.IO.Path.GetFileNameWithoutExtension(i)
Dim lines = File.ReadLines(i)
Dim LINE_pair As String = lines.ElementAtOrDefault(0)
Dim LINE1_details As String = lines.ElementAtOrDefault(1)
Dim LINE2_outlookcombo As String = lines.ElementAtOrDefault(2)
Dim LINE3_rsicombo As String = lines.ElementAtOrDefault(3)
Dim LINE4_macdcombo As String = lines.ElementAtOrDefault(4)
Dim LINE4_ratio As String = lines.ElementAtOrDefault(5)
Dim LINE5_pattern As String = lines.ElementAtOrDefault(6)
Dim LINE6_none As String = lines.ElementAtOrDefault(7)
Dim LINE7_timeframecomvo As String = lines.ElementAtOrDefault(8)
Dim LINE7_date As String = lines.ElementAtOrDefault(9)
Dim LINE8_trade As String = lines.ElementAtOrDefault(10)
Dim LINE9_currentprice As String = lines.ElementAtOrDefault(11)
Dim LINE10_tp As String = lines.ElementAtOrDefault(12)
Dim LINE11_sl As String = lines.ElementAtOrDefault(13)
dt.Rows.Add({LINE_pair, LINE2_outlookcombo, LINE3_rsicombo, LINE4_macdcombo, LINE5_pattern, LINE6_none, LINE4_ratio, LINE7_timeframecomvo, LINE7_date, a, LINE8_trade, LINE9_currentprice, LINE10_tp, LINE11_sl})
Dim NewItem As New ListViewItem(a)
lstListViewItems.Add(NewItem)
Next
ListView1.Items.AddRange(lstListViewItems.ToArray)
DataGridView1.DataSource = dt
End Sub

Digitally sign multiple PDF files with an E-ID in a specified folder

Note: I have heavily edited most of my post as I have advanced a bit further now
I am currently working on a small project: the general idea is that the user selects a folder, inserts his E-ID and all PDF files in that folder are modified with his digital signature and an image to represent this when printed.
I am currently using the iTextSharp framework to accomplish this. But because I have to convert the source to VB.NET, I have hit a full stop.
The following code accomplishes its task of adding a digital signature to a PDF document, however. It only does so with the test-certificate I have created with Visual Studio. Anything else and the PDF just isn't created, I have checked with breakpoints and myPkcs12Store does not get filled with anything: I cannot retrieve the personal key from the eID.
Private Sub Test()
Dim myKeyStore As New X509Store(StoreName.My, StoreLocation.CurrentUser)
myKeyStore.Open(OpenFlags.[ReadOnly])
Dim myCertificateCollection As X509Certificate2Collection = myKeyStore.Certificates
Dim myCertificate As X509Certificate2 = Nothing
Dim selectedCertificates As X509Certificate2Collection = X509Certificate2UI.SelectFromCollection(myCertificateCollection, "Certificaten", "Select een certificaat om te tekenen", X509SelectionFlag.SingleSelection)
If selectedCertificates.Count > 0 Then
Dim certificatesEnumerator As X509Certificate2Enumerator = selectedCertificates.GetEnumerator()
certificatesEnumerator.MoveNext()
myCertificate = certificatesEnumerator.Current
End If
myKeyStore.Close()
'Settings'
Dim source = "source.pdf"
Dim result = "result.pdf"
Dim reason = "test"
Dim Location = "locatie"
Dim myPkcs12Store As New Pkcs12Store()
Using memorystreamPfx As New System.IO.MemoryStream(myCertificate.Export(X509ContentType.Pkcs12))
myPkcs12Store.Load(memorystreamPfx, "")
End Using
For Each strAlias As String In myPkcs12Store.Aliases
If myPkcs12Store.IsKeyEntry(strAlias) Then
Dim pk = myPkcs12Store.GetKey(strAlias).Key
Using myPdfReader As New PdfReader(source)
Using myFileStream As New FileStream(result, FileMode.Create, FileAccess.Write)
Using myPdfStamper As PdfStamper = PdfStamper.CreateSignature(myPdfReader, myFileStream, "0")
Dim myPdfDocument As New Document(myPdfReader.GetPageSizeWithRotation(1))
'Define the digital signature appearance'
Dim myPdfSignatureAppearance As PdfSignatureAppearance = myPdfStamper.SignatureAppearance
myPdfSignatureAppearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED
myPdfSignatureAppearance.Image = Image.GetInstance("Images/poro1_by_justduet-d63wx6c.png")
myPdfSignatureAppearance.Reason = reason
myPdfSignatureAppearance.Location = Location
myPdfSignatureAppearance.SetVisibleSignature(New iTextSharp.text.Rectangle(myPdfDocument.PageSize.Width - 120, 36, myPdfDocument.PageSize.Width - 36, 96), myPdfReader.NumberOfPages, "Digital Signature")
'Attach digital signature to PDF document'
Dim myExternalSignature As IExternalSignature = New PrivateKeySignature(pk, "SHA-256")
MakeSignature.SignDetached(myPdfSignatureAppearance, myExternalSignature, {(myPkcs12Store.GetCertificate(strAlias).Certificate)}, Nothing, Nothing, Nothing, 0, CryptoStandard.CMS)
End Using
End Using
End Using
End If
Next
Any help would be appreciated! Further questions please ask
bdebaere
For anyone looking for an answer to this:
Dim myX509Store As New X509Store(StoreName.My, StoreLocation.CurrentUser)
myX509Store.Open(OpenFlags.[ReadOnly])
'Dim myCertificateCollection As X509Certificate2Collection = myX509Store.Certificates
Dim myCertificateChain As IList(Of X509Certificate) = New List(Of X509Certificate)()
Dim myCertificate As X509Certificate2 = Nothing
Dim myCertificateCollection As X509Certificate2Collection = X509Certificate2UI.SelectFromCollection(myX509Store.Certificates, "Certificaten", "Select een certificaat om te tekenen", X509SelectionFlag.SingleSelection)
If myCertificateCollection.Count > 0 Then
Dim certificatesEnumerator As X509Certificate2Enumerator = myCertificateCollection.GetEnumerator()
certificatesEnumerator.MoveNext()
myCertificate = certificatesEnumerator.Current
'myCertificate = selectedCertificates(0)
Dim myX509Chain As New X509Chain()
myX509Chain.Build(myCertificate)
For Each myChainElement As X509ChainElement In myX509Chain.ChainElements
myCertificateChain.Add(DotNetUtilities.FromX509Certificate(myChainElement.Certificate))
Next
End If
myX509Store.Close()
Dim ocspClient As IOcspClient = New OcspClientBouncyCastle()
Dim tsaClient As ITSAClient = Nothing
For intI As Integer = 0 To myCertificateChain.Count - 1
Dim cert As X509Certificate = myCertificateChain(intI)
Dim tsaUrl As String = CertificateUtil.GetTSAURL(cert)
If tsaUrl IsNot Nothing Then
tsaClient = New TSAClientBouncyCastle(tsaUrl)
Exit For
End If
Next
Dim crlList As IList(Of ICrlClient) = New List(Of ICrlClient)()
crlList.Add(New CrlClientOnline(myCertificateChain))
'Settings
Dim source = "source.pdf"
Dim result = "result.pdf"
Dim reason = "test"
Dim Location = "locatie"
Using myPdfReader As New PdfReader(source)
Using myFileStream As New FileStream(result, FileMode.Create, FileAccess.Write)
Using myPdfStamper As PdfStamper = PdfStamper.CreateSignature(myPdfReader, myFileStream, "0"c)
Dim myPdfDocument As New Document(myPdfReader.GetPageSizeWithRotation(1))
'Define the digital signature appearance
Dim myPdfSignatureAppearance As PdfSignatureAppearance = myPdfStamper.SignatureAppearance
myPdfSignatureAppearance.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED
'myPdfSignatureAppearance.Image = Image.GetInstance("Images/poro1_by_justduet-d63wx6c.png")
myPdfSignatureAppearance.Reason = reason
myPdfSignatureAppearance.Location = Location
myPdfSignatureAppearance.SetVisibleSignature(New iTextSharp.text.Rectangle(myPdfDocument.PageSize.Width - 120, 36, myPdfDocument.PageSize.Width - 36, 96), myPdfReader.NumberOfPages, "Digital Signature")
Dim pks As IExternalSignature = New X509Certificate2Signature(myCertificate, DigestAlgorithms.SHA1)
'Attach digital signature to PDF document
'Dim myExternalSignature As IExternalSignature = New PrivateKeySignature(pk, "SHA-256")
MakeSignature.SignDetached(myPdfSignatureAppearance, pks, myCertificateChain, crlList, ocspClient, tsaClient, 0, CryptoStandard.CMS)
End Using
End Using
End Using
The only problem is if you are using eID for every PDF you have to enter your PIN.
bdebaere

Itextsharp Error using RegenerateField : Field Name can't contain a '#'

How do I hide a button in a PDF? When I try the code below I get an error that says the Field Name can't contain a '#'. The error occurs on the line that uses RegenerateField.
The field name is "form1[0].#pageSet[0].Page1[0].PrintButton1[0]"
Thanks in advance.
Using outStream As New MemoryStream
Dim pdfReader As New PdfReader(pdfBinaryFile)
Dim stamper As New PdfStamper(pdfReader, outStream)
Dim form As AcroFields = stamper.AcroFields
stamper.AddViewerPreference(PdfName.HIDETOOLBAR, New PdfBoolean(True))
stamper.AddViewerPreference(PdfName.FITWINDOW, New PdfBoolean(True))
stamper.FormFlattening = False
Dim keyStringPrintButton As String = stamper.AcroFields.Fields.First(Function(item) item.Key.ToString().ToUpper().Contains("PRINT")).Key.ToString()
Dim keyValuePrintButton As AcroFields.Item = stamper.AcroFields.Fields.First(Function(item) item.Key.ToString().ToUpper().Contains("PRINT")).Value
Dim dictionaryEntryPrintButton As Dictionary(Of String, AcroFields.Item)
dictionaryEntryPrintButton = New Dictionary(Of String, AcroFields.Item)
dictionaryEntryPrintButton.Add(keyStringPrintButton, keyValuePrintButton)
form.SetFieldProperty(dictionaryEntryPrintButton.Keys(0), "setfflags", PdfFormField.FLAGS_HIDDEN, Nothing)
form.RegenerateField(dictionaryEntryPrintButton.Keys(0))
stamper.Close()
pdfReader.Close()
End Using
I found the answer. The SetFieldProperty command was using PdfFormField.FLAGS_HIDDEN and it should be using PDfAnnotation and "setflags' instead.
So
form.SetFieldProperty(dictionaryEntryPrintButton.Keys(0), "setfflags", PdfFormField.FLAGS_HIDDEN, Nothing)
Becomes
form.SetFieldProperty(dictionaryEntryPrintButton.Keys(0), "setflags", PdfAnnotation.FLAGS_HIDDEN, Nothing)
And I don't need the RegenerateField command.

how to add new row after filling all textboxes, not replace old row in gridview?

i wrote program in vb.net. in my page, i have 3 textbox. in Txt_CardBarcode_TextChanged ,i wrote this codes:
Try
Dim stream_CardBarcode As System.IO.MemoryStream = New System.IO.MemoryStream
Dim cls As New Cls_Barcode
Dim pic_CardBarcode As System.Drawing.Image = Nothing
cls.btnEncode(pic_CardBarcode, Txt_CardBarcode.Text.Trim)
pic_CardBarcode.Save(stream_CardBarcode, System.Drawing.Imaging.ImageFormat.Png)
Dim f_cardBarcode As IO.FileStream = _
New IO.FileStream("C:\fafa.png", IO.FileMode.Create, IO.FileAccess.ReadWrite)
Dim b_cardBarcode As Byte() = stream_CardBarcode.ToArray
f_cardBarcode.Write(b_cardBarcode, 0, b_cardBarcode.Length)
f_cardBarcode.Close()
Dim ds As DS_Test
ds = New DS_Test
Dim Val_LabelBarcode() = {stream_CardBarcode.ToArray, Txt_ICCID.Text.Trim}
ds.Tables(2).Rows.Add(Val_LabelBarcode)
crp_CardBarcode.SetDataSource(ds.Tables(2))
Dim frm_CrpCardBarcode As New Frm_RepCardBarcode
frm_CrpCardBarcode.CrystalReportViewer1.ReportSource = crp_CardBarcode
GVSimInfo.DataSource = ds.Tables(2)
ds.Tables(2).Rows.Add(1)
GVSimInfo.Rows(GVSimInfo.Rows.Count - 1).Cells(0).Value = True
ds.Tables(2).Rows(0).Item(0) = True
ds.Tables(2).Rows(0).Item(1) = ""
ds.Tables(2).Rows(0).Item(2) = Txt_ICCID.Text
ds.Tables(2).Rows(0).Item(3) = ""
ds.Tables(2).Rows(0).Item(4) = ""
now, in run time, after filling 3textbox, new row add to gridview , but when user want to more than filling textboxes, new row in grid view replace on old row!!!
how to set new row add to grid view , instead of replace old row?
in my dataset, i put 3tables. tables(2) has 2 columns that save image barcode with byte array data type, but in my gridview ,i have 5 columns.
in run time give me error dialog,it is images from it:
If your DGV is not bound to any data Source:
GVSimInfo.Rows.Add(1);
If your DGV is bound to some Data Source then :
ds.Tables(2).Rows.Add(1)
Add this code after your last text box is filled and new row is needed.
to set the values you can use :
ds.Tables(2).Rows(0).Item("Column_number") = "your text"
Try
Dim stream_CardBarcode As System.IO.MemoryStream = New System.IO.MemoryStream
Dim cls As New Cls_Barcode
Dim pic_CardBarcode As System.Drawing.Image = Nothing
cls.btnEncode(pic_CardBarcode, Txt_CardBarcode.Text.Trim)
pic_CardBarcode.Save(stream_CardBarcode, System.Drawing.Imaging.ImageFormat.Png)
Dim f_cardBarcode As IO.FileStream = _
New IO.FileStream("C:\fafa.png", IO.FileMode.Create, IO.FileAccess.ReadWrite)
Dim b_cardBarcode As Byte() = stream_CardBarcode.ToArray
f_cardBarcode.Write(b_cardBarcode, 0, b_cardBarcode.Length)
f_cardBarcode.Close()
Dim ds As DS_Test
ds = New DS_Test
Dim Val_LabelBarcode() = {stream_CardBarcode.ToArray, Txt_ICCID.Text.Trim}
ds.Tables(2).Rows.Add(Val_LabelBarcode)
crp_CardBarcode.SetDataSource(ds.Tables(2))
Dim frm_CrpCardBarcode As New Frm_RepCardBarcode
frm_CrpCardBarcode.CrystalReportViewer1.ReportSource = crp_CardBarcode
ds.Tables(2).Rows.Add(1)
GVSimInfo.Rows(GVSimInfo.Rows.Count - 1).Cells(0).Value = True
ds.Tables(2).Rows(0).Item(0) = True
ds.Tables(2).Rows(0).Item(1) = ""
ds.Tables(2).Rows(0).Item(2) = Txt_ICCID.Text
ds.Tables(2).Rows(0).Item(3) = ""
ds.Tables(2).Rows(0).Item(4) = ""
GVSimInfo.DataSource = ds.Tables(2) <-------

BooleanQuery worked but not SpanNearQuery

I have following code...
Dim term1 As Lucene.Net.Index.Term = New Lucene.Net.Index.Term("contents", "technical")
Dim term2 As Lucene.Net.Index.Term = New Lucene.Net.Index.Term("contents", "c++")
Dim span1 As SpanQuery = New SpanTermQuery(term1)
Dim span2 As SpanQuery = New SpanTermQuery(term2)
Dim spanQuery As SpanNearQuery = New SpanNearQuery(New SpanQuery() {
span1,
span2},
2000000,
False
)
Dim booleanQuery As BooleanQuery = New BooleanQuery()
booleanQuery.SetMinimumNumberShouldMatch(0)
booleanQuery.Add(span1, BooleanClause.Occur.SHOULD)
booleanQuery.Add(span2, BooleanClause.Occur.SHOULD)
Now if i Search for Boolean query then it return some docs, but if i search for SpanNearQuery then it does not return any doc..
And here is my indexation code..
Dim indexLocation As String = "C:/index"
Dim directory As Lucene.Net.Store.Directory = Lucene.Net.Store.FSDirectory.Open(New DirectoryInfo(indexLocation))
'create an analyzer to process the text
Dim analyzer As Lucene.Net.Analysis.Analyzer = New Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29)
'creating an index writer to write the doc to index
Dim deletionPolicy As Lucene.Net.Index.IndexDeletionPolicy = New Lucene.Net.Index.KeepOnlyLastCommitDeletionPolicy()
Dim indexWriter As Lucene.Net.Index.IndexWriter = New Lucene.Net.Index.IndexWriter(directory, analyzer, True, deletionPolicy, Lucene.Net.Index.IndexWriter.MaxFieldLength.UNLIMITED)
Dim files() As String
files = System.IO.Directory.GetFiles("C:\ResumeDirectory\")
For i As Integer = 0 To files.Length - 1
Dim streamReader As StreamReader = New StreamReader(files(i))
Dim docField1 As Field = New Field("contents", streamReader, Lucene.Net.Documents.Field.TermVector.YES)
Dim docField2 As Field = New Field("CandidateID", files(i), Field.Store.YES, Field.Index.NOT_ANALYZED)
Dim doc As Document = New Document()
doc.Add(docField1)
doc.Add(docField2)
'writing the document to index
indexWriter.AddDocument(doc)
streamReader.Close()
Next
'optimize and close the writer
indexWriter.Optimize()
indexWriter.Dispose()
End Sub
Is there anything wrong with my code of SpanNearQuery?