Besides viewing PDF files from your
.NET MAUI application, it turns out that you, dear viewer, are also
interested in generating PDF files from that same .NET MAUI
application. So let's explore that in this video. In an earlier video, I've already
shown you how to build your own free custom PDF viewer inside of your .NET
MAUI app that works on Windows, macOS, iOS and Android. It was actually pretty simple, with
the exception of Android. You can just get a webview in there, load your PDF
file in that and it will show up nicely. Built in PDF support.
For Android, we had to use a custom JavaScript library. Well,
not custom. It's out there; PDF.js. Just plug that inside
of your .NET MAUI application and load your PDF in that and it will
again show up nicely. Free option. Also, other options are
available through control suites third parties if you have no clue what
I'm talking about, go check out the video. I would highly recommend it in
the video description, but it is important that you know what is going
on there because I'm going to use the code base from that video as the
starting point for this video, just so that we have a vehicle
to let the PDF file show inside of our
application. Now besides that, and also under that video, a lot
of people have asked me over the years, hey, how do I generate
reports? How do generate PDF in .NET MAUI? This is an amazing solution. It's called iText. I think before it
was iTextSharp, now it's called iText. And I think the
latest version is iText7, which is open source. There's a whole
company behind it. They do all kinds of amazing stuff with PDFs and
probably even more. One thing to note is that it is dual licensed, so there is restrictions in place if
you use it commercially. If you use it free, there is some
kinds of stuff in there. You know, I don't really go into that stuff
because that's something that you have to figure out yourself. But do keep in
mind that that is there. But there's probably a lot of
applications that you could use this for free, which is pretty
amazing. But keep that in mind. Important stuff. So I'm just
going to dive into the code and show you how generate PDF in .NET,
inside of your .NET MAUI application. And the really cool thing is it works
for any .NET project. So if you have WPF, WinForms, any type of .NET
project, you can generate PDFs after watching
this video. Let's go check it out. Okay, here we are, Visual Studio 2022. I loaded up that
project that I just mentioned from the other video. This is going to
be our starting point. I'm going to give you a brief overview, but please
still check out the other video because it's good for my YouTube stats. Okay,
just do it. So here we have a simple grid with a web view.
And inside of my resources for this project, I have this, my PDF
file. It's going to load that. I have a little bit of code here in
the code behind for Android. To actually make sure that we can load
local files for Android again, we have to load it into this PDF.js
library. Otherwise we can just say, hey, webview source is my
PDF and it will just run. So if I run this on Windows or any of the
other platforms, you will see the .NET MAUI app and come up and it will
show that PDF and what could be the contents. I don't know.
Well, maybe you want to subscribe to my channel again, good for the YouTube
stats. So just do that. Click on the button down
below. And while you do that, I'm going to move on to the next part here and
I'm going to close this application, leave all of this in place. And what
we're going to do is add a little button that generates a PDF
file and shows that in this same PDF viewer that we
have right here. Before we do that, I need to add a
couple of NuGet packages to actually make that PDF generation
possible. So go over to your Solution Explorer, right click
on your project and do manage NuGet packages. And then you're going
to search for iText. Now there is a couple of things here
you can see. I already searched for iText bouncy. Maybe that's just a good
thing to do because this was what we need to Bouncy Castle
is a whole other library that has some simple cryptography functionality on board, which is what we need as
well. That's just built in and very tightly coupled with itext right here.
So just make sure that you have that one to make sure everything goes smooth
here. And it probably has a dependency, I would think, on iText. If not, I'm going to install that
separately. But you can install this latest at the time of recording,
8.0.3, and you can see here installing Bouncy Castle. All
right, Newtonsoft.Json iText.Commons. Okay. I don't think it
actually installs the package that I also need. So I'm going
to let it install this just to be very, very sure. Also go to
iText without the bouncy and find iText7 right here
you can see 17 million downloads, 17 million
people can't be wrong. This must be an amazing library.
Again, check out the license, check out the options there. Definitely do that
because these people have been delivering wonderful work. iText7 also
install just to make sure that we have everything
here. This will bring in a whole new dependency thing right here.
Dependency graph. Apply all of that, all the licenses I accept and
it will be installed in a little bit. Now
with all of that in place, we don't need to do anything else but
the pdf generation. The thing that we actually want to see. Now to
make that possible, let's add a little button right here. So in my grid I'm
going to add row definitions so I can do row
definitions star so that the web view takes up the whole thing. And
then I'm going to do 50 so that we have 50 down at the bottom
where our button is going to be. So let's add that button that I've
been talking about. Grid. Whoops. Grid.Row="1" Text="Generate PDF" sounds like a great idea. Clicked is
let's generate a new clicked handler and it's done
that and close the tag right here. So now we have a
button that's hooked up to this clicked handler. And in this clicked
handler we're going to use the generate PDF code. Let's go to our code behind MainPage.xaml.cs. So we have this code
already in place here. We have our new button clicked
handler. Now before I'm going to paste in a bunch of code because the whole
generation of PDF is kind of like what this video is about,
but also it's the super hard thing and you're going to have to do
some figuring out yourself. I'm very sorry, this is not something
that I can just give you. And here's how it works. Because all the PDFs
will have different layouts. You will have to loop through items if
you're going to make an invoice or some other list, right? So you have to
take account of all the markup elements and
where you want things to be. I cannot decide that for you. I
can show you the basics, then you have to go out, figure out iText
documentation. I will put the link down in the show notes to
make that all work for you. But I can show you the basics on how
to get started, which is what I'm going to do right here. So let me
paste some code here from off screen this whole thing and don't be scared. Here
it comes. Boom. Okay, adds the missing usings.
Hopefully this is also indented the right way. Let's put the
Solution Explorer away so we can see all of it right here. So
we've got all of this and let's go from top to bottom. So
I'm going to specify the file name where
I'm going to generate this PDF in, mauidotnet.pdf. For Android... So file systems
on mobile devices can still be super
super hard. So for Android I couldn't really figure out a super
easy way, at least on the newer API levels, to write something to the
common documents folder because of the app sandbox and that
kind of stuff. So what I did is add a little bit of Android specific
code. So if you switch here, this is the combo box to switch between the
context, right, for the different platforms. If I switch to Android, this lights up
and what you can see happening is like hey, I'm going to get the
external files directory for the directory documents, but this
documents folder lives inside of my application sandbox. Okay, I can still
reach it, I can do all the things with it, but you cannot
really access it through a File Explorer. Super easy. So we'll see
that in a little bit for Android, a little bit complicated. I
think even for newer Android versions what you might want to do is use the
Essentials permissions API to RequestAsync. The Permissions.StorageWrite, and request those, right? And
this will request pop a little dialogue like hey, I want
to write something to the external storage. Make sure that you have the
right entry in the Android manifest. To be very honest, I haven't deployed
this to an actual physical device. It might be needed there, but this
worked for my scenario without the permissions. So
check out what you need to do for the file system
right here. But there might be something special for other platforms. So for
not Android, let's leave it at Windows for now. You can just say
hey Path.Combine get this special path folder, my documents
works. You dotnet really have to care where it's saved. You can care if you want to have it backuped
to like a cloud service or whatnot, or write it somewhere, but
you can just use this with the path combined. Now here is where itext
comes in the pdf writer because I've pasted it
in this already added like usings at the top
automatically for me because that's how smart Visual Studio
is. So you can see iText image iText.Kernel.Pdf.Canvas.Draw all this
stuff automatically added because I paste this stuff in.
There's a couple of things he didn't work out, Visual Studio. So I need to
do that now. Document can be a couple of things. I know it's
going to be iText.Layout. So we can have that thing in here. It adds
it to the top and I think that's everything. We'll fix this
error later. So we have this PdfWriter using, because this is
a disposable thing. So whenever we're done we can just
dispose this, do not have any memory leaks. I think this might be true for
also this pdf document. So make sure that you dispose of the things as
you go through this. So we're going to have this PDF
writer, which is actually going to be the thing that writes the PDF for us, and
we provide that with this file path. So PdfWriter, this is
where you're going to write this PDF to. Then we're going to
create a PdfDocument. If you've been working with XML
before, this might look familiar. You're going to create an XML
document. Here you have this PDF document and we're going to specify it with the
writer. Like hey, this PDF document is going to be written by this writer,
right? Inversion of control, dependency
injection, that kind of stuff. Here we have the writer that's going to be used to
write this document. Then we have another document which we
provide with PDF. So it's kind of like all layered and
from here we can actually start writing things. So we can create this
paragraph object, the header, and I'm going to do this
Maui PDF sample and I'm going to, in a kind of like
fluent way, set all these properties, set text alignment. So I'm going to
center this set font size. I'm going to make this 20 points and then document add header. I'm
going to add that to my document. Then I'm going to make a
paragraph subheader. Welcome to .NET MAUI, .NET Multi-platform App UI.
Right, we have that again, going to center it, make the
font a little bit smaller, add that to my document line separator. Just going
to add a little line in there with a solid line. You can do other
lines as well. Image stream here is the little error.
Still, I'm going to add the net bot in here. Now to be very
honest, I have added this PNG image to my raw resources right here together with that PDF. So
resources/raw/dotnet_bot.png is right here. That's what it's
going to be using. You can download an image of that,
what you want, generate your own image. I don't really care. You can use any
image. I have a little helper method in here. Again, I'm going to
copy that, which takes the image and turns that into a memory stream
because that's how this stuff works. So let's just put that in
here. Doesn't do really any magic. It opens through the
Essentials APIs like hey, open from package file the image
name netbot PNG and it's going to copy that to a
memory stream and it's going to return that. So now it knows
about this we have to do await. So let's make this an
async thing here. And now it's all happy, right? So we're going to get
that image stream and we can say hey, this iText.Layout.Element.Image,
right? We have multiple things that's called an image. So we need to specify this
is the itext image is a new image with an image data factory. So a
little bit complicated here. Images are complicated. We're going to
create it with this image stream. We're going to set the horizontal
alignment, right? So not text center alignment because this is just horizontal
alignment. Again, set it in the center and I still set the text alignment as
well. I don't think we actually need this. Let's just do only
this horizontal alignment again. Document add so you're just
building your document gradually by adding these blocks to it. And you
can see, I'm pretty sure, pretty confident that
you can set coordinates if that's what you want. But by using it
with this, with these paragraphs and things, you kind of like layer it as a
horizontal stack layout in .NET MAUI you're just going to add
all these elements and you will get a pretty cool PDF document
from this footer. So let's add a footer
too. Paragraph. Don't forget to like and
subscribe. See, in case you didn't do that earlier, this is your sign. Do
it now because you love this stuff, you love how to learn, generate
PDF files and to reward me you're going to subscribe
to my channel. Set text alignment, right? This is
going to be on the right. Font color light gray. It's important, but not that
important. Set font size again, document add that
footer as well. Document close because we're
done. And here it's going to dispose of this PDf writer, right? So it's
going to dispose all these things and that's all we need to generate
this PDF file. So now that we've got that, actually
let's run it right now. And the next step I'm going to take is
show that directly into the PDF viewer that we have inside of our
application. But for now, let's run this on Windows and see what it does when
we actually generate the file, how that shows up. Because if it's not
Android, so if Android it's not, we're going to go to the else,
we're going to go to this file path and we're going to write it to
the my documents folder, which is just the Windows documents folder that you
probably know and love in Windows. We can just go there and you
can see the PDF file actually showing up. So we can just inspect it
with the PDF viewer that's on our Windows machine. That's kind of
like the upside from running this on the desktop platforms.
You can just inspect the file systems and that kind of stuff.
Super much easier. So here we have our PDF file showing up as we did before.
And here we have this big button, generate PDF. So let's click it. It's
going to generate. We don't really have incorporated any
feedback here, so that's fine. I'm just going to assume that I'm the
best software developer in the world and this worked in one time. So let's go
into the File Explorer for Windows. Yes, my drive is
very very full. Thank you for noticing. And then I go to my
documents and here we have this mauidotnet.pdf file and whenever I open
it you can see, hey, we have this PDF and this is what
it looks like. We added that paragraph, we
added the other paragraph, we added that separator line, we added
the image and we added that little footer right there. Super cool.
We now have this PDF file generated. Now let's see how we
can show that actually back directly here inside of our application. I can
actually borrow some code that I wrote earlier
here. You can see it where I set the source. I dotnet need this append to mapping. Well, it's going to
do this anyway, right? It's going to do this anyway.
So you still need this. If this is the only thing that you're going to
do, like not care about this stuff that I wrote earlier, you still need
this because you're going to load on Android local files. So you're still
going to need this custom mapping. Watch the other video if you
don't know what this is about. But for this it will work. And I'm going to
copy this little piece right here because we still need to
differentiate between Android and the rest of the world. So whenever the whole PDF is
generated, I'm going to say if Android and now I can just
paste in the rest. I can just set this to
the file path that we generate here, right? So this
is going to be the same on Android and other platforms, but I can
just copy that because we have that same parameter, the same variable, and I can just paste that in
here instead of the my PDF that was now coming from the
assets right here. Right. We don't need that
anymore. We're going to load it from wherever we saved it. And actually you want to
remove this Android asset right here because this path is
going to be a full path. It's not going to be Android assets. That's
when you provide it together with your resources. You can just have this file
path right now that should be loadable on Android directly. And here for the
source, same thing, we have a full path here in this
variable, so let's just assign it to that. And if I do this on, well, let's
just go off script. Let's go on a little adventure. Let's
run this on Android actually, and I'm going to
fire this up on the Android emulator and see what happens if it
actually works. So on Android, obviously we're going to see the same thing
because it's a .NE MAUI application. Write your code once, run it
everywhere. We're going to see in a different form factor, obviously
the PDF viewer in the top that's going to load the PDF
from our resources. Then at the bottom we're going to have that
button to generate the PDF. We're going to click that. And now
it's not only going to generate it in the file path that we specify, but
it's also going to load it inside of that PDF viewer on the top, the PDF
that we've just generated. And there we go. The application is
coming up. It's being deployed to my Android emulator that I have got
running right here. Here we go. It should show up. Yes, here we are. So the viewer is
going to load. You're going to see that. Subscribe to my channel. I think
you've gotten enough hints now. Just subscribe, click the button. And now
whenever I click this generate button down, generate PDF button down here below,
it's going to generate the PDF. It's going to take a little while and
it's going to load that exact same PDF because that's the power of pdfs
also like write once, run anywhere. You're going to see that
in this viewer right here. And if I know the correct short button
for Android, I can actually zoom in here as well.
And you can inspect that. This is like the exact same thing that
we just saw on Windows, generating a PDF on Android, Windows.
We've seen it all and showing it inside of our own
PDF viewer. Super cool stuff right here in your .NET MAUI
application. And there's that. There's probably other libraries that can do it as
well. I also know that the component vendors that I just mentioned for PDF viewers,
they usually also have functionality to also create PDF file, which might
be even easier if you also use their reporting tools and
all that kind of stuff. But again, if you're looking for free options to
explore your things, keep the license in mind for iText. But this might be a
very good option for you. Is this everything you wanted to know
about pdfs generating viewing them? What else did I miss?
Let me know down in the comments. Are you liking this? What do you want
to see next? I'll see you for the next video. Maybe you still missed
that PDF viewer one, then here's your chance. Click on this link and I'll
see you there.