Loading repository data…
Loading repository data…
cajuncoding / repository
This is a C# .NET solution that tests and illustrates the capabilities of Xsl-FO for dynamically generating PDF documents. It provides a way to generate the XSL-FO source xml from Xslt or Razor Templating to address various development teams. And it provides basic WinForms Application that can be used to aid in developing the Xslt and Xsl-FO markup.
This is a C#.Net solution that provides the capability to easily generate Pdf files using a templated approach that provides great separation between presentation (the template) and data (the Model); as opposed to extremely complex code based approaches most libraries provide. It's based on the Xsl-FO standard and now with ApacheFOP.Serverless provides a PDF-as-a-service architecture for generating PDF reports without unnecessary complexity and long term technical debt of legacy approaches (e.g. reporting engines).
In addition, this is a completely open-source and free solution to use (even commercially). Many of the complex (powerful maybe, but horribly difficult to develop and maintain) API libraries out there require licenses that make them no longer feasible solutions simply due to steep licensing costs for many projects.
ApacheFOP.Serverless is a fully functioning serverless implementation of Apache FOP (up-to-date Xsl-FO rendering engine).
It's a simple Java based Azure Function enabling a serverless microservice for Apache FOP via an Azure Function! Super light-weight, really slick, and easy to deploy . . . providing the flexibility of the latest (e.g. v2.5) Xsl-FO processing from Apache FOP!
I hope this helps anyone looking to dynamically generate PDF files in C# or .Net with a templating approach that is far more maintainable than other code based generation/manipulation approaches . . .
If you like this project and/or use it the please give me a Star (c'mon it's free, and it'll make my day)!
I'm happy to share with the community, but if you find this useful (e.g for professional use), and are so inclinded, then I do love-me-some-coffee!
This project illustrates the capabilities of using templating based approaches to render Xsl-FO for dynamically generating PDF documents. This project illustrates the use and support of two of the most common/well-known templating engines for .Net web development -- Razor Templating & XSLT Templating.
The Razor & Xslt template based approaches to rendering PDF files gives you the benefits of separating the presentation from the Data model, allows different team members to work at the same time because the Template can be developed offline with sample Model data that can be easily loaded, and the code can be made very manageable with the use of Xslt include files, variables, etc. to divide your code into modular "DRY" components for re-use across multiple reports, etc.
In addition, the Razor & Xslt engines are extensible and can support virtually unlimited capabilities with C# based extension functions. For Razor templates the world of .Net is immediately available (e.g. Linq). And, for XSLT custom extension functions can be defined in the assembly or inlinein the Xslt, and this project has many custom extensions already included to augment the Xslt v1.0 engine that .Net provides.
Finally, this project also provides basic a Windows Client (WinForms) application that provides a UI that can be used for developing when using the Xslt templating engine.
NOTE: Currently the Razor Implementation requires Microsoft.AspNet.MVC and does not yet support .Net Core. I plan to extend this as soon as I have a real need to render Pdf file from a .Net Core web application; or a console app for that matter (useful info. [https://stackoverflow.com/questions/38247080/using-razor-outside-of-mvc-in-net-core](here on StackOverflow).)
//Use XSLT Template + FONet PDF Rendering Engine...
public virtual byte[] RenderPdf(MovieSearchResponse templateModel)
{
//***********************************************************
//Execute the XSLT Transform to generate the XSL-FO output
//***********************************************************
//Render the XSL-FO output from the Razor Template and the View Model
var xslFODoc = this.RenderXslFOXml(templateModel);
//Create the Pdf Options for the XSL-FO Rendering engine to use
var pdfOptions = this.CreatePdfOptions();
//****************************************************************************
//Execute the Trasnformation of the XSL-FO source to Binary Pdf via Fonet
//****************************************************************************
var xslFOPdfRenderer = new FONetXslFOPdfRenderer(xslFODoc, pdfOptions);
var pdfBytes = xslFOPdfRenderer.RenderPdfBytes();
return pdfBytes;
}
//Use Razor Template + FONet PDF Rendering Engine...
public virtual byte[] RenderPdf(MovieSearchResponse templateModel)
{
//***********************************************************
//Execute the Razor View to generate the XSL-FO output
//***********************************************************
var razorViewRenderer = new AspNetMvcRazorViewRenderer(this.ControllerContext);
var renderResult = razorViewRenderer.RenderView(this.RazorViewVirtualPath, templateModel);
//Load the XSL-FO output into a fully validated XDocument.
//NOTE: This template must generate valid Xsl-FO output -- via the well-formed xml we load into the XDocument return value -- to be rendered as a Pdf Binary!
var xslFODoc = XDocument.Parse(renderResult.RenderOutput);
//Create the Pdf Options for the XSL-FO Rendering engine to use
var pdfOptions = this.CreatePdfOptions();
//****************************************************************************
//Execute the Transformation of the XSL-FO source to Binary Pdf via Fonet
//****************************************************************************
var xslFOPdfRenderer = new FONetXslFOPdfRenderer(xslFODoc, pdfOptions);
var pdfBytes = xslFOPdfRenderer.RenderPdfBytes();
return pdfBytes;
}
//Use Razor Template + ApacheFOP.Serverless Rendering Engine; PDF-as-a-service via Azure Functions...
public virtual async Task<byte[]> RenderPdfAsync(MovieSearchResponse templateModel)
{
//Ensure that compatibility Mode is Disabled for proper rendering of our Model
templateModel.FonetCompatibilityEnabled = false;
//***********************************************************
//Execute the Razor View to generate the XSL-FO output
//***********************************************************
var razorViewRenderer = new AspNetMvcRazorViewRenderer(this.ControllerContext);
var renderResult = razorViewRenderer.RenderView(this.RazorViewVirtualPath, templateModel);
//Load the XSL-FO output into a fully validated XDocument.
//NOTE: This template must generate valid Xsl-FO output to be rendered as a Pdf Binary!
// This is optional, but parsing the output into XML will validate that it is well-formed!
var xslFODoc = XDocument.Parse(renderResult.RenderOutput);
//******************************************************************************************
//Execute the Transformation of the XSL-FO source to Binary Pdf via Apache FOP Service...
//******************************************************************************************
var pdfBytes = await ApacheFOPServiceHelper.RenderXslFOToPdfAsync(xslFODoc);
return pdfBytes;
}
NOTES:
using PdfTemplating.XslFO.Razor.AspNetCoreMvc; //Use XSLT Template + FONet PDF Rendering Engine...
public virtual async Task<byte[]> RenderPdfAsync(MovieSearchResponse templateModel)
{
//NOTE: This is only needed becasue we share the same Report Template between legacy Fonet and new
// ApacheFOP.Serverless rendering; and there are some markup compatibility logic we want to disable.
//Ensure that compatibility Mode is Disabled for proper rendering of our Model
templateModel.FonetCompatibilityEnabled = false;
//***********************************************************
//Execute the XSLT Transform to generate the XSL-FO output
//***********************************************************
//Render the XSL-FO output from the Razor Template and the View Model
var xslFODoc = this.RenderXslFOContent(templateModel);
//******************************************************************************************
//Execute the Transformation of the XSL-FO source to Binary Pdf via Apache FOP Service...
//******************************************************************************************
var pdfBytes = await _apacheFopHelperClient.RenderXslFOToPdfAsync(xslFODoc).ConfigureAwait(false);
return pdfBytes;
}
//Use ASP.NET Core Razor Template + ApacheFOP.Serverless Rendering Engine; PDF-as-a-service via Azure Functions...
public virtual async Task<byte[]> RenderPdfAsync(MovieSearchResponse templateModel)
{
//Ensure that compatibility Mode is Disabled for proper rendering of our Model
templateModel.FonetCompatibilityEnabled = false;
//***********************************************************
//Execute the Razor View to generate the XSL-FO output
//***********************************************************
var razorViewRenderer = new MvcRazorViewRenderer(this.MvcController);
var renderResult = await razorViewRenderer.RenderViewAsync(this.RazorViewPath, templateModel).ConfigureAwait(false);
//***********************************************************
//OPTIONALLY validate the Output by Loading the XSL-FO output into a fully validated XDocument...
//***********************************************************
//Load the XSL-FO output into a fully validated XDocument.
//NOTE: T