DataTables 1.13 ES6 buttons plugin jszip and pdfmake integration

DataTables 1.13 ES6 buttons plugin jszip and pdfmake integration

SchonhoffSchonhoff Posts: 12Questions: 1Answers: 0
edited November 2022 in Free community support

Hello,

after updating the DataTables packages yesterday, I encountered some problems. I changed my import from

import JSZip from 'jszip';
import ButtonHtml5 from 'datatables.net-buttons/js/buttons.html5';
window.JSZip = JSZip;
ButtonHtml5(window, $);

to

import JSZip from 'jszip';
import 'datatables.net-buttons';
window.JSZip = JSZip;

I found the new implementation in your git repository https://github.com/DataTables/Dist-DataTables-Buttons. But my app still throws this error:

buttons.html5.mjs:18 Uncaught ReferenceError: jszip is not defined
    at _jsZip (buttons.html5.mjs:18:2)
    at Object.available (buttons.html5.mjs:976:45)
    at Buttons.excel (dataTables.buttons.mjs:1875:55)
    at toConfObject (dataTables.buttons.mjs:1066:18)
    at Buttons._resolveExtends (dataTables.buttons.mjs:1101:19)
    at Buttons._expandButton (dataTables.buttons.mjs:587:20)
    at Buttons._expandButton (dataTables.buttons.mjs:646:10)
    at Buttons.add (dataTables.buttons.mjs:178:8)
    at Buttons._constructor (dataTables.buttons.mjs:493:9)
    at new Buttons (dataTables.buttons.mjs:101:7)

Is there a way to include jszip or pdfmake back to buttons again?

Also will there be a new documentation how to implement DataTables into an ES6 project?

I'm currently working with vite and with the following DataTables packages:

"datatables.net": "1.13.0",
"datatables.net-buttons": "2.3.1",
"datatables.net-responsive": "2.4.0",
"datatables.net-select": "1.5.0",
"jszip": "3.10.1",
"pdfmake": "0.2.6",

Maybe someone can give me some hint how to implement it with DataTables 1.13 . Thanks and have a nice day/night.

This question has accepted answers - jump to:

Answers

  • SchonhoffSchonhoff Posts: 12Questions: 1Answers: 0

    Some additional information:

    1.) I only want to include the excel export option on one site (it is an extra .js file) and on another side I want to include the excel/pdf export option.
    2.) DataTables will load if I changed the position of the JSZip import like this

    import JSZip from 'jszip';
    window.JSZip = JSZip;
    
    import 'datatables.net-buttons';
    import './datatables-without-export';
    

    But on my app the button won`t show up. The buttons are defined like this:

    buttons: [
    {
      extend: 'excel',
      text: 'Download current page',
      filename: 'Order overview',
      exportOptions: {
          columns: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9,],
          rows: ':visible',
       }
    },
    [...other buttons...]
    ]
    

    There is no error on the console nor a error on the DataTables debug plugin (I can't open Version check there because of our cors policy).

    For our app we will go back to version 1.12.1 and wait till there are some new information where my configuration error may be.

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin
    import JSZip from 'jszip';
    import DataTable from 'datatables.net';
    import 'datatables.net-buttons';
    
    DataTable.Buttons.jszip( JSZip );
    

    Should do the job.

    Buttons adds two static methods for the setting of pdfMake and JSZip for exactly this sort of thing.

    Allan

  • SchonhoffSchonhoff Posts: 12Questions: 1Answers: 0

    Hello allen,

    sadly it isn't working like expected. My datatables-all-without-pdf.js:

    import JSZip from 'jszip';
    import DataTable from 'datatables.net';
    import 'datatables.net-responsive';
    import 'datatables.net-buttons';
    import 'datatables.net-select';
    DataTable.Buttons.jszip( JSZip );
    

    still throws this error:

    Uncaught TypeError: DataTable.Buttons.jszip is not a function
        at datatables-all-without-pdf.js:6:19
    dataTables.buttons.mjs:1098 Uncaught Cannot extend unknown button type: colvis
    

    For my DataTable I need the following packages:
    1. DataTables
    2. Responsive
    3. Colvis buttons
    4. Excel export buttons
    5. Select

    Here is the content of the vite generated file:

    import __vite__cjsImport0_jszip from "/node_modules/.vite/deps/jszip.js?v=675c9b81"; const JSZip = __vite__cjsImport0_jszip.__esModule ? __vite__cjsImport0_jszip.default : __vite__cjsImport0_jszip;
    import DataTable from '/node_modules/.vite/deps/datatables__net.js?v=b9f48634';
    import '/node_modules/.vite/deps/datatables__net-responsive.js?v=0e994e3f';
    import '/node_modules/.vite/deps/datatables__net-buttons.js?v=2e5e3c2d';
    import '/node_modules/.vite/deps/datatables__net-select.js?v=b5503de8';
    DataTable.Buttons.jszip( JSZip );
    

    If you need more information, please ask. I will try to deliver them asap.

  • SchonhoffSchonhoff Posts: 12Questions: 1Answers: 0
    edited November 2022

    My DataTable code:

    I deleted some parts and changed some naming for security reasons. We did not change the DataTable code after updating to 1.13.

    $('#dt_overview').DataTable({
        ajax: {
            url: '/hello/world',
            type: 'POST',
            data: function ( d ) {
                d.months_to_show = 1;
            }
        },
        responsive: {
            details: {
                type: 'column',
                target: -2
            }
        },
        processing: true,
        serverSide: true,
        dom: 'B<"float-right"f>rt<"flex justify-between items-center px-5"ilp>',
        pageLength: 10,
        lengthMenu: [ [10, 25, 50, 100, 150], [10, 25, 50, 100, 150] ],
        orderMulti: false,
        stripeClasses: ['stripe1', 'stripe2',],
        columns: [
            {responsivePriority: 1, data: null, orderable: false, searchable: false, defaultContent: ""},
            {responsivePriority: 2, data: 'column1', orderable: true, searchable: true},
            {responsivePriority: 4, data: 'column2', orderable: true, searchable: true, width: "15%"},
            {responsivePriority: 6, data: 'column3', orderable: true, searchable: true, className: 'text-nowrap'},
            {responsivePriority: 5, data: 'column4', orderable: true, searchable: true},
            {responsivePriority: 7, data: 'column5', orderable: false, searchable: true, className: 'text-nowrap'},
            {responsivePriority: 10, data: 'column6', orderable: false, searchable: true},
            {responsivePriority: 9, data: 'column7', orderable: true, searchable: true},
            {responsivePriority: 8, data: 'column8', orderable: true, searchable: true},
            {responsivePriority: 12, data: 'column9', orderable: false, searchable: true, visible: false},
            {responsivePriority: 13, data: 'column10', orderable: false, searchable: true},
            {responsivePriority: 14, data: 'column11', orderable: false, searchable: true},
            {responsivePriority: 0, data: null, orderable: false, searchable: false, defaultContent: ""},
            {responsivePriority: 3, data: 'column12', orderable: false, searchable: false},
        ],
        columnDefs: [
            {
                className: 'select-checkbox',
                orderable: false,
                targets: 0
            },
            {
                className: 'dtr-control',
                orderable: false,
                targets: -2
            }
        ],
        select: {
            style:    'multi',
            selector: 'td:not(:last-child, :nth-child(13))',
        },
        buttons: [
            {
                extend: 'collection',
                text: 'Download as .xls',
                titleAttr: 'Download as .xls',
                className: 'lg:rounded-r-none lg:border-r-0 lg:mr-0',
                autoClose: true,
                buttons: [
                    {
                        extend: 'excel',
                        text: 'Download current page',
                        filename: 'Overview',
                        exportOptions: {
                            columns: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
                            rows: ':visible',
                        }
                    },
                    {
                        extend: 'excel',
                        text: 'Download currently selected objects',
                        filename: 'Overview',
                        enabled: false,
                        exportOptions: {
                            columns: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
                        }
                    },
                ]
            },
            {
                extend: 'colvis',
                className: 'lg:rounded-l-none lg:border-l-0 lg:ml-0',
                columns: [1,2,3,4,5,6,7,8,9],
            },
        ]
    });
    
  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin
    Answer ✓

    Hi,

    I've just released Buttons 2.3.2 to npm which should address the issue you are seeing. Here is an example showing Excel and PDF export

    import JSZip from 'jszip';
    import pdfMake from 'pdfmake';
    import pdfFonts from 'pdfmake/build/vfs_fonts';
    import DataTable from 'datatables.net-bs5';
    import 'datatables.net-buttons-bs5';
    import 'datatables.net-buttons/js/buttons.html5';
    
    DataTable.Buttons.jszip(JSZip);
    DataTable.Buttons.pdfMake(pdfMake);
    
    pdfMake.vfs = pdfFonts.pdfMake.vfs;
    
    new DataTable('#example', {
        dom: 'Bftip',
        buttons: [
            'excel',
            'pdf'
        ]
    });
    

    Allan

  • SchonhoffSchonhoff Posts: 12Questions: 1Answers: 0

    Hey allen,

    thanks for the update! It is working like expected. Thanks for the fast replies and the help!

    Maybe a blog post with an updated ES6 integration manual would be helpful for other users.

    Have a nice day/night!

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin
    Answer ✓

    Yes, blog post and a few documentation updates are coming :)

    Allan

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    Hi Allan,

    I am running into the TypeError: Cannot set properties of undefined (setting 'pdfMake') error when applying the code above.

    It appears after applying import 'datatables.net-buttons/js/buttons.html5';
    If I take out that line and the DataTable.Buttons.jszip(JSZip); DataTable.Buttons.pdfMake(pdfMake); pdfMake.vfs = pdfFonts.pdfMake.vfs; Then the table generates without buttons however the <div class="dt-buttons btn-group flex-wrap"> </div> place holder appears.

    Here is the code I have below and all packages are up-to-date, using Buttons 2.3.6

    import React from "react";
    import $ from "jquery";
    import JSZip from 'jszip';
    import pdfMake from 'pdfmake';
    import pdfFonts from 'pdfmake/build/vfs_fonts';
    import DataTable from 'datatables.net-bs5';
    import 'datatables.net-buttons-bs5';
    import 'datatables.net-buttons/js/buttons.html5';
    
    DataTable.Buttons.jszip(JSZip);
    DataTable.Buttons.pdfMake(pdfMake);
    
    pdfMake.vfs = pdfFonts.pdfMake.vfs;
    
    function DataTableDataTwo() {
      $(document).ready(function () {
        var table = $("#dvTable").DataTable({
          retrieve: true,
          lengthChange: false,
          scrollY: 275,
          scrollCollapse: true,
          //dom: 'Bftip',
          buttons: [ 'copy', 'excel', 'pdf', 'colvis']
        });
        table.buttons().container()
        .appendTo($('.col-sm-12:eq(0)', table.table().container()));
      });
    
    

    I've been attempting different solutions for the the last two days so any help is appreciated. Also I didn't know if I should make a new post or not since this is on track with what I'm needing.

    Thanks,
    Cody

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Hi Cody,

    Can you create a repo demonstrating the issue so we can help debug it please.

    Allan

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    Apologies but I'm still new to developing, below is the repo for the code:
    https://github.com/CodyG-2021/dt-debug

    Here is a vid on the error I'm getting:
    https://drive.google.com/file/d/1EbhSNXj_uWIBF5NGowbP0Dzzm8stAPxW/view?usp=sharing

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    Hi Allan,

    I was able to make this work with a very barebones html file utilizing CDNs rather than the import. Hopefully I've been able to make my case with the other files I sent for the React approach, please let me know if I can be of any other assistance.

    I think for now I'm going to try and do a mix of Node and the CDNs to get the buttons. Then depending on what you find I'll switch back to just importing.

    Thanks for the great tool!

    Code below:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <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://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.2.0/css/bootstrap.min.css"
        />
        <link
          rel="stylesheet"
          type="text/css"
          href="https://cdn.datatables.net/1.13.4/css/dataTables.bootstrap5.min.css"
        />
        <link
          rel="stylesheet"
          type="text/css"
          href="https://cdn.datatables.net/buttons/2.3.6/css/buttons.bootstrap5.min.css"
        />
      </head>
      <body>
        <table id="myTable" 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>$320,800</td>
            </tr>
            <tr>
              <td>Garrett Winters</td>
              <td>Accountant</td>
              <td>Tokyo</td>
              <td>63</td>
              <td>2011-07-25</td>
              <td>$170,750</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>$86,000</td>
            </tr>
            <tr>
              <td>Cedric Kelly</td>
              <td>Senior Javascript Developer</td>
              <td>Edinburgh</td>
              <td>22</td>
              <td>2012-03-29</td>
              <td>$433,060</td>
            </tr>
            <tr>
              <td>Airi Satou</td>
              <td>Accountant</td>
              <td>Tokyo</td>
              <td>33</td>
              <td>2008-11-28</td>
              <td>$162,700</td>
            </tr>
            <tr>
              <td>Brielle Williamson</td>
              <td>Integration Specialist</td>
              <td>New York</td>
              <td>61</td>
              <td>2012-12-02</td>
              <td>$372,000</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>
    
        <!-- <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
        <script src="https://cdn.datatables.net/1.11.4/js/jquery.dataTables.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script>
        <script src="https://cdn.datatables.net/v/bs5/jszip-2.5.0/dt-1.13.4/b-2.3.6/b-colvis-2.3.6/b-html5-2.3.6/b-print-2.3.6/datatables.min.js"></script> -->
    
        <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
        <script src="https://cdn.datatables.net/1.13.4/js/jquery.dataTables.min.js"></script>
        <script src="https://cdn.datatables.net/1.13.4/js/dataTables.bootstrap5.min.js"></script>
        <script src="https://cdn.datatables.net/buttons/2.3.6/js/dataTables.buttons.min.js"></script>
        <script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.bootstrap5.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/pdfmake.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.53/vfs_fonts.js"></script>
        <script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.html5.min.js"></script>
        <script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.print.min.js"></script>
        <script src="https://cdn.datatables.net/buttons/2.3.6/js/buttons.colVis.min.js"></script>
        <!-- <script src="dtTest.js"></script> -->
        <script>
          $(document).ready(function () {
            var table = $("#myTable").DataTable({
              lengthChange: false,
              // dom: 'Bfrtip',
              buttons: ["copy", "excel", "pdf", "colvis"],
            });
    
            table
              .buttons()
              .container()
              .appendTo("#myTable_wrapper .col-md-6:eq(0)");
          });
        </script>
      </body>
    </html>
    
    
  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    I've sent an access request for the video.

    Also, in the repo (many thanks for that!) it asks for a login. Can you tell me how I can see the error?

    Thanks,
    Allan

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    I granted the Google Drive access and I'm sorry is GitHub asking for a login or the actual login page on prams-portal site?

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    Also I was able to mix all this together and get it working on my actual project, a few CSS/BS5 things to fix but its such a relief to see the buttons working.

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    the actual login page on prams-portal site?

    The app. I npm start it and then the browser shows me:

    Allan

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    Oh ok sorry should have told you its not fully functional at the moment.
    Please go to the bar chart icon and click the data view button, no login required.

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    Just throwing it out there, but we have go to meeting (screen share ) and I can jump on with you if you would like. I would just send an invite via your email that I have from the GDrive request. I want to respect your time and I'm happy for the quick responses via forum.

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    I just get "Link 1", "Link 2", "Link 3" in all four of the icons down the left I'm afraid.

    Allan

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Also yes, I'd like to get this working locally if that's okay. It will make experimenting with it to figure out what is going wrong much more tractable.

    Allan

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    Hmm not sure what's up with the links. I sent over the request and I'll hop on now.

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    I was able to fix the repo with the most current files I have, when I cloned it from the other repo it had older data, apologies I'm still new to all these tools.

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    No worries - thanks for helping me getting the demo setup so I can debug it!

    I've got it running now, but it looks like it is using the files from our CDN, so it appears to be working. What do I need to do to get it into the broken state with imports?

    Also apologies, I'm not going to make a call just now. Its gone 5pm here in the UK and I need to drop offline for a bit. I'll hopefully be able to look at it more this evening, but it might be tomorrow morning. If you can tell me how to get the broken import to happen, hopefully I can either suggest a resolution or apply any fixes needed to Buttons.

    Regards,
    Allan

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    No worries, completely understandable I'm usually in by 8am USA, 1pm your time if that works, meanwhile I'll work on updating the code to the broken state with comments to hopefully help walk you though what's going on. Again thank you so much for the support!

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    Alright, created a new branch "broken-state" with the lines to toggle to show it working and then with the pdfMake error posted above. In the dataTableData.js file you should see some comments explaining what to do.

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Many thanks! I can reproduce the error now. It takes me very quickly into WebPack hell. The app uses Create React App, which generates a WebPack config via the react-scripts package. Now part of the problem here is going to be that I'm not very familiar with React, but I think this is more of a WebPack issue and it always gives me a headache!

    What appears to be happening is that WebPack is attempting to support ES modules by converting them to CommonJS modules. The issue with that is that it doesn't extend the modules in quite the same was a ES modules, causing the issue we are seeing here.

    There are a few ways to address this - none of them pleasant for either of us:

    • Convert the app to use only ES modules - no CommonJS. I've no idea where to start with that for Create React App!
    • I was going to suggest using CommonJS's require() - but this issue suggests that might not be an option!
    • I rewrite (and break APIs) to support WebPack's bundling here.
    • Use Vite instead of CRA.

    I'd say that since you have a workaround using the CDN for the moment, stick with that until I sit down and focus fully on a proper React component for DataTables. Out of that work I hope to get a better understanding of the eco-system, particularly Create React App and its modules.

    Blood, sweat and tears are likely to be involved from previous experiences... ;)

    Allan

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    I wanted to try it with Vite, just to confirm my sanity, and here is a little React app with the export buttons.

    So yes, most certainly something to do with WebPack's ESM "compatibility".

    Allan

  • CodyPramsCodyPrams Posts: 12Questions: 0Answers: 0

    Thank you so much for looking into this! I'll admit its all over my head I'll show this to our other dev and see what he can make of it.

    Since it sounds like its not great for either of us I'll continue to use the CDNs and CSS links as they appear to be working so far with no consequence.

    Thanks again!

Sign In or Register to comment.