55using Syncfusion . HtmlConverter ;
66using Syncfusion . Pdf ;
77using Syncfusion . Pdf . Graphics ;
8+ using System . Diagnostics ;
89using System . Reflection ;
910using System . Runtime . InteropServices ;
1011
@@ -20,58 +21,124 @@ public Function1(ILogger<Function1> logger)
2021 }
2122
2223 [ Function ( "Function1" ) ]
23- public static async Task < IActionResult > Run ( [ HttpTrigger ( AuthorizationLevel . Function , "get" , "post" , Route = null ) ] HttpRequest req , ILogger log , FunctionContext executionContext )
24+ public IActionResult Run ( [ HttpTrigger ( AuthorizationLevel . Function , "get" , "post" ) ] HttpRequest req )
2425 {
25- string blinkBinariesPath = string . Empty ;
26- //Create a new PDF document.
27- PdfDocument document ;
28- BlinkConverterSettings settings = new BlinkConverterSettings ( ) ;
29- //Creating the stream object.
30- MemoryStream stream ;
26+ _logger . LogInformation ( "C# HTTP trigger function processed a request." ) ;
3127 try
3228 {
33- blinkBinariesPath = SetupBlinkBinaries ( ) ;
34-
35- //Initialize the HTML to PDF converter with the Blink rendering engine.
29+ byte [ ] pdfBytes = HtmlToPdfConvert ( "<p>Hello world</p>" ) ;
30+ return new FileStreamResult ( new MemoryStream ( pdfBytes ) , "application/pdf" ) ;
31+ }
32+ catch ( Exception ex )
33+ {
34+ _logger . LogError ( ex . Message . ToString ( ) , "An error occurred while converting HTML to PDF." ) ;
35+ return new ContentResult
36+ {
37+ Content = $ "Error: { ex . Message } ",
38+ ContentType = "text/plain" ,
39+ StatusCode = StatusCodes . Status500InternalServerError
40+ } ;
41+
42+ }
43+
44+ }
45+ public byte [ ] HtmlToPdfConvert ( string htmlText )
46+ {
47+ if ( string . IsNullOrWhiteSpace ( htmlText ) )
48+ {
49+ throw new ArgumentException ( "HTML text cannot be null or empty." , nameof ( htmlText ) ) ;
50+ }
51+
52+ try
53+ {
54+ // Setup Blink binaries and install necessary packages
55+ var blinkBinariesPath = SetupBlinkBinaries ( ) ;
56+ InstallLinuxPackages ( ) ;
57+
58+ // Initialize HTML to PDF converter
3659 HtmlToPdfConverter htmlConverter = new HtmlToPdfConverter ( HtmlRenderingEngine . Blink ) ;
37- settings . BlinkPath = blinkBinariesPath ;
38- //Assign BlinkConverter settings to the HTML converter
60+
61+ // Display settings
62+ BlinkConverterSettings settings = new BlinkConverterSettings
63+ {
64+ BlinkPath = blinkBinariesPath ,
65+ ViewPortSize = new Syncfusion . Drawing . Size ( 1024 , 768 ) , // Set your desired viewport size
66+ Margin = new PdfMargins
67+ {
68+ Top = 20 , // Set your desired margins
69+ Left = 20 ,
70+ Right = 20 ,
71+ Bottom = 20
72+ }
73+ } ;
3974 htmlConverter . ConverterSettings = settings ;
40- //Convert URL to PDF
41- document = htmlConverter . Convert ( "http://www.syncfusion.com" ) ;
42- stream = new MemoryStream ( ) ;
43- //Save and close the PDF document
44- document . Save ( stream ) ;
75+
76+ // Convert HTML to PDF
77+ using ( var memoryStream = new MemoryStream ( ) )
78+ {
79+ PdfDocument document = htmlConverter . Convert ( htmlText , null ) ;
80+ document . Save ( memoryStream ) ;
81+ document . Close ( true ) ;
82+ return memoryStream . ToArray ( ) ;
83+ }
84+ }
85+ catch ( Exception ex )
86+ {
87+ // Handle exceptions
88+ Console . WriteLine ( "An error occurred: " + ex . Message ) ;
89+ throw ;
90+ }
91+ }
92+ #region Install dependencies.
93+ private static void InstallLinuxPackages ( )
94+ {
95+ if ( ! RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) )
96+ {
97+ return ;
4598 }
46- catch ( Exception ex )
99+ FileAccessPermissions ExecutableFilePermissions = FileAccessPermissions . UserRead | FileAccessPermissions . UserWrite | FileAccessPermissions . UserExecute |
100+ FileAccessPermissions . GroupRead | FileAccessPermissions . GroupExecute | FileAccessPermissions . OtherRead | FileAccessPermissions . OtherExecute ;
101+ string assemblyDirectory = Path . GetDirectoryName ( System . Reflection . Assembly . GetExecutingAssembly ( ) . Location ) ;
102+ //Install the dependencies packages for HTML to PDF conversion in Linux
103+ string shellFilePath = Path . Combine ( assemblyDirectory ) ;
104+ string tempBlinkDir = Path . GetTempPath ( ) ;
105+ string dependenciesPath = Path . Combine ( tempBlinkDir , "dependenciesInstall.sh" ) ;
106+ if ( ! File . Exists ( dependenciesPath ) )
47107 {
48- //Create a new PDF document.
49- document = new PdfDocument ( ) ;
50- //Add a page to the document.
51- PdfPage page = document . Pages . Add ( ) ;
52- //Create PDF graphics for the page.
53- PdfGraphics graphics = page . Graphics ;
54-
55- //Set the standard font.
56- PdfFont font = new PdfStandardFont ( PdfFontFamily . Helvetica , 8 ) ;
57- //Draw the text.
58- graphics . DrawString ( ex . Message . ToString ( ) , font , PdfBrushes . Black , new Syncfusion . Drawing . PointF ( 0 , 0 ) ) ;
59-
60- stream = new MemoryStream ( ) ;
61- //Save the document into memory stream.
62- document . Save ( stream ) ;
63-
108+
109+ CopyFilesRecursively ( shellFilePath , tempBlinkDir ) ;
110+ var execPath = Path . Combine ( tempBlinkDir , "dependenciesInstall.sh" ) ;
111+ if ( File . Exists ( execPath ) )
112+ {
113+ var code = Chmod ( execPath , ExecutableFilePermissions ) ;
114+ if ( code != 0 )
115+ {
116+ throw new Exception ( "Chmod operation failed" ) ;
117+ }
118+ }
119+
120+ Process process = new Process
121+ {
122+ StartInfo = new ProcessStartInfo
123+ {
124+ FileName = "/bin/bash" ,
125+ Arguments = "-c " + execPath ,
126+ CreateNoWindow = true ,
127+ UseShellExecute = false ,
128+ }
129+ } ;
130+ process . Start ( ) ;
131+ process . WaitForExit ( ) ;
64132 }
65-
66- document . Close ( ) ;
67- stream . Position = 0 ;
68- return new FileStreamResult ( stream , "application/pdf" ) ;
69133 }
70- private static string SetupBlinkBinaries ( )
134+ #endregion
135+
136+ #region Setup Blink Binaries
137+
138+ private static string SetupBlinkBinaries ( )
71139 {
72- var fileInfo = new FileInfo ( Assembly . GetExecutingAssembly ( ) . Location ) ;
73- string path = fileInfo . Directory . Parent . FullName ;
74- string blinkAppDir = Path . Combine ( path , @"wwwroot" ) ;
140+ string assemblyDirectory = Path . Combine ( Path . GetDirectoryName ( System . Reflection . Assembly . GetExecutingAssembly ( ) . Location ) , "runtimes" , "linux" , "native" ) ;
141+ string blinkAppDir = Path . Combine ( assemblyDirectory ) ;
75142 string tempBlinkDir = Path . GetTempPath ( ) ;
76143 string chromePath = Path . Combine ( tempBlinkDir , "chrome" ) ;
77144 if ( ! File . Exists ( chromePath ) )
@@ -81,39 +148,46 @@ private static string SetupBlinkBinaries( )
81148 }
82149 return tempBlinkDir ;
83150 }
151+
84152 private static void CopyFilesRecursively ( string sourcePath , string targetPath )
85153 {
86154 //Create all the directories from the source to the destination path.
87155 foreach ( string dirPath in Directory . GetDirectories ( sourcePath , "*" , SearchOption . AllDirectories ) )
88156 {
89157 Directory . CreateDirectory ( dirPath . Replace ( sourcePath , targetPath ) ) ;
90158 }
159+
91160 //Copy all the files from the source path to the destination path.
92161 foreach ( string newPath in Directory . GetFiles ( sourcePath , "*.*" , SearchOption . AllDirectories ) )
93162 {
94163 File . Copy ( newPath , newPath . Replace ( sourcePath , targetPath ) , true ) ;
95164 }
96165 }
166+
97167 [ DllImport ( "libc" , SetLastError = true , EntryPoint = "chmod" ) ]
98168 internal static extern int Chmod ( string path , FileAccessPermissions mode ) ;
169+
99170 private static void SetExecutablePermission ( string tempBlinkDir )
100171 {
101- FileAccessPermissions ExecutableFilePermissions = FileAccessPermissions . UserRead | FileAccessPermissions . UserWrite | FileAccessPermissions . UserExecute |
102- FileAccessPermissions . GroupRead | FileAccessPermissions . GroupExecute | FileAccessPermissions . OtherRead | FileAccessPermissions . OtherExecute ;
172+ FileAccessPermissions ExecutableFilePermissions =
173+ FileAccessPermissions . UserRead | FileAccessPermissions . UserWrite | FileAccessPermissions . UserExecute |
174+ FileAccessPermissions . GroupRead | FileAccessPermissions . GroupExecute | FileAccessPermissions . OtherRead |
175+ FileAccessPermissions . OtherExecute ;
103176 string [ ] executableFiles = new string [ ] { "chrome" , "chrome_sandbox" } ;
104177 foreach ( string executable in executableFiles )
105178 {
106179 var execPath = Path . Combine ( tempBlinkDir , executable ) ;
107180 if ( File . Exists ( execPath ) )
108181 {
109- var code = Function1 . Chmod ( execPath , ExecutableFilePermissions ) ;
182+ var code = Chmod ( execPath , ExecutableFilePermissions ) ;
110183 if ( code != 0 )
111184 {
112185 throw new Exception ( "Chmod operation failed" ) ;
113186 }
114187 }
115188 }
116189 }
190+
117191 [ Flags ]
118192 internal enum FileAccessPermissions : uint
119193 {
@@ -127,5 +201,7 @@ internal enum FileAccessPermissions : uint
127201 UserWrite = 128 ,
128202 UserRead = 256
129203 }
204+
205+ #endregion
130206 }
131207}
0 commit comments