'' 完毕:
Imports System.IO
Imports System.Drawing
Imports GrapeCity.Documents.Pdf
Imports GrapeCity.Documents.Pdf.AcroForms
Imports GrapeCity.Documents.Text
Imports System.Security.Cryptography.X509Certificates
'' 此示例生成并签署 PDF(使用与 SignDoc 示例类似的代码),
'' 然后使用第二个签名对生成的 PDF 进行签名,而不会使原始文件失效
'' 签名,通过使用增量更新(使用 Sign() 方法时的默认设置)。
Public Class SignIncremental
Function CreatePDF(ByVal stream As Stream) As Integer
Dim doc = New GcPdfDocument()
'' 加载签名文档(我们使用类似于SignDoc示例的代码):
doc.Load(CreateAndSignPdf())
'' 初始化第二个证书:
Dim pfxPath = Path.Combine("Resources", "Misc", "JohnDoe.pfx")
Dim cert = New X509Certificate2(File.ReadAllBytes(pfxPath), "secret",
X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.Exportable)
Dim sp2 = New SignatureProperties() With {
.SignatureBuilder = New Pkcs7SignatureBuilder() With {.CertificateChain = New X509Certificate2() {cert}},
.Location = "DsPdfWeb Demo Browser",
.SignerName = "Jaime Smith",
.SigningDateTime = Util.TimeNow()
}
'' 找到第二个(尚未填写)签名字段:
Dim sfld2 = CType(doc.AcroForm.Fields("SecondSignature"), SignatureField)
'' 连接签名字段和签名属性:
If sfld2 Is Nothing Then
Throw New Exception("Unexpected: could not find 'SecondSignature' field")
End If
sp2.SignatureField = sfld2
'' 签署并保存文档:
doc.Sign(sp2, stream)
'' 倒回流以读取刚刚创建的文档
'' 进入另一个 GcPdfDocument 并验证所有签名:
stream.Seek(0, SeekOrigin.Begin)
Dim doc2 = New GcPdfDocument()
doc2.Load(stream)
For Each fld In doc2.AcroForm.Fields
If TypeOf fld Is SignatureField Then
Dim sfld = CType(fld, SignatureField)
If Not sfld.Value.VerifySignatureValue() Then
Throw New Exception($"Failed to verify signature for field {sfld.Name}")
End If
End If
Next
''
'' 完成(生成并签名的文档已保存到“流”)。
Return doc.Pages.Count
End Function
'' 这个方法与SignDoc示例几乎完全相同,
'' 但添加了第二个签名字段(但不签名):
Private Function CreateAndSignPdf() As Stream
Dim doc = New GcPdfDocument()
Dim page = doc.NewPage()
Dim tf = New TextFormat() With {.Font = StandardFonts.Times, .FontSize = 14}
page.Graphics.DrawString("你好世界!" +
"",
tf, New PointF(72, 72))
'' 初始化测试证书:
Dim pfxPath = Path.Combine("Resources", "Misc", "DsPdfTest.pfx")
Dim cert = New X509Certificate2(File.ReadAllBytes(pfxPath), "qq",
X509KeyStorageFlags.MachineKeySet Or X509KeyStorageFlags.PersistKeySet Or X509KeyStorageFlags.Exportable)
Dim sp = New SignatureProperties() With {
.SignatureBuilder = New Pkcs7SignatureBuilder() With {
.CertificateChain = New X509Certificate2() {cert}
},
.Location = "DsPdfWeb Demo Browser",
.SignerName = "DsPdfWeb",
.SigningDateTime = Util.TimeNow()
}
'' 初始化一个签名字段来保存签名:
Dim sf = New SignatureField()
sf.Widget.Rect = New RectangleF(72, 72 * 2, 72 * 4, 36)
sf.Widget.Page = page
sf.Widget.BackColor = Color.LightSeaGreen
'' 将签名字段添加到文档中:
doc.AcroForm.Fields.Add(sf)
'' 连接签名字段和签名属性:
sp.SignatureField = sf
'' 添加第二个签名字段:
Dim sf2 = New SignatureField() With {.Name = "SecondSignature"}
sf2.Widget.Rect = New RectangleF(72, 72 * 3, 72 * 4, 36)
sf2.Widget.Page = page
sf2.Widget.BackColor = Color.LightYellow
'' 将签名字段添加到文档中:
doc.AcroForm.Fields.Add(sf2)
Dim ms = New MemoryStream()
doc.Sign(sp, ms)
Return ms
End Function
End Class