Excel Button not showing up using Webpack

Excel Button not showing up using Webpack

ricgarcasricgarcas Posts: 1Questions: 1Answers: 0

Hello guys,

Im trying to insert the Excel button but I can't seem to make it appear.

Here's what my code looks like:

import * as $ from 'jquery';

import 'datatables';
import * as JSZip from 'jszip';
import 'datatables.net-buttons';

export default (function () {

    class UsuariosIndex {
        constructor() {
            if ($('#usuarios-index').length > 0) {
                this.init();
            }
        }

        init () {
            
            let DTUsuarios = $('.table-usuarios').DataTable({
                language: window.dataTable.language,
                "order": [],
                iDisplayLength: 100,
                scrollY: '50vh',
                scrollX: true,
                autoWidth: false,
                dom: 'Blftip',
                buttons: [
                         'excel'
                    ]
            }); 
        }
    }

    let usuariosIndex = new UsuariosIndex();
}());

My package.json:

{
  "dependencies": {
    "datatables.net": "^1.10.16",
    "datatables.net-buttons": "^1.5.1",
    "jquery": "^3.2.1",
    "jszip": "^3.1.5",
  }
}

I've tried using require instead of import, and it still doesnt work. The console doesn't show any errors whatsoever.
Do you know what could be causing this issue? Im stuck. :/

Thanks a lot.

Answers

  • allanallan Posts: 61,439Questions: 1Answers: 10,053 Site admin

    You need to add:

    import './node_modules/datatables.net-buttons/js/buttons.html5';
    

    as well. The file that actually define the button behaviour are separate from the main file (e.g. if you don't need the Flash export buttons, it won't include them).

    Allan

  • vctlsvctls Posts: 5Questions: 1Answers: 0
    edited September 2018

    I'm having the same issue using Webpack and Encore on a Symfony project.
    I already imported buttons.html5.
    Copy and CSV buttons are working fine, only the Excel button won't show up.
    I'm guessing this might have something to do with JSZip.
    I tried importing it in different ways, and adding it to externals, but still no luck.

    Edit: it works when putting JSZip in window.
    But I wish there was a way to avoid that.

  • allanallan Posts: 61,439Questions: 1Answers: 10,053 Site admin

    If you are using CommonJS, then yes, it is possible by passing JSZip in at the third parameter to the import.

    Allan

  • vctlsvctls Posts: 5Questions: 1Answers: 0
    edited September 2018

    I'm sorry, I'm not even sure how to do that :/
    I'm using ES6 imports for all of my dependencies.

    import $ from 'jquery';
    import 'bootstrap';
    import moment from 'moment';
    import jszip from 'jszip';
    import 'datatables.net-bs4';
    import 'datatables.net-responsive-bs4';
    import 'datatables.net-select-bs4';
    import 'datatables.net-buttons-bs4';
    import 'datatables.net-buttons/js/buttons.html5';
    

    That works for everything, except the sneaky Excel button.

    Should I do something like this?

    require('datatables.net-buttons/js/buttons.html5')($, jszip);
    

    I tried other that, among other syntaxes, but I never manage to even get into that if statement.
    When I debug the scripts, it always enters the first if statement, the one for AMD, supposedly.
    Unless I change the order of the statements myself, in which case it does enter the CommonJS part, but then I get this error:
    $.fn is undefined, can't access property "dataTable" of it at this line:

    if ( ! $ || ! $.fn.dataTable ) {
    
  • justinmohjustinmoh Posts: 1Questions: 0Answers: 0

    This could help: require JSZip in global scope so that your buttons.html5.js finds it.

    // app.js
    window.JSZip = require('jszip')
    .
    .
    .
    import 'datatables.net-bs4'
    import 'datatables.net-buttons-bs4'
    import 'datatables.net-buttons/js/buttons.html5.js'
    
  • vctlsvctls Posts: 5Questions: 1Answers: 0

    Yeah, that works, as I stated in my first comment.
    But I'd prefer not to use global variables.
    After all that's one of the points of using Webpack.

  • allanallan Posts: 61,439Questions: 1Answers: 10,053 Site admin

    I reckon the easiest (and most intuitive to me) way to address this is for me to add a couple of methods that let's you set the PDFMake and JSZip libraries externally. To that end, I've just committed a change that allows that. e.g.

    $.fn.dataTable.Buttons.jszip( jszip );
    

    Regards,
    Allan

  • alexisdielalexisdiel Posts: 1Questions: 0Answers: 0

    This way that I've used to work correctly with webpack

    import pdfMake from "pdfmake/build/pdfmake";
    import pdfFonts from "pdfmake/build/vfs_fonts";
    pdfMake.vfs = pdfFonts.pdfMake.vfs;
    
    import * as JSZip from "jszip";
    window.JSZip = JSZip;
    
    import "datatables.net-buttons";
    import "datatables.net-buttons/js/buttons.html5.js";
    import "datatables.net-buttons/js/buttons.print.js";
    
This discussion has been closed.