How to customize jquery datatables export PDF?

I've modified a cell on a datatable to show a coloured div which is a gradient depending on score enter image description here

{
"data": "fert_percent",
"autoWidth": true,
"searchable": true,
"render": function (data, type, row, meta)
{
var ret = "<div class='col' style='background-color: lawngreen;'><div class='col' style='background-color: red; opacity: " + (data / 100) + ";'>&nbsp;</div></div>";
return ret;
}
},

The code works fine viewing the table but if I export to PDF, the cell is empty.

enter image description here

How can I make the exported PDF show the modified cell?


The pdfMake library doesn't support opacity on the background colour, it only applies to the font. If you're wondering why that is, it's because the PDF format is unrelated to the CSS standard.

That said, you can export different colours if you update the pdfMake document before DataTables sends it off to the file generator:

(Note: I didn't bother putting the greens into the DataTable version, only the PDF export)

pdf output

$(document).ready(function() {

  $('#example').DataTable({
    columns: [{
        "data": "name"
      },
      {
        "data": "position"
      },
      {
        "data": "office"
      },
      {
        "data": "age"
      },
      {
        "data": "start_date"
      },
      {
        "data": "salary"
      }
    ],
    dom: 'Bfrtip',
    buttons: [{
      extend: 'pdfHtml5',
      text: 'PDF with cell background colour',
      customize: function(doc) { // set the cell colours for the PDF
        //console.log(doc); // useful if you want to see what the doc object contains

        // you can set generate styles like this if you want
        //doc.styles["Opac10"] = { opacity: "0.1"};

        let table = doc.content[1].table.body;

        for (i = 1; i < table.length; i++) // skip table header row (i = 0)
        {
          table[i][3].text = " "; // couldn't be bothered clearing the Age column sample data above :)
          table[i][3].fillColor = "#00" + Math.round((i / 9) * 255).toString(16) + "00"; // ( divided by 9 since 9 rows in my example)

          
          if (table[i][2].text == 'Tokyo') {
            table[i][2].fillColor = '#fbed1d'; // yellow
            //table[i][2].style = 'Opac10'; // Here's how you can refer to styles from above. Note: opacity only applies to the font, not the background colour in the pdf table cell!!     
          }
        }
      }
    }],
    rowCallback: function(row, data, index) { // sets the cell colours for DataTables
      if (data.office == "Tokyo") {
        $('td:eq(2)', row).css('background-color', '#fbed1d'); // yellow
      }
    }
  });
});
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.11.4/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/2.2.2/css/buttons.dataTables.min.css">

<script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.11.4/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/2.2.2/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/2.2.2/js/buttons.html5.min.js"></script>

<table id="example" class="display" style="width:100%">
  <thead>
    <tr>
      <th>Name</th>
      <th>Position</th>
      <th>Office</th>
      <th>Age</th>
      <th>Start date</th>
      <th>Salary</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tiger Nixon</td>
      <td>System Architect</td>
      <td>Edinburgh</td>
      <td>61</td>
      <td>2011/04/25</td>
      <td>320800</td>
    </tr>
    <tr>
      <td>Garrett Winters</td>
      <td>Accountant</td>
      <td>Tokyo</td>
      <td>63</td>
      <td>2011/07/25</td>
      <td>170750</td>
    </tr>
    <tr>
      <td>Ashton Cox</td>
      <td>Junior Technical Author</td>
      <td>San Francisco</td>
      <td>66</td>
      <td>2009/01/12</td>
      <td>86000</td>
    </tr>
    <tr>
      <td>Cedric Kelly</td>
      <td>Senior Javascript Developer</td>
      <td>Edinburgh</td>
      <td>22</td>
      <td>2012/03/29</td>
      <td>433060</td>
    </tr>
    <tr>
      <td>Airi Satou</td>
      <td>Accountant</td>
      <td>Tokyo</td>
      <td>33</td>
      <td>2008/11/28</td>
      <td>162700</td>
    </tr>
    <tr>
      <td>Brielle Williamson</td>
      <td>Integration Specialist</td>
      <td>New York</td>
      <td>61</td>
      <td>2012/12/02</td>
      <td>372000</td>
    </tr>
    <tr>
      <td>Herrod Chandler</td>
      <td>Sales Assistant</td>
      <td>San Francisco</td>
      <td>59</td>
      <td>2012/08/06</td>
      <td>137500</td>
    </tr>
    <tr>
      <td>Rhona Davidson</td>
      <td>Integration Specialist</td>
      <td>Tokyo</td>
      <td>55</td>
      <td>2010/10/14</td>
      <td>327900</td>
    </tr>
    <tr>
      <td>Donna Snider</td>
      <td>Customer Support</td>
      <td>New York</td>
      <td>27</td>
      <td>2011/01/25</td>
      <td>112000</td>
    </tr>
  </tbody>
  <tfoot>
    <tr>
      <th>Name</th>
      <th>Position</th>
      <th>Office</th>
      <th>Age</th>
      <th>Start date</th>
      <th>Salary</th>
    </tr>
  </tfoot>
</table>