Converting XAML to PDF and paginating it.

Hello,

I'm trying to add image pagination to an image via XAML conversion to PDF in a UWP project within Xamarin.Forms. So far it only renders the top half of the page, but not the rest. The grid I am trying to convert lies within a ScrollView. Is there a way to capture the entire ScrollView to convert it to PDF?

Below is the code for the download button:
```
private async void DownloadPdfBtn_OnClicked(object sender, EventArgs e)
        {
            try
            {
                var filename = "SurveyReport_" + ((App)Application.Current).CurrentUser.UserName + "_" + DateTime.UtcNow.ToString("MMddyy") + ".pdf";
                // Init Memory Stream.
                var stream = new MemoryStream();

                //Create a new PDF document
                using (var document = new PdfDocument())
                {
                    // Captures the XAML page as image and returns the image in memory stream.
                    var byteData = await DependencyService.Get<IExportPdf>().CaptureAsync();
                    Stream imageStream = new MemoryStream(byteData);

                    // Load the image in PdfBitmap.
                    var pdfBitmapImage = new PdfBitmap(imageStream);

                    // Set layout to break across pages.
                    var pdfLayoutFormat = new PdfLayoutFormat
                    {
                        Break = PdfLayoutBreakType.FitPage,
                        Layout = PdfLayoutType.Paginate
                    };

                    // Set the page size.
                    document.PageSettings.Margins.All = 0;
                    document.PageSettings.Orientation = PdfPageOrientation.Portrait;
                    document.PageSettings.Size = new SizeF(pdfBitmapImage.Width, pdfBitmapImage.Height);

                    var page = document.Pages.Add();

                    // Draw the image to the page.
                    pdfBitmapImage.Draw(page, 0, 0, pdfLayoutFormat);                  

                    // Save the document into memory stream.
                    document.Save(stream);
                }

                stream.Position = 0;

                // Save the stream as a file in the device and invoke it for viewing.
                await Xamarin.Forms.DependencyService.Get<IExportPdf>().Save(filename, "application/pdf", stream);
            }
            catch (Exception ex)
            {
                DisplayErrorAlert("DownloadPdfBtn_OnClicked", ex.Message);
            }
        }
```
And here is the dependency service class for the export:
```
public class ExportPdf : IExportPdf
    {
        public async Task<byte[]> CaptureAsync()
        {
            var renderTargetBitmap = new RenderTargetBitmap();
            await renderTargetBitmap.RenderAsync(Window.Current.Content);

            var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
            var pixels = pixelBuffer.ToArray();

            var displayInformation = DisplayInformation.GetForCurrentView().LogicalDpi;

            var stream = new InMemoryRandomAccessStream();

            var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
            encoder.SetPixelData(
                BitmapPixelFormat.Bgra8, 
                BitmapAlphaMode.Ignore, 
                (uint)renderTargetBitmap.PixelWidth, 
                (uint)renderTargetBitmap.PixelHeight, 
                displayInformation,
                displayInformation, 
                pixels);
            await encoder.FlushAsync();

            stream.Seek(0);
            var readStream = stream.AsStreamForRead();
            var bytes = new byte[readStream.Length];
            await readStream.ReadAsync(bytes, 0, bytes.Length);

            return bytes;
        }

        public async Task Save(string filename, string contentType, MemoryStream stream)
        {
            if (Device.Idiom != TargetIdiom.Desktop)
            {
                var local = ApplicationData.Current.LocalFolder;
                var outFile = await local.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
                using (var outStream = await outFile.OpenStreamForWriteAsync()) { await outStream.WriteAsync(stream.ToArray(), 0, (int)stream.Length); }

                if (contentType != "application/html") await Windows.System.Launcher.LaunchFileAsync(outFile);
            }
            else
            {
                StorageFile storageFile = null;
                var savePicker = new FileSavePicker
                {
                    SuggestedStartLocation = PickerLocationId.Desktop,
                    SuggestedFileName = filename
                };
                switch (contentType)
                {
                    case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
                        savePicker.FileTypeChoices.Add("PowerPoint Presentation", new List<string> { ".pptx" });

                        break;

                    case "application/msexcel":
                        savePicker.FileTypeChoices.Add("Excel Files", new List<string> { ".xlsx" });

                        break;

                    case "application/msword":
                        savePicker.FileTypeChoices.Add("Word Document", new List<string> { ".docx" });

                        break;

                    case "application/pdf":
                        savePicker.FileTypeChoices.Add("Adobe PDF Document", new List<string> { ".pdf" });

                        break;
                    case "application/html":
                        savePicker.FileTypeChoices.Add("HTML Files", new List<string> { ".html" });

                        break;
                }

                storageFile = await savePicker.PickSaveFileAsync();

                using (var outStream = await storageFile.OpenStreamForWriteAsync())
                {
                    await outStream.WriteAsync(stream.ToArray(), 0, (int)stream.Length);
                    await outStream.FlushAsync();
                    outStream.Dispose();
                }

                stream.Flush();
                stream.Dispose();
                await Windows.System.Launcher.LaunchFileAsync(storageFile);
            }
        }
    }
```


Attachment: codeInTextFile_cca5ca5d.7z

5 Replies 1 reply marked as answer

CM Chinnu Muniyappan Syncfusion Team May 26, 2021 03:46 PM UTC

Hi Bryan, 
 
Thank you for contacting Syncfusion support. 
 
Currently, we are analyzing to capture the entire ScrollView content to image and draw it to the PDF document. We will update you on the further details on 28th May 2021. 
 
Regards,  
Chinnu M 



BR Bryan May 26, 2021 03:57 PM UTC

Hi Chinnu,

Thank you so much, I greatly appreciate it! Please let me know if you need any more details.


GK Gowthamraj Kumar Syncfusion Team May 28, 2021 11:43 AM UTC

Hi Bryan, 
 
We have tried to export the entire ScrollView to image in Xamarin UWP platform. But it capture only the visible area of the screen and it does not cover the entire ScrollView. Without capturing the entire screen, we could not proceed to generate a PDF document. 
 
Regards, 
Gowthamraj K 



BR Bryan May 28, 2021 10:23 PM UTC

Hi Gowthamraj, 

Thank you for looking into this for me. Does this mean I should use another means of displaying the report data? Like a list view? Or is there another solution to this I could try?

Thank you,
     Bryan W


GK Gowthamraj Kumar Syncfusion Team May 31, 2021 11:42 AM UTC

Hi Bryan, 
 
Thank you for your update. 
 
No. If you are trying with list view in UWP platforms, it will capture only the visible area of the screen and it does not cover the entire list view. You can get the same output result which you are getting from the KB documentation sample. In this sample, we capture the screenshot of the screen and then add it into PDF document. We could not able to achieve this requirement with list view too. 
 
Regards, 
Gowthamraj K 


Marked as answer
Loader.
Up arrow icon