3

I'm working on a UWP app and as one of the requirements I need to generate a PDF file dynamically.

There are a few contraints / requirements that I need to concider:

  • Need an ability to generate PDF from the UWP app directly / offline scenario
  • Potentially need an ability to generate the report on the server - ideally from the same source template
  • Report needs to be somewhat dynamic (i.e. not compiled into the app it self and format editable without recompilation of the app)
  • Ideally - not depend on a closed source propetiary library / component

I have had couple of ideas on how to approach this:

  1. Have a XAML page and convert it PDF by printing that XAML view as a PDF through a hidden print dialog - limited by the fact the XAML will need to be compiled into the app + would probably be imposisble to use the same approach to generate reports on the server side.
  2. Do something similar with an WebView and HTML - but that will require JavaScript logic to be executed - adn I'm not sure if it is possible in UWP app.

Has anyone achieved something similar in the past and if so - what approach have you taken?

Nick Goloborodko
  • 2,883
  • 3
  • 21
  • 38

1 Answers1

4

Currently, there are many third party paid packages for generating PDF in UWP, such as Syncfusion and XFinium. For free libraries like PDFSharp that are not available in UWP. Since you don't want a paid one, you may consider to create classical application with free libraries and then create an AppService to handle it. For more details please reference AppServiceBridgeSample.

Have a XAML page and convert it PDF by printing

Generate the PDF by printing feature can work well. But for your requirements "through a hidden print dialog" is not possible, print UI cannot be hidden to print.

Do something similar with an WebView and HTML

The open jsPDF library can help you generate HTML to PDF by JavaScript. And you can get the PDF result return by InvokeScriptAsync from WebView. For example:

JavaScript

<html>
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.4/jspdf.debug.js"></script> 
    <script type='text/javascript'> 
        function print() {
            var doc = new jsPDF()
            doc.text('Hello world!', 10, 10);
            doc.circle(50, 50, 50);
            var pdfresult = doc.output(); 
            document.getElementById('myDiv').innerText = pdfresult; 
            //doc.save('a4.pdf');
            return pdfresult;
        }
    </script>
</head>
<body>
    <div id='myDiv'>Hello</div> 
</body>
</html>

WebView

Webview.Navigate(new Uri("ms-appx-web:///Assets/test.html"));
string pdfresult = await Webview.InvokeScriptAsync("eval", new string[] { "print()" });
StorageFile pdf = await ApplicationData.Current.LocalFolder.CreateFileAsync("test.pdf");
await FileIO.WriteTextAsync(pdf, pdfresult);

After all, you can consider Write the PDF file format yourself. Here is a document for windows phone but you may still reference.

Sunteen Wu
  • 10,509
  • 1
  • 10
  • 21
  • what if we want to insert an imagefile in that pdf as well? – Muhammad Touseef Dec 21 '18 at 12:31
  • Ended up going with Syncfusion components. – Nick Goloborodko May 27 '19 at 02:50
  • @SunteenWu Your code seems promising but it creates `test.pdf` of size `0kb` in local folder. I even added lots of test to the `test.html` file to make it of a size 8kb. But the resulting `test.pdf` file is still empty (`0kb` size). – nam Jul 02 '20 at 04:44
  • I don't know when support was added, but there is a [PdfSharpCore Nuget package](https://www.nuget.org/packages/PdfSharpCore). It works for me with no bridge app necessary. – Ben Jasperson Jun 08 '23 at 11:23