1
+ using Syncfusion . HtmlConverter ;
2
+ using Syncfusion . Pdf ;
3
+ using Syncfusion . Pdf . Graphics ;
4
+ using Syncfusion . Pdf . Interactive ;
5
+ using Syncfusion . Pdf . Parsing ;
6
+ using Syncfusion . Pdf . Redaction ;
7
+ using Syncfusion . Pdf . Security ;
8
+
9
+ class Program
10
+ {
11
+ static void Main ( string [ ] args )
12
+ {
13
+ // Initialize HTML to PDF converter and load HTML
14
+ HtmlToPdfConverter htmlConverter = new HtmlToPdfConverter ( ) ;
15
+ string htmlFilePath = Path . GetFullPath ( @"Data/Input.html" ) ;
16
+ PdfDocument document = htmlConverter . Convert ( htmlFilePath ) ;
17
+
18
+ // Save the PDF to a memory stream
19
+ using ( MemoryStream memoryStream = new MemoryStream ( ) )
20
+ {
21
+ document . Save ( memoryStream ) ;
22
+ document . Close ( true ) ;
23
+
24
+ // Load back the PDF for further processing
25
+ memoryStream . Position = 0 ;
26
+ PdfLoadedDocument loadedDocument = new PdfLoadedDocument ( memoryStream ) ;
27
+
28
+ // This will collect (pageIndex, word) for each form field
29
+ List < ( int pageIdx , TextWord word ) > fieldData = new List < ( int pageIdx , TextWord word ) > ( ) ;
30
+
31
+ // Pass 1: Locate each placeholder and add a redaction on its bound
32
+ for ( int i = 0 ; i < loadedDocument . Pages . Count ; i ++ )
33
+ {
34
+ PdfLoadedPage page = loadedDocument . Pages [ i ] as PdfLoadedPage ;
35
+ page . ExtractText ( out TextLineCollection lines ) ;
36
+ if ( lines == null ) continue ;
37
+ foreach ( TextLine line in lines . TextLine )
38
+ {
39
+ foreach ( TextWord word in line . WordCollection )
40
+ {
41
+ if ( word == null ) continue ;
42
+ if ( word . Text == "{{name}}" ||
43
+ word . Text == "{{date}}" ||
44
+ word . Text == "{{signature}}" )
45
+ {
46
+ page . AddRedaction ( new PdfRedaction ( word . Bounds ) ) ;
47
+ fieldData . Add ( ( i , word ) ) ;
48
+ }
49
+ }
50
+ }
51
+ }
52
+ loadedDocument . Redact ( ) ;
53
+
54
+ // Pass 2: Add form fields exactly over the bounds
55
+ foreach ( var ( pageIdx , word ) in fieldData )
56
+ {
57
+ PdfPageBase page = loadedDocument . Pages [ pageIdx ] ;
58
+
59
+ if ( word . Text == "{{name}}" )
60
+ {
61
+ PdfTextBoxField textBox = new PdfTextBoxField ( page , "FirstName" )
62
+ {
63
+ Bounds = word . Bounds ,
64
+ ToolTip = "First Name" ,
65
+ Text = "John"
66
+ } ;
67
+ loadedDocument . Form . Fields . Add ( textBox ) ;
68
+ }
69
+ else if ( word . Text == "{{date}}" )
70
+ {
71
+ PdfTextBoxField dateField = new PdfTextBoxField ( page , "DateField" )
72
+ {
73
+ Bounds = word . Bounds
74
+ } ;
75
+ dateField . Actions . KeyPressed = new PdfJavaScriptAction ( "AFDate_KeystrokeEx(\" m/d/yy\" )" ) ;
76
+ dateField . Actions . Format = new PdfJavaScriptAction ( "AFDate_FormatEx(\" m/d/yy\" )" ) ;
77
+ loadedDocument . Form . Fields . Add ( dateField ) ;
78
+ }
79
+ else if ( word . Text == "{{signature}}" )
80
+ {
81
+ PdfSignatureField sigField = new PdfSignatureField ( page , "SignatureField" )
82
+ {
83
+ Bounds = word . Bounds ,
84
+ Signature = new PdfSignature ( )
85
+ } ;
86
+ // Optionally draw a signature image in the field area
87
+ FileStream imageStream = new FileStream ( Path . GetFullPath ( "Data/signature.png" ) , FileMode . Open , FileAccess . Read ) ;
88
+ PdfBitmap image = new PdfBitmap ( imageStream ) ;
89
+ ( page as PdfLoadedPage ) . Graphics . DrawImage ( image , word . Bounds ) ;
90
+ imageStream . Dispose ( ) ;
91
+
92
+ // Optional: add digital certificate
93
+ using ( FileStream certStream = new FileStream ( Path . GetFullPath ( @"Data/PDF.pfx" ) , FileMode . Open , FileAccess . Read ) )
94
+ {
95
+ sigField . Signature . Certificate = new PdfCertificate ( certStream , "syncfusion" ) ;
96
+ sigField . Signature . Reason = "I am author of this document" ;
97
+ }
98
+ loadedDocument . Form . Fields . Add ( sigField ) ;
99
+ }
100
+ }
101
+ //Create file stream.
102
+ using ( FileStream outputFileStream = new FileStream ( Path . GetFullPath ( @"Output/Output.pdf" ) , FileMode . Create , FileAccess . ReadWrite ) )
103
+ {
104
+ //Save the PDF document to file stream.
105
+ loadedDocument . Save ( outputFileStream ) ;
106
+ }
107
+
108
+ //Close the document.
109
+ loadedDocument . Close ( true ) ;
110
+ }
111
+ }
112
+ }
0 commit comments