/// <summary> /// Helper method to render the XSL FO output /// This can be overridden by implementing classes to customize this behaviour as needed. /// </summary> /// <param name="viewModel"></param> /// <returns></returns> protected virtual XDocument RenderXslFOXml(TViewModel viewModel) { //*********************************************************** //Execute the XSLT Tempalte to generate the XSL-FO output //*********************************************************** //Convert the Model to Xml var xmlDataDoc = ConvertModelToXDocument(viewModel).RemoveNamespaces(); //Load the Xslt Report Template to process the Xml model data //Load the Local FileInfo for the View Report so that we can use it's Directory // as the BaseDirectory for resolving locally referenced files/images within the XSL-FO processing. var xsltFileInfo = this.XsltFileInfo; var xsltDoc = XDocument.Load(xsltFileInfo.FullName); //Create the Xslt Transform Engine helper with Custom Extension methods on XDocument //NOTE: We use the enhanced Xml Url Resolver to support importing Xslt Common libraries var xsltTransformOptions = this.CreateXsltTransformEngineOptions(); XslTransformEngine xslTransformer = xsltDoc.CreateXslTransformEngine(xsltTransformOptions); //Execute the Xslt Transformation to generate Xsl-FO Source //NOTE: This template must generate valid Xsl-FO output -- via the well-formed xml via XDocument return value -- to be rendered as a Pdf Binary! var xslFODoc = xslTransformer.TransformToXDocument(xmlDataDoc); return(xslFODoc); }
/// <summary> /// Transforms an XDocument using the specified Compiled Xslt and returns an XDocument with the results parsed. /// Note: This assumes that the Results are Valid Xml or an exception will occur. /// </summary> /// <param name="xInputDocument">The XDocument to Transform.</param> /// <param name="xslTransformer">The Compiled Xsl Transform to convert.</param> /// <param name="xXsltParams">The Arguments List to inject into the Xsl Transform to convert.</param> /// <returns>The Transform Output in Text format supporting any output from transformation (text, html, xml, etc.).</returns> public static XDocument TransformToXDocument(this XDocument xInputDocument, XslTransformEngine xslTransformer, XsltArgumentList xXsltParams = null) { return(xslTransformer.TransformToXDocument(xInputDocument, xXsltParams)); }
/// <summary> /// Convert the current XDocument object into a Compiled Xsl Transformer with the specified XmlResovlver to use when Loading/Compiling the Xslt. /// Errors will be thrown if the input Xml is not valid for an Xslt. /// This allows increaed performance because the caller can keep a reference to the fully compiled Transformer, after all /// parsing/imports/includes etc., have been processed. /// </summary> /// <param name="xXsltDocument"></param> /// <param name="xsltOptions"></param> /// <returns></returns> public static XslTransformEngine CreateXslTransformEngine(this XDocument xXsltDocument, XslTransformEngineOptions xsltOptions = null) { XslTransformEngine transformer = new XslTransformEngine(xXsltDocument, xsltOptions); return(transformer); }
/// <summary> /// Transforms an XDocument using the specified Compiled Xslt and returns a Stream object contains the results. /// </summary> /// <param name="xInputDocument">The XDocument to Transform.</param> /// <param name="xslTransformer">The Compiled Xsl Transform to convert.</param> /// <param name="xXsltParams">The Arguments List to inject into the Xsl Transform to convert.</param> /// <returns>The Transform Output in Text format supporting any output from transformation (text, html, xml, etc.).</returns> public static MemoryStream TransformToStream(this XDocument xInputDocument, XslTransformEngine xslTransformer, XsltArgumentList xXsltParams = null) { return(xslTransformer.TransformToStream(xInputDocument, xXsltParams)); }
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); } }