MVC Net Core 3.1: Tool to create and download PDF file

Viewed 1429

From past 2 days I have have tried multiple tools to create PDF file. Previously I have used iTextSharp but in Console app in .Net 4. Now I want to create PDF in Asp Net Core, when I tried to use iTextSharp I found there are other nuget packages which I can use. I installed them and did the coding but I am having lot of reference errors. Also tried several others tool but either I am having issues at runtime or at design time, at one point my program was crashing and at runtime and I had to undo my changes.

Can someone guide me to any tutorial that is good for Asp .Net Core 3.1? It can be an example either creating a PDF from the html or from the object list.

4 Answers

Recommand Rotativa as well, feel it is very convenient to use. I made a demo, which you can have a reference.

1.Download the Rotativa.AspNetCore from nuget.

2.we need to add a new Folder in wwwroot with name “Rotativa” and inside this folder, then add wkhtmltopdf.exe, wkhtmltoimage.exe files.

enter image description here

You can get the two files from GitHub sample demo

https://github.com/webgio/Rotativa.AspNetCore/tree/master/Rotativa.AspNetCore.Demo/wwwroot/Rotativa

3.Configure it in your Startup.cs

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

var hostingEnvironment = app.ApplicationServices.GetService<Microsoft.AspNetCore.Hosting.IHostingEnvironment>();
RotativaConfiguration.Setup(hostingEnvironment);

4.In your controller action, Just change the returnType to ViewAsPdf, then it will display the view as pdf.

public IActionResult Index()
{
    var users = new List<User>()
    {
        new User{ Id = 1, Name = "AA", Address = "Address1"},
        new User{ Id = 2, Name = "BB", Address = "Address2"},
        new User{ Id = 3, Name = "CC", Address = "Address3"},
        new User{ Id = 4, Name = "DD", Address = "Address4"},
    };
    return new ViewAsPdf(users);
}

The Index view:

@model IEnumerable<User>

@{
    ViewData["Title"] = "Index";
}

<h1>Index</h1>

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Address)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Id)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Address)
                </td>
                <td>
                    <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Result:

enter image description here

If you want to download it, you can simply give it a FileName

return new ViewAsPdf(users) 
{ 
    FileName="MyPdf.pdf"
};

Update:

Action:

public IActionResult DemoViewAsPDF()
{
    var users = new List<User>()
    {
        new User{ Id = 1, Name = "AA", Address = "Address1"},
        new User{ Id = 2, Name = "BB", Address = "Address2"},
        new User{ Id = 3, Name = "CC", Address = "Address3"},
        new User{ Id = 4, Name = "DD", Address = "Address4"},
    };
    ViewData["Data"] = "ViewDataValue";
    ViewBag.Data2 = "ViewBagValue";
    return new ViewAsPdf(users, ViewData);
}

View:

@model IEnumerable<User>

@{
    ViewData["Title"] = "Index";
}

<h1>@ViewData["Data"]</h1>
<h1>@ViewBag.Data2</h1>

<h1>@ViewData["Title"]</h1>

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Address)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Id)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Address)
                </td>
                <td>
                    <a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.Id">Details</a> |
                    <a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
                </td>
            </tr>
        }
    </tbody>
</table>

Result:

enter image description here

For .net core, I moved to generating PDF files from HTML using PuppeteerSharp:

https://www.puppeteersharp.com/

I believe iTextSharp requires a license these days unless an older version is used.

I have also used PdfSharp (another free library, but don't believe it support .net core yet. possibly one to look out for in future. This works pretty well and much easier to use than iTextSharp.

Related