Articles in this section
Category / Section

How to convert XAML to PDF in Xamarin using C#?

4 mins read

Syncfusion Essential PDF is a Xamarin PDF library used to create, read, and edit PDF documents. Using this library, you can convert XAML to PDF in the Xamarin platform.

Steps to convert XAML to PDF programmatically:

  1. Create a new C# Xamarin.Forms application project. Create xamarin forms application project

Project naming for xamarin platform

 

  1. Select a project template and required platforms to deploy the application. In this application, to share the portable assemblies across multiple platforms, the .NET Standard code sharing strategy has been selected. For more details about code sharing, Click here.
    Note:

    If .NET Standard is not available in the code sharing strategy, the Portable Class Library (PCL) can be selected.

Xamarin blank app create

  1. Install the Syncfusion.Xamarin.Pdf NuGet packages as a reference to your Portable/NetStandard project from nuget.org.

Syncfusion.Xamarin.Pdf nuget image

  1. Add new forms of XAML page in the portable project if there is no XAML page, it is defined in the App class. Otherwise, proceed to the next step.
  1. To add the new XAML page, right-click the project and select Add ->New Item and add a Forms XAML page from the list, and name it as MainXamlPage.
  2. In the App class of the portable project (App.cs), replace the existing constructor of the App class with the following code sample, which invokes the MainXamlPage.
    public App()
    {
          //The root page of your application.
          MainPage = new MainXamlPage();
    }
    
  1. In the MainXamlPage.xaml, add a new button with the heading as follows.
    <StackLayout>
                <Label x:Name="SampleTitle" Text="XAML to PDF"
                             FontSize="Large"
                             HorizontalOptions="Center"
                             VerticalOptions="Center">
                </Label>
                <Label></Label>
                <Label x:Name="Description" Text="This sample demonstrates how to convert XAML page to PDF document."
                             FontSize="Medium"
                             HorizontalOptions="Center"
                             VerticalOptions="Center">
                </Label>
                <Label></Label>
                <Button x:Name="btnGenerate"  Text="Generate PDF"
                               HorizontalOptions="Center"
                               VerticalOptions="Center"
                               Clicked="OnButtonClicked" />
    </StackLayout>
    
  1. Download the helper files from this link and add them to the mentioned project. These helper files allow you to capture the XAML file as an image and return the image stream. Also, it helps to save the PDF stream as a physical file and open the file for viewing.

Project

File Name

Summary

Portable project

ISave.cs

Represents the base interface for save operation.

iOS Project

SaveIOS.cs

Saves implementation and captures the XAML page as an image for iOS device.

PreviewControllerDS.cs

QLPreviewItemFileSystem.cs

Helper class for viewing the PDF file on iOS device.

Android project

SaveAndroid.cs

Saves implementation and captures the XAML page as an image for Android device.

UWP project

SaveWindows.cs

Saves implementation and captures the XAML page as an image for the UWP device.

             

Note:

Introduced a new runtime permission model for the Android SDK version 23 and above. So, include the following code for enabling the Android file provider to save and view the generated PDF document.

  • Create a new XML file with the name of the provider_paths.xml under the Android project Resources folder and add the following code to it.

Eg: Resources/xml/provider_paths.xml

<?xml version="1.0" encoding="UTF-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <external-path name="external_files" path="."/>
</paths>

 

  • Add the following code to the AndroidManifest.xml file located under Properties/AndroidManifest.xml.
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.mycompany.pdfxamarinsample" android:installLocation="auto">
     <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="30" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">  
     </uses-permission>
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.INTERNET" />
     <application android:label=" PDFXamarinSample.Android" android:requestLegacyExternalStorage="true">
      <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true">
       <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
      </provider>
     </application>
    </manifest>
    

 

             Please include the changes if you deploy the application in Android 11:

  • Enabled the androidLegacyExtranalStorage in the AndroidManifest.xml file.
    <application android:label=" PDFXamarinSample.Android" android:requestLegacyExternalStorage="true"> 
    

 

  • User permission for read or write external storage.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">              
    </uses-permission>  
          <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
    

 

 

  • Replaced the following code to get the external storage download folder in the SaveAndroid.cs file.
    if (Android.OS.Environment.IsExternalStorageEmulated)  
    {  
    root = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;              
    }  
    

 

  1. Add the following code for capturing the XAML file as an image in the Xamarin.Android project.
    public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
    {
             var activity1 = Forms.Context as Activity;
     
             var view = activity1.Window.DecorView;
             view.DrawingCacheEnabled = true;
     
             Bitmap bitmap = view.GetDrawingCache(true);
     
             byte[] bitmapData;
     
             using (var stream = new MemoryStream())
             {
                    bitmap.Compress(Bitmap.CompressFormat.Jpeg, 0, stream);
                    bitmapData = stream.ToArray();
             }
     
             return bitmapData;
     }
    

 

  1. Add the following code for capturing the XAML file as an image in the Xamarin.iOS project.
    public async System.Threading.Tasks.Task<byte[]> CaptureAsync()
    {
            var view = UIApplication.SharedApplication.KeyWindow.RootViewController.View;
     
            UIGraphics.BeginImageContext(view.Frame.Size);
            view.DrawViewHierarchy(view.Frame, true);
            var image = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();
     
            using (var imageData = image.AsJPEG(100))
            {
                  var bytes = new byte[imageData.Length];
                  System.Runtime.InteropServices.Marshal.Copy(imageData.Bytes, bytes, 0, Convert.ToInt32(imageData.Length));
                  return bytes;
            }
    }
    
  1. Add the following code for capturing the XAML file as an image in the Xamarin.UWP project.
    Public async Task<byte[]> CaptureAsync()
    {
            RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();            
            await renderTargetBitmap.RenderAsync(Window.Current.Content);                  
            var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
            var pixels = pixelBuffer.ToArray();          
            var displayInformation = DisplayInformation.GetForCurrentView();
            var stream = new InMemoryRandomAccessStream();
            var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
            encoder.SetPixelData(BitmapPixelFormat.Bgra8,
    BitmapAlphaMode.Premultiplied,
    (uint)renderTargetBitmap.PixelWidth,
    (uint)renderTargetBitmap.PixelHeight, displayInformation.RawDpiX, displayInformation.RawDpiY,  pixels);
            await encoder.FlushAsync();
            stream.Seek(0);
            var readStram = stream.AsStreamForRead();
            var bytes = new byte[readStram.Length];
            readStram.Read(bytes, 0, bytes.Length);
            return bytes;
    }
    
  1. Include the following namespace in the MainXamlPage.xaml.cs file.
    using Syncfusion.Pdf;
    using Syncfusion.Pdf.Graphics;
    
  1. Include the following code samples in the click event of the button in the MainXamlPage.xaml.cs, which converts the “MainPage.Xaml” file to PDF and save it in a stream.
    //Create a new PDF document.
    PdfDocument document = new PdfDocument();
     
    //Add page to the PDF document.
    PdfPage page = document.Pages.Add();
    //Create graphics instance.
    PdfGraphics graphics = page.Graphics;
    Stream imageStream = null;
     
    //Capture the XAML page as an image and return the image in a memory stream.
    imageStream = new MemoryStream(DependencyService.Get<ISave>().CaptureAsync().Result);
     
    //Load the image in the PdfBitmap.
    PdfBitmap image = new PdfBitmap(imageStream);
     
    //Draw the image on the page.
    graphics.DrawImage(image, 0, 0, page.GetClientSize().Width, page.GetClientSize().Height);
     
    //Save the document into a memory stream.
    MemoryStream stream = new MemoryStream();
    document.Save(stream);
     
    stream.Position = 0;
       
    //Save the stream as a file in the device and invoke it for viewing.
    Xamarin.Forms.DependencyService.Get<ISave>().SaveAndView("Output.pdf", "application/pdf", stream);
    
  1. Compile and execute the application.

 

 

By executing the sample, you will get the output document as follows.

Output

Download the complete work sample from PDFXamarinSample.zip.

 

Take a moment to peruse the documentation, where you will find other options like inserting an image in a new or existing PDF document, replacing an image in an existing document, or paginating an image in a PDF document.

 

Click here to explore the rich set of Syncfusion Essential PDF features.

 

Note:

Starting with v16.2.0.x, if you reference Syncfusion assemblies from the trial setup or from the NuGet feed, include a license key in your projects. Refer to the link to learn about generating and registering the Syncfusion license key in your application to use the components without a trail message.

 

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments
Please sign in to leave a comment
Access denied
Access denied