Some test text!

menu

C# XAML to PDF converter

Sample C# code for using PDFTron SDK to dynamically generate PDF or XPS directly from a FlowDocument, XAML, or WPF. Converting XAML/FlowDocument to PDF is not only easy, but is also very flexible in terms of how content is paginated and flowed into a fixed document such as PDF or XPS. Learn more about our C# PDF Library and PDF Conversion Library.

Get StartedSamplesDownload

To run this sample, get started with a free trial of PDFTron SDK.

//
// Copyright (c) 2001-2020 by PDFTron Systems Inc. All Rights Reserved.
//
using System;
using System.IO;
using System.Windows;
using System.Windows.Documents; 
using System.Windows.Media; 
using System.Xml;
using System.Windows.Controls;
using System.Windows.Markup;

using pdftron;
using pdftron.Common;
using pdftron.SDF;
using pdftron.PDF;
using pdftron.Xaml;

namespace Xaml2PdfTestCS
{
    /// <summary>
    /// This sample shows how use pdftron.Xaml.Convert to convert .xaml files 
    /// into PDF documents with control over headers and footers, main body placement,
    /// and column widths.  Pagination is controlled by specifying the page size and 
    /// body size (margins) and all pages are appended to a PDFDoc which can then be
    /// further manipulated using the PDFNet API.
    /// 
    /// Three types of XAML objects are convertible using pdftron.Xaml.Convert:
    /// - FlowDocument's which describe content that is reflowable from page to page
    /// - FixedDocument's which describe content that has been placed on a fixed page
    /// - Blocks such as Canvas, RichTextBox, Section etc which can be wrapped or inserted 
    ///     directly into a FlowDocument
    ///     
    /// This sample has three example uses of pdftron.Xaml.Convert:
    /// - CreateXamlFlowDocumentFromCanvas() demonstrates how to read in a Canvas
    ///   described in a .xaml file and convert it to PDF.
    /// - CreateXamlTableAndConvert() demonstrates how to programmatically create
    ///   a FlowDocument with a table, and then convert it to PDF as a single column
    ///   document.
    /// - ConvertXamlFlowDocumentsFromFiles() demonstrates how to define functions to
    ///   create page headers and footers.
    ///   
    /// Limitations:
    /// Requires Microsoft .NET 3.5
    /// 
    /// There are many Xaml classes that cannot be added to FlowDocument or FixedDocuments and
    /// therefore this sample converter cannot convert Page, Window or Frame objects.
    /// </summary>
    class Program
    {
        private static pdftron.PDFNetLoader pdfNetLoader = pdftron.PDFNetLoader.Instance();
		static Program() {}
        
        // Relative path to the folder containing test files.
        const string inputPath = "../../TestFiles/";
        const string outputPath = "../../../../TestFiles/Output/";
        
        /// <summary>
        /// Entry point for the sample.
        /// </summary>
        /// <param name="args">command line arguments (ignored)</param>
        [STAThread]
        static void Main(string[] args)
        {
            PDFNet.Initialize();
            try
            {
                CreateXamlFlowDocumentFromCanvas();
                CreateXamlTableAndConvert();
                ConvertXamlFlowDocumentsFromFiles();
            }
            catch (PDFNetException e)
            {
                Console.WriteLine(e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }

        /// <summary>
        /// Demonstrate how to load a Xaml file containing a Canvas and convert
        /// it to PDF.
        /// </summary>
        static public void CreateXamlFlowDocumentFromCanvas()
        {
            // load the Xaml file containing the canvas
            string rawXamlText = "";
            using(StreamReader streamReader = File.OpenText(inputPath + "xamlshield.xaml"))
            {
                rawXamlText = streamReader.ReadToEnd();
            }
            StringReader stringReader = new StringReader(rawXamlText);
            XmlReader xmlReader = XmlReader.Create(stringReader);
            Canvas canvasImage = (Canvas)XamlReader.Load(xmlReader);

            // Now convert to PDF
            using (PDFDoc pdfdoc = new PDFDoc())
			{
				pdftron.Xaml.Convert.ToPdf(pdfdoc, canvasImage);
				string outputFileName = outputPath + "xamlshield.pdf";
				pdfdoc.Save(outputFileName, SDFDoc.SaveOptions.e_linearized);

				Console.WriteLine("Wrote " + outputFileName);
				Console.WriteLine("Done.");
			}
        }

        /// <summary>
        /// Demonstrate how to create a Xaml table and convert it to 
        /// PDF.  Also demonstrates how to use the ConverterOptions.NumColumns
        /// setting to draw the table across the page, rather than across
        /// the left column of a two column page.
        /// </summary>
        static public void CreateXamlTableAndConvert()
        {
            // from MSDN SDK Sample TableCsharpSample
            FlowDocument flowDoc = new FlowDocument();

            pdftron.Xaml.ConverterOptions options = new ConverterOptions();
            options.NumColumns = 1;

            // Create the Table...
            Table table1 = new Table();
            // ...and add it as a content element of the TextFlow.
            flowDoc.Blocks.Add(table1);
            // tf1.ContentStart.InsertTextElement(table1);

            // Set some global formatting properties for the table.
            table1.CellSpacing = 10;
            table1.Background = Brushes.White;

            // Create 6 columns and add them to the table's Columns collection.
            int numberOfColumns = 6;
            for (int x = 0; x < numberOfColumns; x++) table1.Columns.Add(new TableColumn());

            // Set alternating background colors for the middle colums.
            table1.Columns[1].Background =
                table1.Columns[3].Background =
                Brushes.LightSteelBlue;
            table1.Columns[2].Background =
                table1.Columns[4].Background =
                Brushes.Beige;

            // Create and add an empty TableRowGroup to hold the table's Rows.
            table1.RowGroups.Add(new TableRowGroup());

            // Add the first (title) row.
            table1.RowGroups[0].Rows.Add(new TableRow());

            // Alias the current working row for easy reference.
            TableRow currentRow = table1.RowGroups[0].Rows[0];

            // Global formatting for the title row.
            currentRow.Background = Brushes.Silver;
            currentRow.FontSize = 40;
            currentRow.FontWeight = System.Windows.FontWeights.Bold;

            // Add the header row with content, 
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("2004 Sales Project"))));
            // and set the row to span all 6 columns.
            currentRow.Cells[0].ColumnSpan = 6;

            // Add the second (header) row.
            table1.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table1.RowGroups[0].Rows[1];

            // Global formatting for the header row.
            currentRow.FontSize = 18;
            currentRow.FontWeight = FontWeights.Bold;

            // Add cells with content to the second row.
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Product"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 1"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 2"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 3"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Quarter 4"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("TOTAL"))));

            table1.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table1.RowGroups[0].Rows[2];

            // Global formatting for the row.
            currentRow.FontSize = 12;
            currentRow.FontWeight = FontWeights.Normal;

            // Add cells with content to the third row.
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Widgets"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$50,000"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$55,000"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$60,000"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$65,000"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$230,000"))));

            // Bold the first cell.
            currentRow.Cells[0].FontWeight = FontWeights.Bold;

            // Add the fourth row.
            table1.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table1.RowGroups[0].Rows[3];

            // Global formatting for the row.
            currentRow.FontSize = 12;
            currentRow.FontWeight = FontWeights.Normal;

            // Add cells with content to the third row.
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Wickets"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$100,000"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$120,000"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$160,000"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$200,000"))));
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("$580,000"))));

            // Bold the first cell.
            currentRow.Cells[0].FontWeight = FontWeights.Bold;

            table1.RowGroups[0].Rows.Add(new TableRow());
            currentRow = table1.RowGroups[0].Rows[4];

            // Global formatting for the footer row.
            currentRow.Background = Brushes.LightGray;
            currentRow.FontSize = 18;
            currentRow.FontWeight = System.Windows.FontWeights.Normal;

            // Add the header row with content, 
            currentRow.Cells.Add(new TableCell(new Paragraph(new Run("Projected 2004 Revenue: $810,000"))));
            // and set the row to span all 6 columns.
            currentRow.Cells[0].ColumnSpan = 6;

            // The PDFDoc to put the converted .xaml document into
            using (PDFDoc pdfdoc = new PDFDoc())
			{
				pdftron.Xaml.Convert.ToPdf(pdfdoc, flowDoc, options );
				string outputFileName = outputPath + "CreateXamlTableAndConvert.pdf";
				pdfdoc.Save(outputFileName, SDFDoc.SaveOptions.e_linearized);

				Console.WriteLine("Wrote " + outputFileName);
				Console.WriteLine("Done.");
			}
        }

        /// <summary>
        /// Demonstrate how to convert Xaml files directly from .xaml to .pdf
        /// </summary>
        static public void ConvertXamlFlowDocumentsFromFiles()
        {
            string[] inputFileNames = new string[] {"BobWatson.xaml",
                                         "chocolate.xaml",
                                         "FlowDocumentFormats.xaml",
                                         "FlowDocumentSample1.xaml",
                                         "FlowDocumentSample2.xaml",
                                         "FlowDocumentSample3.xaml",
                                         "MarkusEgger.xaml",
                                         "MarkusEgger-withImageReference.xaml",
                                         "RichTextBox.xaml",
                                         "ThreeRectangles.xaml",
                                         "WPFNotepad-1.xaml"};

            foreach( string inputFileName in inputFileNames)
            {
                try
                {
                    // The PDFDoc to put the converted .xaml document into
                    using (PDFDoc pdfdoc = new PDFDoc())
					{

						ConverterOptions options = new ConverterOptions();
						options.HeaderFunc = new ConverterOptions.DrawHeaderFooter(MyDrawHeader);
						options.FooterFunc = new ConverterOptions.DrawHeaderFooter(MyDrawFooter);

						pdftron.Xaml.Convert.ToPdf(pdfdoc, inputPath + inputFileName, options);
						
						// output the PDFDoc:
						string outputFileName = inputFileName;
						outputFileName = outputFileName.Remove(outputFileName.LastIndexOf('.')) + ".pdf";
						outputFileName = outputPath + outputFileName;
						pdfdoc.Save(outputFileName, SDFDoc.SaveOptions.e_linearized);

						Console.WriteLine("Wrote " + outputFileName);
						Console.WriteLine("Done.");
					}
                }
                catch (PDFNetException e)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine("For file " + inputFileName);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine("For file " + inputFileName);
                }
            }
        }

        /// <summary>
        /// This variable hold the typeface resource used by the header and footer.
        /// Any resource that you use in the header and footer delegates must persist 
        /// until the document is serialized.
        /// </summary>
        static Typeface typeface = null;

        /// <summary>
        /// Example Header delegate for ConverterOptions, used in ConvertXamlFlowDocumentsFromFiles()
        /// </summary>
        static public void MyDrawHeader(DrawingContext context, pdftron.PDF.Rect bounds,
                                        pdftron.PDF.Rect bodyBounds, Size pageSize, int pageNumber)
        {
            // any resources that you use in the header and footer delegates must persist until the 
            // document is serialized
            if (typeface == null)
            {
                typeface = new Typeface("Comic Sans MS");
            }

            //12 point text for header page number
            FormattedText text = new FormattedText("Page " + (pageNumber + 1),
                System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                typeface, 12, Brushes.Black);
            // the translation applied to the page put the origin at the top left corner of the 
            // body rectangle.  So negative y values move us out of the body into the top margin
            context.DrawText(text, new System.Windows.Point(0, -bounds.y2));
        }

        /// <summary>
        /// Example Footer delegate for ConverterOptions, used in ConvertXamlFlowDocumentsFromFiles()
        /// </summary>
        static public void MyDrawFooter(DrawingContext context, pdftron.PDF.Rect bounds,
                                        pdftron.PDF.Rect bodyBounds, Size pageSize, int pageNumber)
        {
            // any resources that you use in the header and footer delegates must persist until the 
            // document is serialized
            if (typeface == null)
            {
                typeface = new Typeface("Comic Sans MS");
            }

            //8 point text for footer in DarkGreen
            FormattedText text = new FormattedText("This is the footer for page " + (pageNumber + 1),
                System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                typeface, 8, Brushes.DarkGreen);

            // The translation applied to the page puts the origin at the top left corner of the 
            // body rectangle, adjust.
            context.DrawText(text, new System.Windows.Point(0, bounds.y1 - bodyBounds.y1));
        }

    }
}
close

Free Trial

Get unlimited trial usage of PDFTron SDK to bring accurate, reliable, and fast document processing capabilities to any application or workflow.

Select a platform to get started with your free trial.

Unlimited usage. No email address required.

Join our upcoming webinar to learn about how to collaborate on videos frame by frame directly in your browser

Save your seat
close