Преобразование файла .xlsx с объединенными ячейками в JSON с помощью SheetJS

#javascript #excel #sheetjs

#javascript #excel #sheetjs

Вопрос:

Я пытаюсь прочитать файл .xlsx с помощью SheetJS и преобразовать его в JSON. Я могу прочитать и преобразовать простой (без объединенных ячеек) файл .xlsx в JSON, но я не понимаю, как правильно использовать объединенные ячейки.

Проблема в том, что у меня есть файл .xlsx с продуктами на разных языках.

Я пытался искать решение на разных веб-сайтах и в репозитории SheetJS на github https://github.com/sheetjs/js-xlsx/#json с посредственным успехом. В основном рассматривается, как писать объединенные ячейки.

 function handleFile(e) {
   var files = e.target.files, f = files[0];
   var reader = new FileReader();
   reader.onload = function(e) {
      var data = new Uint8Array(e.target.result);
      var workbook = XLSX.read(data, {type: 'array'});
      let result = '';
      let sheet_name_list = workbook.SheetNames;
      // iterate through sheets
      sheet_name_list.forEach(function (y) {

         workbook.Sheets[y]['!merges'].map(r => {
             let startChar = XLSX.utils.encode_range(r).split(':')[0].replace(/[^a-zA-Z] /g, '');
             let endChar = XLSX.utils.encode_range(r).split(':')[1].replace(/[^a-zA-Z] /g, '');
             let number = XLSX.utils.encode_range(r).split(':')[0].match(/[ -]?d (?:.d )?/g)[0];
             for (let i = numbersFromLetters(startChar); i < numbersFromLetters(endChar); i  ) {
                workbook.Sheets[y][numbersToLetters(i   1)   number] = {t:'s'};
                workbook.Sheets[y][numbersToLetters(i   1)   number].v = workbook.Sheets[y][XLSX.utils.encode_range(r).split(':')[0]].v;
                workbook.Sheets[y][numbersToLetters(i   1)   number].h = workbook.Sheets[y][XLSX.utils.encode_range(r).split(':')[0]].v;
                workbook.Sheets[y][numbersToLetters(i   1)   number].w = workbook.Sheets[y][XLSX.utils.encode_range(r).split(':')[0]].v;
                workbook.Sheets[y][numbersToLetters(i   1)   number].r = '<t>'   workbook.Sheets[y][XLSX.utils.encode_range(r).split(':')[0]].v   '</t>';
             }

         });   
         // Convert the cell value to JSON
         //let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y]);
         //let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y], {range: 1});
         let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y], {header: 1});
         //let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y], {skipHeader: true});
         //let roa = XLSX.utils.sheet_to_json(workbook.Sheets[y], {header: 1, range: 1});
         if (roa.length > 0) result = roa;

      });
      console.log(result);
   };
   reader.readAsArrayBuffer(f);
}
 

Для лучшего восприятия это пример файла Excel с объединенными языковыми ячейками:
введите описание изображения здесь

и я хочу этот результат:

 [
   { "languages": 
      [
         {
            "language": "US", 
            "name": "blue pants"
         },
         {
            "language": "DE", 
            "name": "blaue Hose"
         },             
         {
            "language": "ES", 
            "name": "pantalones azules"
         }
      ],
      "price": 29.9,
      "category": "pants"
   },
   ...
]
 

В зависимости от того, какую часть комментируемого кода я выполняю, я получаю разные результаты, которые выглядят похожими на код, который я хочу достичь или, по крайней мере, могу работать дальше. Но при каждом исходе мне нужно еще повозиться, и мне кажется, что может быть лучшее решение.

Ответ №1:

 const workbook = XLSX.readFile(fileName, readOptions);
    const sheetNames = workbook.SheetNames;
    for (let worksheet of sheetNames) {
      if (workbook.Sheets[worksheet]['!merges'])
        workbook.Sheets[worksheet]['!merges'].map((merge) => {
          const value = XLSX.utils.encode_range(merge).split(':')[0];
          for (let col = merge.s.c; col <= merge.e.c; col  )
            for (let row = merge.s.r; row <= merge.e.r; row  )
              workbook.Sheets[worksheet][String.fromCharCode(65   col)   (row   1)] = workbook.Sheets[worksheet][value];
        }); 

Комментарии:

1. Добро пожаловать в SO. Пожалуйста, не публикуйте ответы только для кода, добавьте небольшое текстовое объяснение о том, почему и как работает ваш код.