Как я могу проанализировать файл Excel с помощью SheetJS из внешней ссылки (Amazon S3)

Я пытаюсь проанализировать файл excel, для которого у меня уже есть URL-адрес. Я продолжаю получать разные ошибки при попытке получить доступ к файлу, чтобы он мог быть читаемым. Прямо сейчас, вот мой код:

  const input_file = doc.input_file;
  const extension = input_file.split('.').pop();



  let XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
  let oReq = new XMLHttpRequest();
  oReq.open("GET", input_file, true);
  oReq.responseType = "arraybuffer";

  oReq.onload = function(e) {
    let arraybuffer = oReq.responseText;
    /* convert data to binary string */
    let data = new Uint8Array(arraybuffer);
    let arr = new Array();
    for(let i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
    let bstr = arr.join("");

    /* Call XLSX */
    let workbook = XLSX.read(bstr, {type:"binary"});

    /* DO SOMETHING WITH workbook HERE */
    let firstSheet = workbook.SheetNames[0];
    let parsed = XLSX.utils.sheet_to_csv(firstSheet);
    console.log(parsed);
  }

  oReq.send();

текущая ошибка, которую я получаю:Error: Unsupported file NaN при попытке прочитать файл по адресу:let workbook = XLSX.read(bstr, {type:"binary"});

Я не уверен, что самый простой способ прочитать эту внешнюю ссылку. Есть идеи? Если это поможет, я использую Meteor.

4 ответов


это проверенный и верный ответ.

есть две проблемы с вашим кодом:

  1. для двоичных файлов, он должен быть!--3-->, а не let arraybuffer = oReq.responseText;

  2. на экземпляре Amazon S3 необходимо включить общий доступ к ресурсам из разных источников. Просто следуйте за официальный учебник здесь.

вот рабочий сайт CodePen:

http://codepen.io/KevinWang15/pen/GZXJKj

вы используете nodeJS?

Примечание: приведенный выше код просто использует XMLHttpRequest веб-браузера (chrome), я замечаю, что вы используете

XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest

вы используете что-то вроде nodejs? (Извините, я не знаком с Meteor)

более конкретно, вы используете driverdan/node-XMLHttpRequest ?

я экспериментировал с ним и вашим кодом, и это привело к точно то же сообщение об ошибке. Я думаю, это потому, что это XMLHttpRequest по-прежнему имеет проблему совместимости с oReq.response и oReq.responseText

если вы используете nodeJS, я рекомендую другую библиотеку:ykzts/node-xmlhttprequest

установить ему с

npm i w3c-xmlhttprequest

измените свой XMLHttpRequest на

let XMLHttpRequest = require('w3c-xmlhttprequest').XMLHttpRequest;

и это мгновенно решает проблему!


лучшей идеей может быть использование Метеора HTTP пакет чтобы получить файл. Документы здесь

добавить пакет с помощью

meteor add http

и затем использовать :

let result = HTTP.get(input_file,function (error,result){
//process result here
});

результат.данные будут содержать ваш файл Excel, который вы можете удобно анализировать с помощью SheetJS.

однако убедитесь, что вы разрешили Cross Origin на Amazon S3, или вы получите сообщение об ошибке формы:

"нет Заголовок "Access-Control-Allow-Origin" присутствует на запрашиваемом ресурсе. Происхождение "бла-бла" поэтому не допускается доступ."


XMLHttpRequest ограничен Та Же Политика Происхождения, что означает, что вы можете получить доступ только к контенту непосредственно из своего домена.

но вы можете создать службу на своем сервере, которая загрузит лист для вас и передаст его обратно клиенту.

здесь прямой учебник.

но имейте в виду, что общий подход к загрузке сторонних файлов может быть серьезной проблемой безопасности. Поэтому, если Ваш URL-адрес на листе константа вы можете рассмотреть только загрузку этой конкретной ссылки через php-скрипт и не разрешать никаких других URL-адресов.


Я закончил тем, что использовал комбинацию нескольких из этих ответов. Я хочу опубликовать его здесь на случай, если это поможет кому-то еще.

Я начал использовать HTTP-пакет Meteor, как упоминалось Ахалом.

meteor add http

Я также добавил дополнительный пакет от сообщества Meteor, который позволил добавить тип ответа.

meteor add aldeed:http

затем я использовал следующий код для преобразования в двоичный и мог продолжить чтение листа:

HTTP.get(input_file, {responseType: 'arraybuffer'}, function(error, result) {
  let data = new Uint8Array(result.content);
  let arr = new Array();
  for(let i = 0; i != data.length; ++i) arr[i] = String.fromCharCode(data[i]);
  let bstr = arr.join("");

  let workbook = XLSX.read(bstr, {type:"binary"});
  var first_sheet_name = workbook.SheetNames[0];
  let sheet = workbook.Sheets[first_sheet_name];
  let parsed = XLSX.utils.sheet_to_json(sheet);
});