Sheetjs: TypeError: Object doesn't support property or method 'charCodeAt'

Created on 18 Jan 2017  Â·  10Comments  Â·  Source: SheetJS/sheetjs

EDIT by @SheetJSDev: the recommended ArrayBuffer approach is summarized in the wiki h/t @Aymkdn

Hi Everyone,
Currently I use xlsx to read content file excel, but I have problem when I read file, The image description error bellow, now I use IE 11
error

Please help me. Tks you so much.

All 10 comments

@jindovu can you share a code sample that shows this? If I had to guess, you are passing a non-string object (like a Uint8Array) but the reader is expecting a binary string.

Hi reviewher
This is my code, I write directive to read content from Excel file and browser chrome and Fifox still working fine but IE not working, Please take a look the code bellow
`.directive("fileread", [
function () {
return {
scope: {
opts: '='
},
link: function ($scope, $elm, $attrs) {
$elm.on('change', function (changeEvent) {
var reader = new FileReader();

                        reader.onload = function (evt) {
                            $scope.$apply(function () {
                                var filePath = $elm.val();
                                if (filePath.indexOf("csv") >= 0 || filePath.indexOf("xls") >= 0 || filePath.indexOf("xlsx") >= 0) {
                                    var data = evt.target.result;
                                    var workbook = XLSX.read(data, { type: 'binary' });
                                    var dataJson = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);
                                    $scope.opts.data = dataJson;
                                }
                            });
                        };

                        var isVersionIe = false || !!document.documentMode;
                        if (isVersionIe) {
                            reader.readAsArrayBuffer(changeEvent.target.files[0]);
                        } else {
                            reader.readAsBinaryString(changeEvent.target.files[0]);
                        }
                    });
                }
            }`

@jindovu as I suspected, the problem is that you aren't always passing a binary string.

readAsBinaryString will set the result evt.target.result to a binary string, suitable for the binary type. readAsArrayBuffer will return an array buffer and you have to process it. In the demo, the array buffer is converted to a base64 string: https://github.com/SheetJS/js-xlsx/blob/master/index.html#L226-L233 You need something similar.

Do you think it's worth adding an example using angular?

Hi,

I'm not sure your problem is the same, but I guess it's related.

When we try to read a file using readAsArrayBuffer (https://developer.mozilla.org/en-US/docs/Web/API/FileReader/readAsArrayBuffer) and pass it to XLSX.read with option type:"buffer", then we receive a JavaScript error: Unsupported file undefined (from readSync).

If we pass it to XLSX.read with option type:"binary", then we receive another JavaScript error: TypeError: f.charCodeAt is not a function from firstbyte().

The typical code to read a file would be:

document.getElementById('file-object').addEventListener("change", function(e) {
  var files = e.target.files,file;
  if (!files || files.length == 0) return;
  file = files[0];
  var fileReader = new FileReader();
  fileReader.onload = function (e) {
    var filename = file.name;
    // call 'xlsx' to read the file
    var oFile = XLSX.read(e.target.result, {type: 'binary', cellDates:true, cellStyles:true});
  };
  fileReader.readAsArrayBuffer(file);
});

Example of the problem: http://codepen.io/Aymkdn/pen/YZqdqE

To fix this issue I used http://stackoverflow.com/questions/18582643/alternative-to-readasbinarystring-for-ie10 so I pre-process my file before sending it to XLSX.read:

document.getElementById('file-object').addEventListener("change", function(e) {
  var files = e.target.files,file;
  if (!files || files.length == 0) return;
  file = files[0];
  var fileReader = new FileReader();
  fileReader.onload = function (e) {
    var filename = file.name;
    // pre-process data
    var binary = "";
    var bytes = new Uint8Array(e.target.result);
    var length = bytes.byteLength;
    for (var i = 0; i < length; i++) {
      binary += String.fromCharCode(bytes[i]);
    }
    // call 'xlsx' to read the file
    var oFile = XLSX.read(binary, {type: 'binary', cellDates:true, cellStyles:true});
  };
  fileReader.readAsArrayBuffer(file);
});

Codepen of the fix: http://codepen.io/Aymkdn/pen/aJNPMV

I hope it will help

@Aymkdn the web demo actually does this conversion. Should this logic be lifted into the read function?

@SheetJSDev yes, it could be into read, but I guess it's also OK to have it as an example into this issue, for later reference for someone else. So it's up to you :-) If you want to add it, let me know and I'll create a pull request.

@Aymkdn If you have a moment can you add the body of the comment to a page in the project wiki? That way if things change we can modify the recommendation.

@Aymkdn
Thank you for resolving my problem at the beginning, but do you know if this pre-processing would affect the date format shown in the spreadsheet? Can you tell if it is possible? Because I am finding divergence with the date displayed on the spreadsheet with the date parsed

@VictorLessa > honestly, I don't know… Sorry.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

eyalcohen4 picture eyalcohen4  Â·  3Comments

jamespan0 picture jamespan0  Â·  3Comments

dullin picture dullin  Â·  3Comments

jamesbillinger picture jamesbillinger  Â·  4Comments

sangpuion picture sangpuion  Â·  3Comments