private static FonetDriver GetFonetDriver(XslFOPdfOptions pdfOptions = null) { FonetDriver driver = FonetDriver.Make(); driver.CloseOnExit = false; //Ensure we have a minimal default set of options if they are null. driver.Options = new PdfRendererOptions() { Author = pdfOptions?.Author, Title = pdfOptions?.Title, Subject = pdfOptions?.Subject, EnableModify = pdfOptions?.EnableModify ?? true, EnableAdd = pdfOptions?.EnableAdd ?? true, EnableCopy = pdfOptions?.EnableCopy ?? true, EnablePrinting = pdfOptions?.EnablePrinting ?? true, OwnerPassword = pdfOptions?.OwnerPassword, UserPassword = pdfOptions?.UserPassword, //NOTE: We use Subset font setting so that FONet will create embedded fonts with the precise characters/glyphs that are actually used: // http://fonet.codeplex.com/wikipage?title=Font%20Linking%2c%20Embedding%20and%20Subsetting&referringTitle=Section%204%3a%20Font%20Support FontType = FontType.Subset, Kerning = true }; //Initialize BaseDirectory if defined in our Options if (pdfOptions?.BaseDirectory != null) { driver.BaseDirectory = pdfOptions.BaseDirectory; } return(driver); }
/// <summary> /// Implements the IRazorPdfRenderer interface and delegate the specific logic to the abstract /// methods to simplify the implementations of all inheriting Razor View Renderer implementations. /// NOTE: This method orchestrates all logic to create the view model, execute the view template, /// and render the XSL-FO output, and then convert that XSL-FO output to a valid Pdf /// in one and only place and greatly simplifies all Razor View Renderer implementations to keep /// code very DRY. /// </summary> /// <param name="templateModel"></param> /// <returns></returns> 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 = new XslFOPdfOptions() { Author = Assembly.GetExecutingAssembly()?.GetName()?.Name ?? "PdfTemplating Renderer", Title = $"Xsl-FO Pdf Templating Renderer [{this.GetType().Name}]", Subject = $"Dynamic Xslt Generated Xsl-FO Pdf Document [{DateTime.Now}]", //SET the Base Directory for XslFO Images, Xslt Imports, etc. BaseDirectory = this.XsltFileInfo.Directory, EnableAdd = false, EnableCopy = true, EnableModify = false, EnablePrinting = true, }; //**************************************************************************** //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); }
/// <summary> /// Implements the IRazorPdfRenderer interface and delegate the specific logic to the abstract /// methods to simplify the implementations of all inheriting Razor View Renderers. /// NOTE: This method orchestrates all logic to create the view model, execute the view template, /// and render the XSL-FO output, and then convert that XSL-FO output to a valid Pdf /// in one and only place and greatly simplifies all Razor View Renderers to keep /// code very DRY. /// </summary> /// <param name="templateModel"></param> /// <returns></returns> public virtual byte[] RenderPdf(MovieSearchResponse templateModel) { //*********************************************************** //Execute the Razor View to generate the XSL-FO output //*********************************************************** var razorViewRenderer = new MvcRazorViewRenderer(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 = new XslFOPdfOptions() { Author = Assembly.GetExecutingAssembly()?.GetName()?.Name ?? "PdfTemplating Renderer", Title = $"Xsl-FO Pdf Templating Renderer [{this.GetType().Name}]", Subject = $"Dynamic Razor Template Generated Xsl-FO Pdf Document [{DateTime.Now}]", //SET the Base Directory for XslFO Images, Xslt Imports, etc. //BaseDirectory = this.RazorViewFileInfo.Directory, BaseDirectory = this.RazorViewFileInfo.Directory, EnableAdd = false, EnableCopy = true, EnableModify = false, EnablePrinting = true, }; //**************************************************************************** //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); }
public void LoadXslt(FileInfo xmlSourceFile, FileInfo xslFOXsltSourceFile, XslFOPdfOptions pdfOptions) { XDocument xXmlDoc = null; XDocument xXsltDoc = null; TriggerLoadStart(); try { LogItem("Xml Source Load Starting."); var timer = Stopwatch.StartNew(); xXmlDoc = xmlSourceFile.OpenXDocument(); LogItem("Xml Source Document Load Completed [{0}s].", timer.Elapsed.TotalSeconds); } catch (Exception exc) { throw new ArgumentException("The Xml source file specified could not be read; ensure that the file exists and that you have read access", exc); } try { LogItem("Xslt Source Load Starting."); var timer = Stopwatch.StartNew(); xXsltDoc = xslFOXsltSourceFile.OpenXDocument(); LogItem("Xslt Source Document Load Completed [{0}s].", timer.Elapsed.TotalSeconds); } catch (Exception exc) { throw new ArgumentException("The Xslt source file (to create Xml FO) specified could not be read; ensure that the file exists and that you have read access", exc); } LoadXslt(xXmlDoc, xXsltDoc, pdfOptions); }
/// <summary> /// Helper method to convert the XSL-FO into a valid Pdf /// </summary> /// <param name="xslFODoc"></param> /// <param name="xslFOPdfOptions"></param> /// <returns></returns> protected virtual byte[] RenderXslFOPdfBytes(XDocument xslFODoc, XslFOPdfOptions xslFOPdfOptions) { //*********************************************************** //Render the Xsl-FO results into a Pdf binary output //*********************************************************** var xslFOPdfRenderer = new FONetXslFOPdfRenderer(xslFODoc, xslFOPdfOptions); var pdfBytes = xslFOPdfRenderer.RenderPdfBytes(); return(pdfBytes); }
public void LoadXslFO(FileInfo xslFOSourceFile, XslFOPdfOptions pdfOptions) { XDocument xXslFODoc = null; try { TriggerLoadStart(); xXslFODoc = xslFOSourceFile.OpenXDocument(); } catch (Exception exc) { throw new ArgumentException("The Xml source file specified could not be read; ensure that the file exists and that you have read access", exc); } LoadXslFO(xXslFODoc, pdfOptions); }
/// <summary> /// Helper method to Create the PdfOptions for the XSL-FO Rendering engine to use. /// </summary> /// <returns></returns> protected virtual XslFOPdfOptions CreatePdfOptions() { //Initialize the Pdf rendering options for the XSL-FO Pdf Engine var pdfOptions = new XslFOPdfOptions() { Author = Assembly.GetExecutingAssembly()?.GetName()?.Name ?? "PdfTemplating Renderer", Title = $"Xsl-FO Pdf Templating Renderer [{this.GetType().Name}]", Subject = $"Dynamic Xslt Generated Xsl-FO Pdf Document [{DateTime.Now}]", //SET the Base Directory for XslFO Images, Xslt Imports, etc. BaseDirectory = this.XsltFileInfo.Directory, EnableAdd = false, EnableCopy = true, EnableModify = false, EnablePrinting = true, }; return(pdfOptions); }
public void LoadXslFO(XDocument xXslFODoc, XslFOPdfOptions pdfOptions) { TriggerLoadStart(); FileInfo pdfBinaryFileInfo = GetTempFileHelper(); var xslFORenderedOutput = xXslFODoc.RenderXslFOToPdfFile(pdfBinaryFileInfo, new XslFORenderOptions() { PdfOptions = pdfOptions, RenderErrorHandler = GetFONetErrorHandler(), RenderEventHandler = GetFONetEventHandler() }); TriggerLoadFile(xslFORenderedOutput); //Cleanup Temp File once loaded because Acrobat ActiveX Control no longer needs it //NOTE: Acrobot can browse the file after it is loaded, however Find/Search functionality is broken // so we cannot delete the file pre-maturely. //CleanupTempFileHelper(); }
public void LoadXslt(XDocument xXmlInputDoc, XslTransformEngine xslTransformer, XslFOPdfOptions pdfOptions) { TriggerLoadStart(); //NOTE: We Lock this entire method because it is the Core method for the UI Control and we don't want this Control // to allow primary processing by more than one Thread at a time. Though Background threads are launched // to not block the UI thread, this is not intended to process multiple items at a Time and this // block contains code where critical values are being modified. lock (_threadLock) { ClearLog(); //Initialize Temp File Helper to manage temp files for Transformation into PDF var uiTaskFactory = new TaskFactory(_uiThreadScheduler); LogItem("XslFO Pdf Render Process Starting."); var timerOverall = Stopwatch.StartNew(); //Execute the Work Async, with a Continuation back on the UI Thread when completed. var workerTask = Task.Factory.StartNew <XslFORenderFileOutput>(() => { //*********************************************************** //XsltEngine is already passed in and Compiled for performance //Execute the Xslt Transformation //*********************************************************** LogItem("Xslt Execution Starting."); var timer = Stopwatch.StartNew(); var xXslFOResultsDoc = xslTransformer.TransformToXDocument(xXmlInputDoc); LogItem("Xslt Execution Completed in [{0}] seconds.", timer.Elapsed.TotalSeconds); //*********************************************************** //Render the XslFO results into a Pdf //*********************************************************** //return xXmlInputDoc.TransformToPdfFile(xslTransformer, tempPdfFileInfo, pdfOptions, _fnFonetEventHandler, _fnFonetEventHandler, _fnXsltEventHandler); LogItem("Pdf Render Starting."); timer.Restart(); var XslFORenderedOutput = xXslFOResultsDoc.RenderXslFOToPdfFile(GetTempFileHelper(), new XslFORenderOptions() { PdfOptions = pdfOptions, RenderErrorHandler = GetFONetErrorHandler(), RenderEventHandler = GetFONetEventHandler() }); LogItem("Pdf Render Completed in [{0}] seconds.", timer.Elapsed.TotalSeconds); //*********************************************************** //Finally Return the Renderd Output from the the Background //Thread so that the results can be processed on the UI! //*********************************************************** return(XslFORenderedOutput); }).ContinueWith((workTask) => { //NOTE: Since this is the Followup Thread executing we must check to see if the Background Thread Faulted and handle it correctly. //This allows us to process the Exception back on the UI Thread instead of loosing it on the background thread. if (workTask.IsFaulted) { String renderSource = String.Empty; var innerException = workTask.Exception.InnerException; if (innerException is XslTransformEngineException) { renderSource = innerException.As <XslTransformEngineException>().XsltOutput; } else if (innerException is XslFORenderException) { renderSource = innerException.As <XslFORenderException>().RenderSource; } RaiseViewerError(new XslFOViewerEventArgs("Exception Occurred Processing the Transformer. Inner Exception Details: {0}".FormatArgs(workTask.Exception.GetMessages()), renderSource)); } else { //Halt and Wait for the workerTask's result! //NOTE: This DOES NOT Halt our UI, because this is only invoked within our ContinueWith continuation of the Parallel Task // which will handle the coordination and usher our results back to the UI Thread via the ThreadScheduler parameter below! LogItem("XslFO Pdf Render Process Completed in [{0}] seconds.", timerOverall.Elapsed.TotalSeconds); TriggerLoadFile(workTask.Result); } //Cleanup Temp File once loaded because Acrobat ActiveX Control no longer needs it //NOTE: Acrobot can browse the file after it is loaded, however Find/Search functionality is broken // so we cannot delete the file pre-maturely. //CleanupTempFileHelper(); }, _uiThreadScheduler); } }