Some test text!
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 Started Samples DownloadTo run this sample, get started with a free trial of Apryse SDK.
//
// Copyright (c) 2001-2023 by Apryse Software 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(PDFTronLicense.Key);
try
{
CreateXamlFlowDocumentFromCanvas();
CreateXamlTableAndConvert();
ConvertXamlFlowDocumentsFromFiles();
}
catch (PDFNetException e)
{
Console.WriteLine(e.Message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
PDFNet.Terminate();
}
/// <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));
}
}
}