How to render PDF if a cell contains an inner table

How to render PDF if a cell contains an inner table

isadukovskiyisadukovskiy Posts: 5Questions: 1Answers: 1


table = $('#Table_AuditHistory').DataTable({
"pageLength": 4,
"responsive": true,
"order": [[0, 'desc']],
"dom": 'Bfrtip',
"buttons": [
'pdfHtml5'
],
"columns": [
{ "width": "10%", "responsivePriority": 3 },
{ "width": "25%", "responsivePriority": 2 },
{ "width": "50%", "responsivePriority": 1, "orderable": false },
{ "width": "15%", "responsivePriority": 4 },
]
});

Here is what's rendered:
<tbody>
<tr class="odd">
<td data-order="2022-06-08 20:24:27.6364492" class="dtr-control sorting_1" tabindex="0">06/08/2022 04:24:27 PM EST</td>
<td>Financial details</td>
<td>
<table class="table table-hover">
<tbody><tr>
<th style="width: 30%">Field</th>
<th style="width: 35%">Old Value</th>
<th style="width: 35%">New Value</th>
</tr>
</tbody><tbody>
<tr>
<td class="auditChangesCell" style="text-align: left">Special information</td>
<td class="auditChangesCell" style="text-align: left"></td>
<td class="auditChangesCell" style="text-align: left">Corporation owned property, Bonus</td>
</tr>
</tbody>
</table>
</td>
<td>email2is@yahoo.com</td>
</tr><tr class="even">
<td data-order="2022-06-08 20:22:51.3185058" class="dtr-control sorting_1" tabindex="0">06/08/2022 04:22:51 PM EST</td>
<td>Financial details</td>
<td>
<table class="table table-hover">
<tbody><tr>
<th style="width: 50%">Field</th>
<th style="width: 50%">First Entry</th>
</tr>
</tbody><tbody>
<tr>
<td class="auditChangesCell" style="text-align: left">List price</td>
<td class="auditChangesCell" style="text-align: left">100</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Buyer agent compensation</td>
<td class="auditChangesCell" style="text-align: left">2</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Comission in $ (False = %)</td>
<td class="auditChangesCell" style="text-align: left">False</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Min % down requirement</td>
<td class="auditChangesCell" style="text-align: left">None</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Lender approval required</td>
<td class="auditChangesCell" style="text-align: left">True</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Short sale</td>
<td class="auditChangesCell" style="text-align: left">True</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">REO</td>
<td class="auditChangesCell" style="text-align: left">True</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">On auction</td>
<td class="auditChangesCell" style="text-align: left">True</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Auction date</td>
<td class="auditChangesCell" style="text-align: left">06/29/2022 08:00:00 PM EST</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Terms considered</td>
<td class="auditChangesCell" style="text-align: left">Cash only, Cash, Assumption</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Pocession information</td>
<td class="auditChangesCell" style="text-align: left">Before closing, Funding</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Tax information</td>
<td class="auditChangesCell" style="text-align: left">County only tax, City county tax</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Total mortgage</td>
<td class="auditChangesCell" style="text-align: left">100</td>
</tr>
</tbody>
</table>
</td>
<td>email2is@yahoo.com</td>
</tr><tr class="odd">
<td data-order="2022-06-04 16:29:51.4834668" class="dtr-control sorting_1" tabindex="0">06/04/2022 12:29:51 PM EST</td>
<td>Address</td>
<td>
<table class="table table-hover">
<tbody><tr>
<th style="width: 50%">Field</th>
<th style="width: 50%">First Entry</th>
</tr>
</tbody><tbody>
<tr>
<td class="auditChangesCell" style="text-align: left">Address line 1</td>
<td class="auditChangesCell" style="text-align: left">9733 Darlington Pl</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">City</td>
<td class="auditChangesCell" style="text-align: left">Cooper City</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">State</td>
<td class="auditChangesCell" style="text-align: left">FL</td>
</tr>
<tr>
<td class="auditChangesCell" style="text-align: left">Zip code</td>
<td class="auditChangesCell" style="text-align: left">33328</td>
</tr>
</tbody>
</table>
</td>
<td>isadukovskiy@magicleap.com</td>
</tr></tbody>

This question has an accepted answers - jump to answer

Answers

  • isadukovskiyisadukovskiy Posts: 5Questions: 1Answers: 1

    As you can see PDF content is not aligned and I could not find an example that would render datatable html contents as rendered.

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    I'm afraid the PDF export we provide in Buttons isn't that smart. The pdfmake library doesn't render HTML in table cells (indeed our default is to strip all HTML tags). For something more complex like this I think a custom export would be needed.

    Allan

  • isadukovskiyisadukovskiy Posts: 5Questions: 1Answers: 1

    :( When you say custom, are you talking about customize function like below or outside of datatable?

    "buttons": [{
                extend: 'pdfHtml5',
                text: 'PDF',
                customize: function (doc) {
                    let table = doc.content[1].table.body;
                    for (i = 1; i < table.length; i++) // skip table header row (i = 0)
                    {
                        var test = table[i][0];
                    }
                }
            }]
    

    I tried to see if I can somehow manipulate the data but did not see a way.

    What about Excel, Print or Copy? They all output different format of data from my datatable. Is one maybe easier than other to manipulate?

  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    You could probably do it with the customize callback, but you'd need to parse the inner HTML table and convert that to pdfmake's format. As such I would recommend generating this sort of pdf generation server-side - that's what I would do myself.

    Allan

  • isadukovskiyisadukovskiy Posts: 5Questions: 1Answers: 1
    edited June 2022 Answer ✓

    For those interested. Ended up using jsPDF and html2canvas for same table but without applying datatable. .In .net core I ended up using partial view for this.

    window.html2canvas = html2canvas;
    var doc = new jsPDF('p', 'pt', 'a4');
    doc.html($('#contentElement')[0],
       {
           callback: function (pdf) {
              pdf.save("Test.pdf");
           }
       });
    
  • allanallan Posts: 63,498Questions: 1Answers: 10,471 Site admin

    Nice one - thanks for posting back with your solution.

    Allan

  • isadukovskiyisadukovskiy Posts: 5Questions: 1Answers: 1
    edited June 2022

    You are welcome. Hopefully this will save someone time.
    This is full implementation of calling partial view. I ended up also using html2pdf which formats pdf much nicer with page breaks. It also allowed me to add a spinner while pdf is being generated.

    $(async function () {
        createDashboardTable();
        window.html2canvas = html2canvas;
        $('#btnPdf').click(() => {
            var listingId = $('#ListingId').val();
            $('.loading').removeClass('invisible');
            $.ajax({
                type: "GET",
                url: `/Dashboard/AuditHistory?listingId=${listingId}&isForPdf=true`,
                success: function (data) {
                    var content = $(data)[0];
                    var opt = {
                        margin: 1,
                        filename: 'ListingChanges.pdf',
                        image: { type: 'jpeg', quality: 0.95 },
                        html2canvas: { scale: 1 },
                        jsPDF: { unit: 'in', format: 'letter', orientation: 'landscape' },
                        pagebreak: { mode: 'css', avoid: ['img', 'tr'] }
                    };
    
                    html2pdf(content, opt).then(function() {
                        $('.loading').addClass('invisible');
                    });
                }
            });
        });
    });
    
Sign In or Register to comment.