Search code examples
javascriptasp.net-corerazorjspdf

How to create a button to convert Razor view in .NET 7.0 to a PDF doc using JsPDF?


I've created a page that pulls in various information and displays it all using a custom made document template. It's in the form of a form that can either be printed out and signed by all relevant people or, for the purposes of what I want, be converted to a PDF that can be used with electronic signatures. The signatures part is unimportant at the moment. All I want right now is to be able to convert this view to PDF.

I did some research and tried using JsPDF for this purpose.

I made the necessary script call

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>

Created the view along with the button needed to perform the function

<body>
    <div class="col-xl-10 mx-xl-auto"
         style="max-width: 100%">
        <div class="page-portrait-custom"
             style="font-size: 13px;">

            //Some view code here

            <button id="generatePdfButton">Generate PDF</button>

            //The rest of the view code here

        </div>
    </div>
</body>

Finally, my Javascript code

<script>
    document.getElementById('generatePdfButton').addEventListener('click', function () {
        // Create a new jsPDF instance
        const doc = new jsPDF();

        // Add content to the PDF document
        const htmlContent = document.querySelector('.page-portrait-custom').outerHTML;
        doc.html(htmlContent, {
            callback: function (pdf) {
                // Save the PDF document
                pdf.save('ChangeOrderForm.pdf');
            }
        });
    });
</script>

The button appears, but when I click it, nothing happens. I'm using Chrome for this, so I checked what was happening using the developer's tools and I got a 200 code for jspdf loading in, so that's not the problem.

When I click on the button, it doesn't seem to show anything happening. I've tried checking around to see if the file was saved in the background, but can't find anything.

I'm relatively inexperienced in this so maybe there's something fundamental I'm just unaware of that I'm missing. Regardless, any insight, advice, or suggestions would be very much appreciated.


Solution

  • I test with an asp.net core mvc project.

    Within _Layout.cshtml, adding the required libraries. Without html2canvas.min, I would get Could not load html2canvas: Error: Could not load html2canvas error.

    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
    

    Then inside the index.cshtml, I had a table in the view and would export this table into pdf.

    <div id="myContent">
        <table id="employeeTable" class="table table-striped">
            <thead>
                <tr>
                    <!-- Empty header for the toggle button -->
                    <th></th>
                    <th>First Name</th>
                    <th>Second Name</th>
                    <th>Job Title</th>
                    <th>Salary</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var employee in Model)
                {
                    <tr class="parent-row">
                        <td><i class="fas fa-arrow-right expand-icon"></i></td>
                        <td>@employee.FirstName</td>
                        <td>@employee.SecondName</td>
                        <td>@employee.JobTitle</td>
                        <td>@employee.Salary</td>
                    </tr>
                    <tr class="child-row rowhide">
                        <td></td>
                        <td colspan="4">
                            <div class="child-details">
                                About me: @employee.AboutMe
                                <br />
                                ID: @employee.Id
                            </div>
                        </td>
                        <td style="display:none"></td>
                        <td style="display:none"></td>
                        <td style="display:none"></td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
    
    <button id="exportPdf">export to pdf</button>
    
    @section Scripts{
        <script>
            $("#exportPdf").click(function () {
                window.html2canvas = html2canvas;
                window.jsPDF = window.jspdf.jsPDF;
    
                var doc = new jsPDF();
                var elementHTML = document.querySelector("#myContent");
                console.info("this is element :" + elementHTML);
                
                doc.html(elementHTML, {
                    callback: function (doc) {
                        // Save the PDF
                        doc.save('sample-document.pdf');
                    },
                    x: 15,
                    y: 15,
                    width: 170, //target width in the PDF document
                    windowWidth: 650 //window width in CSS pixels
                });
    
            });
        </script>
    }
    

    Like you see, the html content is loaded dynamically, based on the view model. And it worked for me to generate a pdf. There's css issue in the file but anyway pdf is generated.

    enter image description here