Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Syncfusion.HtmlConverter;
using Syncfusion.Pdf;
using Syncfusion.Pdf.Graphics;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.InteropServices;

Expand All @@ -20,58 +21,124 @@ public Function1(ILogger<Function1> logger)
}

[Function("Function1")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log, FunctionContext executionContext)
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
{
string blinkBinariesPath = string.Empty;
//Create a new PDF document.
PdfDocument document;
BlinkConverterSettings settings = new BlinkConverterSettings();
//Creating the stream object.
MemoryStream stream;
_logger.LogInformation("C# HTTP trigger function processed a request.");
try
{
blinkBinariesPath = SetupBlinkBinaries();

//Initialize the HTML to PDF converter with the Blink rendering engine.
byte[] pdfBytes = HtmlToPdfConvert("<p>Hello world</p>");
return new FileStreamResult(new MemoryStream(pdfBytes), "application/pdf");
}
catch (Exception ex)
{
_logger.LogError(ex.Message.ToString(), "An error occurred while converting HTML to PDF.");
return new ContentResult
{
Content = $"Error: {ex.Message}",
ContentType = "text/plain",
StatusCode = StatusCodes.Status500InternalServerError
};

}

}
public byte[] HtmlToPdfConvert(string htmlText)
{
if (string.IsNullOrWhiteSpace(htmlText))
{
throw new ArgumentException("HTML text cannot be null or empty.", nameof(htmlText));
}

try
{
// Setup Blink binaries and install necessary packages
var blinkBinariesPath = SetupBlinkBinaries();
InstallLinuxPackages();

// Initialize HTML to PDF converter
HtmlToPdfConverter htmlConverter = new HtmlToPdfConverter(HtmlRenderingEngine.Blink);
settings.BlinkPath = blinkBinariesPath;
//Assign BlinkConverter settings to the HTML converter

// Display settings
BlinkConverterSettings settings = new BlinkConverterSettings
{
BlinkPath = blinkBinariesPath,
ViewPortSize = new Syncfusion.Drawing.Size(1024, 768), // Set your desired viewport size
Margin = new PdfMargins
{
Top = 20, // Set your desired margins
Left = 20,
Right = 20,
Bottom = 20
}
};
htmlConverter.ConverterSettings = settings;
//Convert URL to PDF
document = htmlConverter.Convert("http://www.syncfusion.com");
stream = new MemoryStream();
//Save and close the PDF document
document.Save(stream);

// Convert HTML to PDF
using (var memoryStream = new MemoryStream())
{
PdfDocument document = htmlConverter.Convert(htmlText, null);
document.Save(memoryStream);
document.Close(true);
return memoryStream.ToArray();
}
}
catch (Exception ex)
{
// Handle exceptions
Console.WriteLine("An error occurred: " + ex.Message);
throw;
}
}
#region Install dependencies.
private static void InstallLinuxPackages()
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return;
}
catch(Exception ex)
FileAccessPermissions ExecutableFilePermissions = FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite | FileAccessPermissions.UserExecute |
FileAccessPermissions.GroupRead | FileAccessPermissions.GroupExecute | FileAccessPermissions.OtherRead | FileAccessPermissions.OtherExecute;
string assemblyDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
//Install the dependencies packages for HTML to PDF conversion in Linux
string shellFilePath = Path.Combine(assemblyDirectory);
string tempBlinkDir = Path.GetTempPath();
string dependenciesPath = Path.Combine(tempBlinkDir, "dependenciesInstall.sh");
if (!File.Exists(dependenciesPath))
{
//Create a new PDF document.
document = new PdfDocument();
//Add a page to the document.
PdfPage page = document.Pages.Add();
//Create PDF graphics for the page.
PdfGraphics graphics = page.Graphics;

//Set the standard font.
PdfFont font = new PdfStandardFont(PdfFontFamily.Helvetica, 8);
//Draw the text.
graphics.DrawString(ex.Message.ToString(), font, PdfBrushes.Black, new Syncfusion.Drawing.PointF(0, 0));

stream = new MemoryStream();
//Save the document into memory stream.
document.Save(stream);


CopyFilesRecursively(shellFilePath, tempBlinkDir);
var execPath = Path.Combine(tempBlinkDir, "dependenciesInstall.sh");
if (File.Exists(execPath))
{
var code = Chmod(execPath, ExecutableFilePermissions);
if (code != 0)
{
throw new Exception("Chmod operation failed");
}
}

Process process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "/bin/bash",
Arguments = "-c " + execPath,
CreateNoWindow = true,
UseShellExecute = false,
}
};
process.Start();
process.WaitForExit();
}

document.Close();
stream.Position = 0;
return new FileStreamResult(stream, "application/pdf");
}
private static string SetupBlinkBinaries( )
#endregion

#region Setup Blink Binaries

private static string SetupBlinkBinaries()
{
var fileInfo = new FileInfo(Assembly.GetExecutingAssembly().Location);
string path = fileInfo.Directory.Parent.FullName;
string blinkAppDir = Path.Combine(path, @"wwwroot");
string assemblyDirectory = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "runtimes", "linux", "native");
string blinkAppDir = Path.Combine(assemblyDirectory);
string tempBlinkDir = Path.GetTempPath();
string chromePath = Path.Combine(tempBlinkDir, "chrome");
if (!File.Exists(chromePath))
Expand All @@ -81,39 +148,46 @@ private static string SetupBlinkBinaries( )
}
return tempBlinkDir;
}

private static void CopyFilesRecursively(string sourcePath, string targetPath)
{
//Create all the directories from the source to the destination path.
foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
{
Directory.CreateDirectory(dirPath.Replace(sourcePath, targetPath));
}

//Copy all the files from the source path to the destination path.
foreach (string newPath in Directory.GetFiles(sourcePath, "*.*", SearchOption.AllDirectories))
{
File.Copy(newPath, newPath.Replace(sourcePath, targetPath), true);
}
}

[DllImport("libc", SetLastError = true, EntryPoint = "chmod")]
internal static extern int Chmod(string path, FileAccessPermissions mode);

private static void SetExecutablePermission(string tempBlinkDir)
{
FileAccessPermissions ExecutableFilePermissions = FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite | FileAccessPermissions.UserExecute |
FileAccessPermissions.GroupRead | FileAccessPermissions.GroupExecute | FileAccessPermissions.OtherRead | FileAccessPermissions.OtherExecute;
FileAccessPermissions ExecutableFilePermissions =
FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite | FileAccessPermissions.UserExecute |
FileAccessPermissions.GroupRead | FileAccessPermissions.GroupExecute | FileAccessPermissions.OtherRead |
FileAccessPermissions.OtherExecute;
string[] executableFiles = new string[] { "chrome", "chrome_sandbox" };
foreach (string executable in executableFiles)
{
var execPath = Path.Combine(tempBlinkDir, executable);
if (File.Exists(execPath))
{
var code = Function1.Chmod(execPath, ExecutableFilePermissions);
var code = Chmod(execPath, ExecutableFilePermissions);
if (code != 0)
{
throw new Exception("Chmod operation failed");
}
}
}
}

[Flags]
internal enum FileAccessPermissions : uint
{
Expand All @@ -127,5 +201,7 @@ internal enum FileAccessPermissions : uint
UserWrite = 128,
UserRead = 256
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
<PackageReference Include="Syncfusion.HtmlToPdfConverter.Net.Linux" Version="*" />
</ItemGroup>
<ItemGroup>
<None Update="dependenciesInstall.sh">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
apt-get update && apt-get install -yq --no-install-recommends libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 libnss3 libgbm1