1. Вступайте в наш Telegram чат: https://t.me/a_parser Нас уже 400+ и мы растем!
    Скрыть объявление

Сохранение результатов в формате Excel (.xlsx)

Описание способа сохранения данных в XLSX

Метки:
  1. Support
    В техническую поддержку довольно часто поступают вопросы о возможности сохранять результаты парсинга сразу в виде xlsx файлов (стандартный формат Excel). Обычно мы рекомендуем использовать CSV, т.к. это по сути текстовый формат и выводить в таком виде результаты можно без каких-либо дополнений.
    Но, благодаря возможности подключать Node.js модули, стало возможным сохранение в XLSX. Стоит сразу отметить, что это требует некоторых дополнительных манипуляций, но в целом в этом нет ничего сложного. И в этой статье будет показан реальный пример парсинга с сохранением в Excel.

    Рассмотрим такую задачу:
    Решение будет состоять из 2-х этапов:
    1. сбор данных и их подготовка, на выходе должен получиться текстовый файл с данными
    2. обработка и сохранение в Excel, на выходе должен быть xlsx файл
    Первый этап довольно стандартный и на самом парсинге мы не будем останавливаться. Важным моментом здесь является сохранение спаршенных данных. Нам уже сейчас нужно определять на каком листе будет находится каждый товар, а также формировать данные для записи в файл.
    Поэтому мы будем каждый товар сохранять отдельной строкой в JSON формате, а первой строкой обязательно укажем массив названий столбцов.
    Код:
    ["Category","Name","Price"]
    {"sheet":"Samsung","data":["Телевизоры","Телевизор Samsung UE40NU7170U ","33990.00"]}
    {"sheet":"LG","data":["Телевизоры","Телевизор LG 49UK6300 ","37990.00"]}
    {"sheet":"LG","data":["Телевизоры","Телевизор LG 43UK6450 ","35990.00"]}
    {"sheet":"Samsung","data":["Телевизоры","Телевизор Samsung UE32M5550AU ","25990.00"]}
    {"sheet":"LG","data":["Телевизоры","Телевизор LG 43UK6300 ","32990.00"]}
    {"sheet":"Samsung","data":["Телевизоры","Телевизор Samsung UE49N5510AU ","37990.00"]}
    {"sheet":"LG","data":["Телевизоры","Телевизор LG 49UK7550 ","52990.00"]}
    {"sheet":"LG","data":["Телевизоры","Телевизор LG 55UK6750 ","57990.00"]}
    {"sheet":"Panasonic","data":["Телевизоры","Телевизор Panasonic TX-55FXR600 ","54990.00"]}
    {"sheet":"Samsung","data":["Телевизоры","Телевизор Samsung UE49NU7670U ","54990.00"]}
    {"sheet":"LG","data":["Телевизоры","LED-4K UHD телевизор 66"+ LG 70UK6710 ","99990.00"]}
    {"sheet":"Samsung","data":["Телевизоры","Телевизор Samsung UE43NU7170U ","35990.00"]}
    {"sheet":"Apple","data":["Ноутбуки Apple MacBook","Ноутбук Apple MacBook Pro 13 i5 2.3/8/128Gb SG (MPXQ2RU/A) ","94990.00"]}
    {"sheet":"Apple","data":["Ноутбуки Apple MacBook","Ноутбук Apple MacBook Pro 13 i5 2.3/8/128Gb Silver (MPXR2RU/A) ","94990.00"]}
    {"sheet":"HP","data":["Ноутбуки","Ноутбук HP 15-rb040ur 4UT06EA ","16990.00"]}
    {"sheet":"Lenovo","data":["Ноутбуки","Ноутбук Lenovo IdeaPad 330-17IKB (81DK001VRU) ","29990.00"]}
    {"sheet":"HP","data":["Ноутбуки","Ноутбук HP 15-ra072ur 3YD53EA ","23990.00"]}
    {"sheet":"HP","data":["Ноутбуки","Ноутбук HP Pavilion 13-an0072ur 5WC37EA ","45990.00"]}
    ...
    Как видно из примера выше, в каждой строке (кроме первой) есть переменная sheet - это название листа, и data - это строка данных в виде массива, где каждый элемент - это отдельная ячейка.

    Настроив сохранение в таком виде, можно переходить ко 2-му этапу.
    Для создания xlsx файла воспользуемся модулем Node XLSX. По ссылке можно посмотреть примеры использования и ознакомиться с возможностями.
    Устанавливаем данный модуль и приступаем к написанию небольшого JS-парсера, который должен будет сконвертировать полученные на 1-м этапе данные в нужный нам формат. В качестве запросов будет указываться файл результатов из 1-го этапа.

    Т.к. этот модуль (и в целом формат XLSX) не позволяют добавлять данные в уже существующий файл, а многопоточные чтение-добавление-запись сильно замедлят работу (либо даже могут привести к ошибкам), то воспользуемся пакетным чтением списка запросов и считаем все запросы из файла за один раз. Для этого укажем в defaultConf переменную bulkQueries и зададим большое значение, например 1000000 (чтобы гарантировано считать все данные из файла).
    Код:
    constructor() {
        this.defaultConf = {
            bulkQueries: 1000000
        };
    }
    Получив все строки (массив set.bulkQueries), парсер должен привести их к виду, который принимает модуль node-xlsx. В это же время все строки будут рассортированы по своим листам.
    Код:
    let sheets = {}, headers = JSON.parse(set.bulkQueries[0].query);
    for(let i = 1; i < set.bulkQueries.length; i++) {
        let row = JSON.parse(set.bulkQueries[i].query);
        if(!sheets[row.sheet]) {
            sheets[row.sheet] = [headers]
        }
        sheets[row.sheet].push(row.data)
    }
    
    let output = [];
    for(let sheet of Object.keys(sheets).sort((a, b) => {return a > b ? 1 : a < b ? -1 : 0})) {
        output.push({
            name: sheet,
            data: sheets[sheet]
        })
    }
    После сортировки мы получаем массив output, в необходимом виде. Остается только сформировать результирующий файл и завершить работу.

    Сохраняем получившийся парсер в отдельное задание и возвращаемся к 1-му этапу. Объединяем оба пресета в цепочку заданий, указав запуск второго с файлом результатов от первого. Этим мы автоматизируем конвертацию полученных данных.
    Указываем ссылки для парсинга, запускаем и получаем итоговый файл в формате xlsx такого вида:
    [​IMG]
    Как видно на скриншоте, для каждого производителя создан отдельный лист с данными о товарах, а значит поставленная задача решена полностью.

    Аналогичным образом можно формировать более сложные файлы, сохранять больше данных и применять форматирование.

    Получившиеся пресеты опубликованы в Каталоге: https://a-parser.com/resources/324/
    relay и Vvtex нравится это.