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