...

Парсинг таблиц Excel

Тема в разделе "Примеры сценариев", создана пользователем lattelix, 18 июн 2023.

  1. lattelix

    lattelix Новичок

    Всем привет! Здесь описан способ получения данных из таблиц с помощью сторонней библиотеки от https://sheetjs.com.

    Для парсинга нужен файл библиотеки - можно скачать по ссылке https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
    (к сожалению не получилось прикрепить этот файл к статье)
    Файл самой таблицы тоже не получилось прикрепить, по этому вот его описание:
    1. Вкладка в таблице называется "Лист1"
    2. Названия столбиков и содержимое не важны.
    upload_2023-6-18_9-39-30.png
    В статье есть два варианта получения данных. В первом варианте очень мало кода и он отлично работает на формах приложения, но не на формах задачи в бизнес процессах, так же он нужен скорее для ознакомления и понимания принципе работы решения. Во втором варианте количество кода и сложность его описания сильно возрастают, но он везде работает и с ним у меня уже реализовано решение для парсинга данных из excel прямо в таблицу на форме.

    ВАРИАНТ 1:
    Далее по пунктам на примере формы редактирования.
    1. На вкладке "файлы" загрузите xlsx.full.min.js полученный по ссылке.
    upload_2023-6-18_9-40-26.png
    2. Добавить в контекст приложения, а затем на форму свойство типа Файлы (один) и свойство типа Строка.
    upload_2023-6-18_9-41-14.png
    3. Добавьте в сценарии формы один из следующих вариантов
    Спойлер: Текст сценария функции 1: Получение значения одной ячейки
    Код:
    
    import * as XLSX from 'xlsx.full.min.js';

    async function readXLSX(): Promise<void> {
        
    // Получаем бинарные данные файла
        
    const url await Context.data.faily!.getDownloadUrl();
        const 
    req await fetch(url);
        const 
    data await req.arrayBuffer();

        
    // Читаем excel-файл
        
    let workbook XLSX.read(data);
        
    let cell_value workbook.Sheets['Лист1']['A1'].v;
        
    Context.data.stroka cell_value;
    }
    Спойлер: Текст сценария функции 2: Получение всех значений из столбца
    Код:
    
    import * as XLSX from 'xlsx.full.min.js';

    async function readXLSX(): Promise<void> {
        
    // Получаем бинарные данные файла
        
    const url await Context.data.faily!.getDownloadUrl();
        const 
    req await fetch(url);
        const 
    data await req.arrayBuffer();

        
    // Читаем excel-файл
        
    const workbook XLSX.read(data);
        const 
    sheet workbook.Sheets['Лист1'];

        
    // Получаем ключи заполненных ячеек в столбце A
        
    const cols Object.keys(sheet).filter((i) => i.match(/[A]{1}\d/g));

        
    let stroka '';
        for (
    let c of cols) {
            
    stroka stroka sheet[`${c}`].' ';
        }
        
    Context.data.stroka stroka;
    }
    4. На событие изменения свойства Файлы на форме повесьте запуск функции xls из сценария.

    Пояснение
    Библиотека выдает нам объект заполненных ячеек на Листе в формате: Лист1: { A1: {}, A2: {}, …, B1: {}, … }, поэтому, для получения значений из одного столбца, нам необходимо отфильтровать ключи. В данном случае, для фильтрации используется регулярное выражение.
    Excel-файл для примера во вложении.
    Подробнее о работе с библиотекой XLSX можно ознакомиться по ссылке: https://docs.sheetjs.com/docs/getting-started/example

    ВАРИАНТ 2:
    1. Выведите на форму свойства Файлы (file) и свойство Таблица (table) в которую вы будете загружать данные.
    2. Добавьте на форму виджет "Код" в который поместите код из спойлера:
    Спойлер: Код
    Код:
    
    <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script>
    <script>
    function readData (data) {
    const workbook = XLSX.read(data);
    const sheet = workbook.Sheets['Лист1'];
    const rows = Object.keys(sheet).filter((i) => i.match(/[A]{1}\d/g));
    <%=Scripts%>.fillRows(rows, sheet)
    }
    </script>
    3. В сценариях формы добавьте скрипт:
    Спойлер: Скрипт парсера таблицы
    Код:
    
    declare const readData: Function

    // Парсинг таблицы. Тело функции в виджете "код"
    async function xls(): Promise<void> {
        if (
    Context.data.file) {
            const 
    url await Context.data.file.getDownloadUrl();
            const 
    req await fetch(url);
            const 
    data await req.arrayBuffer();

            
    readData(data)
        }
    }

    // Заполнение массива данными из файла
    async function fillRows(rowsanysheetany): Promise<void> {
        
    // Проходим циклом по строкам (отфильтрованным значениям столбика А)
        
    for (let r 2rows.length 1r++) {
            
    let row Context.data.table.insert();
            
    // К букве столбика прибавляем номер строки из переменной цикла и получаем ключь свойства массива
            
    row.column1 sheet[`${'A' r}`].v;
            
    row.column2 sheet[`${'B' r}`].v;
        }
        
    Context.data.table Context.data.table;
    }
    Пояснение:
    В бизнес процессах есть баг из-за которого не получается воспользоваться в скрипте загруженными на формы задач файлами. Из-за этого пришлось дробить код на функции и отправлять данные файла в скрипт на форме в виджете "Код", откуда получать массив снова в сценарии. Зато работает)
    Последнее редактирование: 18 июн 2023