2

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.

Faisal
  • 109
  • 1
  • 9

4 Answers4

1

Have a look at Rotativa (can personally say it works really well) -

https://www.nuget.org/packages/Rotativa.AspNetCore/1.2.0-beta

GitHub page has a tutorial of how to begin -

https://github.com/webgio/Rotativa

bsod_
  • 903
  • 8
  • 27
1

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

mj1313
  • 7,930
  • 2
  • 12
  • 32
  • Hi mj1313, I used Rotativa but the current release did not work on the asp.net 3.1. After searching I had to use the beta version and then I was able to successfully create the pdf file. Nevertheless, I got into one issues afterword that I am not able to access viewbag in the view. See the post here https://stackoverflow.com/questions/59995626/asp-net-core-3-rotativa-startup-cs-env-problem – Faisal Nov 16 '20 at 09:29
  • Hi @Faisal, if you want to enable ViewBag or ViewData in the pdf, you need to return ViewData as well. See my update. – mj1313 Nov 17 '20 at 08:20
  • Thanks Great. mj1313, it was helpful, I am able to get the View.Bag. Just like i mentioned and mentioned by bsod that in order for me to get it right I had to get beta version of 1.2.0. – Faisal Nov 18 '20 at 20:29
  • Hi mj1313, thanks for showing how to pass ViewBag. Do you know how I can change the page orientation to Portrait? Since the number of columns are a many and not fitting nicely on the page in vertical view. – Faisal Nov 20 '20 at 22:47
1

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.

Mark Redman
  • 24,079
  • 20
  • 92
  • 147
  • 1
    HI Mark, I didn't try PuppeteerSharp because I am using asp.net 3.1. I checked the files they were last updated on 2017 whereas asp.net 3.1 release in late 2019. Since I have had already tried few others 3rd tools to generate PDF and was finding issues, I went to use Rotativa, but I will do try that when I am free. Thanks – Faisal Nov 16 '20 at 09:33