Alasql: Error while using with TypeScript: Error: "Please include the xlsx.js library"

Created on 7 Jun 2018  路  9Comments  路  Source: agershun/alasql

I am working on a project which is created with create-react-app which has TypeScript version. You can see from here: https://github.com/Microsoft/TypeScript-React-Starter

The library is added to package json as:
"alasql": "^0.4.5"

The library is imported like:
import * as alasql from 'alasql';

When it is executed like:

const opts = [{ sheetid: fileName, header: true }];
alasql(`SELECT * INTO XLSX("${fileName}.xlsx",?) FROM ?`, [opts, [list]]);

the app crashes and the error message is:
Error: Please include the xlsx.js library

! Question

All 9 comments

Does it work if you select into a csv file? "SELECT * INTO CSV"?

The solution is to include the xlsx.js library (as stated in the error message)

Have a look at https://github.com/SheetJS/js-xlsx

Any news on this?

I tried "SELECT * INTO CSV", it doesn't crash but the generated file is not a valid file.

I checked the code and saw that the XLSX is taken from XLSX = utils.global.XLSX || null; where the global is defined like

utils.global = (function() {
    try {
        return Function('return this')();
    } catch (e) {
        //If Content Security Policy
        var global = self || window || global;

        if (global) {
            return global;
        } else {
            throw new Error('Unable to locate global object');
        }
    }
})();

So I imported xlsx library and put the XLSX into window like (window as any).XLSX = xlsx; but it is still not working. However I can reach to window.XLSX from browser console.

I also tried to add the xlsx into the HTML with script tag <script lang="javascript" src="/xlsx.min.js"/> but the typescript project doesn't compile when there is a javascript file referenced in a script tag.

How should I include the xlsx.js library for alasql.js to see it?

I also tried to see what is in utils.global by logging it like console.log((alasql as any).utils.global) and it seems it is referenced to Window and it has XLSX in it.

It seems like the issue is getXLSX function. utils.isBrowserify is true when importing the package from TypeScript file like import * as alasql from 'alasql';, so it falls into the first condition and never assigns the XLSX. BTW the Window.XLSX exists at that moment. I have no idea why the first condition is empty. You must be knowing the reason better.

var getXLSX = function() {
    var XLSX = null;
    /* If require() shuold be supported else take from global scope */
    if (utils.isNode || utils.isBrowserify || utils.isMeteorServer) {
        /*not-for-browser/*
        XLSX = require('xlsx') || null;
        //*/
    } else {
        XLSX = utils.global.XLSX || null;
    }

    if (null === XLSX) {
        throw new Error('Please include the xlsx.js library');
    }

    return XLSX;
};

So if the function would be like this it would do the same thing for both conditions. (Since the first condition is empty anyway) and it fixes the TypeScript issue.

var getXLSX = function() {
    var XLSX = (utils.global && utils.global.XLSX) ? utils.global.XLSX : null;

    if (null === XLSX) {
        throw new Error('Please include the xlsx.js library');
    }
    return XLSX;
};

Would it be OK to change the function like this?

Thank you so much for your time to look into this.

The /*not-for-browser/* is used to have code that compiles both to a node version and for a browser version. Now, the problem is that typescript is handeling the default - the node version. But actually it should use the browser version. What part of the code is default would not be a large change. Ill look into it next weekend.

Awesome. Thanks.

It was a bit more cryptic than expected.

I added a new function: alasql.setXLSX(...) so you can load XLSX manually and parse it into alasql instead of it trying to load XLSX.

Please try this and let me know if it fixed this.

  • Make sure you are using the latest code from this repo by replacing "alasql": "^0.4.5" with "alaswl": "github:agershun/alasql" in package.json
  • Do a npm install xlsx
  • Include XLSX with a import { XLSX } from 'xlsx'
  • Before using alasql do a alasql.setXLSX(XLSX);
  • See if it works.

I tried it and I got error while calling alasql.setXLSX(XLSX); function because the setXLSX function doesn't exist in alasql.js.

Also I have to import the alasql like const alasql = require('alaswl'); instead of import * as alasql from 'alaswl';. Otherwise the compilation fails with error ... alasql.d.ts is not a module.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mathiasrw picture mathiasrw  路  5Comments

SWard1992 picture SWard1992  路  3Comments

DickSwart picture DickSwart  路  6Comments

umasudhan picture umasudhan  路  4Comments

SamanthaAdrichem picture SamanthaAdrichem  路  4Comments