Search code examples
asp.net-corepdfprintingrazor-pages

Printing PDF in ASP.NET Core 3.1 Razor Pages


In my quest to learn ASP.NET core I've created a simple CRUD application using asp.net core 3.1. I want to print my Details page as a Invoice. I have looked around and it seems like printing PDF in full .NET Framework was more available.

Can anyone point me in the right direction? I have come across free libraries like SelectPDF, WKHTMLTOPDF, PDFSharp but quiet frankly the samples are pre- asp.net core and cannot quiet integrate it with ASP.NET Core Razor Pages. Actually, if I'm not mistaken some of the libraries mentioned above are not compatible with Razor Pages.


Solution

  • I have come across free libraries like SelectPDF, WKHTMLTOPDF, PDFSharp but quiet frankly the samples are pre- asp.net core and cannot quiet integrate it with asp.net core Razor Pages.

    I suggest that you could use client side library.Because what you metioned are all server side libraries,they all need to find the view and convert to string.As far as I known,it seems no such direct method to convert razor pages to string.So I suggest that you could use jsPDF library.

    Here is a whole working demo:

    @page
    @model DetailsModel
    <div id="details">       //be sure add this id...
    
        <h1>Details</h1>
    
        <div>
            <h4>test</h4>
            <hr />
            <dl class="row">
                <dt class="col-sm-2">
                    @Html.DisplayNameFor(model => model.test.Name)
                </dt>
                <dd class="col-sm-10">
                    @Html.DisplayFor(model => model.test.Name)
                </dd>
            </dl>
        </div>
        <div>
            <a asp-page="./Edit" asp-route-id="@Model.test.Id">Edit</a> |
            <a asp-page="./Index">Back to List</a>
        </div>
    </div>
    
    <button onclick="javascript:demoFromHTML();">Generate PDF</button>
    
    @section Scripts
    {
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
        <script>
            function demoFromHTML() {
                var pdf = new jsPDF('p', 'pt', 'letter');
                // source can be HTML-formatted string, or a reference
                // to an actual DOM element from which the text will be scraped.
                source = $('#details')[0];
    
                // we support special element handlers. Register them with jQuery-style
                // ID selector for either ID or node name. ("#iAmID", "div", "span" etc.)
                // There is no support for any other type of selectors
                // (class, of compound) at this time.
                specialElementHandlers = {
                    // element with id of "bypass" - jQuery style selector
                    '#bypassme': function (element, renderer) {
                        // true = "handled elsewhere, bypass text extraction"
                        return true
                    }
                };
                margins = {
                    top: 80,
                    bottom: 60,
                    left: 40,
                    width: 522
                };
                // all coords and widths are in jsPDF instance's declared units
                // 'inches' in this case
                pdf.fromHTML(
                    source, // HTML string or DOM elem ref.
                    margins.left, // x coord
                    margins.top, { // y coord
                    'width': margins.width, // max width of content on PDF
                    'elementHandlers': specialElementHandlers
                },
    
                    function (dispose) {
                        // dispose: object with X, Y of the last line add to the PDF
                        //          this allow the insertion of new lines after html
                        pdf.save('Test.pdf');
                    }, margins);
            }
        </script>
    }