Python для генерации статических отчетов XLSX по данным SAP-систем

от автора

Статья предназначена в первую очередь для консультантов и архитекторов, работающих с продуктами SAP, перед которыми стоит задача проектирования и реализации решения по подготовке отчетности в формате Excel. 

В настоящее время все большую популярность набирают облачные решения для визуализации данных, демонстрируя двузначный рост год-к-году по большинству показателей. Однако не все компании — клиенты поставщиков облачных решений могут позволить себе использовать “облака” по самым разным причинам: от требований безопасности данных до недостаточной функциональности или даже более высокой стоимости владения по сравнению с on-premise. 

Поэтому время от времени возникают задачи подготовки отчетности для визуализации в on-premise-инструментах. Автор долгое время работал и продолжает работать с решениями SAP, поэтому именно решения SAP (SAP BW/4, SAP S/4), как поставщики данных для отчетности, наиболее близки. Однако предлагаемый подход может быть скопирован и на другие системы-источники. Никаких препятствий к этому нет.

Задача формулируется так: реализовать on-premise решение по автоматической и регулярной подготовке отчетов по бизнес-данным SAP-систем (BW/4 или S/4).

Технические требования к отчетам:

  • минимальное время отклика при открытии отчета пользователем (2-4 сек)

  • возможность смотреть отчеты как на настольном, так и на мобильном устройстве (планшет, телефон)

  • комбинация табличных и графических представления данных на одной странице

  • несколько страниц (вкладок) с отчетами

  • корректное разбиение на страницы при печати на принтере/PDF.

  • отдельные табличные представления могут содержать большое число строк и/или столбцов (более 1 млн ячеек совокупно).

  • табличные представления 

    • реализуют кросс-табличный формат

    • содержат итоги, подитоги по строкам и столбцам.

    • содержат иерархические группировки

    • содержат данные нарастающим итогом по календарным аналитикам

    • поддерживают функции “автофильтр”, “фиксация прокрутки” и некоторые другие функции Excel (например, комментарии к ячейкам, merge cells)

    • добавление статических картинок

    • условное форматирование ячеек

  • построены по csv-выгрузкам данных из исходных систем. Это означает, что отчеты содержат данные, сформированные на момент выгрузки данных из исходных систем. Чем чаще выполняется выгрузка, тем более актуальные данные в отчетах.

Наиболее близкими стандартными инструментами SAP, подходящими для этой задачи, является a)SAP BW on HANA + Broadcaster или b)SAP BW/4 HANA + SAP BI Platform + SAP Crystal Report Enterprise + Publishing.

  • Вариант a) подходит для клиентов, остающихся пока на решении SAP BW on HANA. 

  • Вариант b) — для клиентов, перешедших на новое перспективное решение SAP BW/4 HANA и имеющих лицензии SAP BI Platform

Однако, оба этих варианта имеют те или иные ограничения, которые может быть крайне непросто или даже невозможно преодолеть, в т.ч. даже с добавлением “точечной” разработки (макросы VBA, ABAP-программы или кода на встроенном script-языке в Crystal Reports). Даже если в первоначальной постановке задачи нерешаемых требований нет, это не означает, что в будущем такие требования не появятся. Это означает, что лучше с самого начала выбрать подход, достаточно гибкий для решения как известных сейчас, так и неизвестных, но ожидаемых будущих требований. 

Очевидно, что реализация третьего варианта, варианта с) будет с высокой долей собственной разработки отдельных компонентов целевого решения. Какие же опции могут существовать для технологических решений SAP в этом случае?

Существуют классы из библиотеки ABAP2XLSX (Apache2 licence model). Написанные на ABAP, они содержат методы по генерации XLSX-файла без использования Excel: XLSX-файлы создаются напрямую из кода на ABAP. Создав программную “обертку” для этих классов внутри S/4 или BW, вы можете генерировать XLSX-файлы с требуемым форматированием. Запускать эту генерацию возможно как диалоговом, так и в пакетном (batch) режиме, что позволяет настроить автоматическую публикацию, рассылку и пр. по расписанию или событиям. 

Таким образом, все стадии процесса: извлечение данных, преобразования в формат отчета и генерация XLSX реализуются на одном языке (ABAP), и являются неотъемлемой частью хорошо знакомой в SAP-мире инфраструктуры жизненного цикла и среды выполнения ABAP-кода.

Но представляет интерес и альтернативный подход, который при определенном масштабе более эффективен и функционален. Речь идет о генерации XLSX-файла в коде на Python. Существует минимум две очень популярные python-библиотеки генерации Excel-кода: openpyxl и xlsxwriter. Это дает больше гибкости при выборе и развитии вашего решения, чем использование единственно возможной библиотеки на ABAP.  

Процессы целевого решения могут выглядеть, например, так:

  • Данные системы-источника выгружаются на регулярной основе в текстовые csv-файлы. Файлы выгружаются в каталоги сервера приложений SAP или на выделенный файловый сервер или даже в облачный каталог, если это позволяют политики безопасности.

  • csv-файлы считываются Python-программой, которая затем выполняет обработку данных (расчет подитогов, итогов, расчет нарастающих итогов, объединение нескольких наборов данных, подтягивание наименований к кодам аналитик и т.п и т.д.), генерацию и публикацию XLSX-файла

Архитектура целевого решения состоит из:

  • SAP-системы-источника данных, которая генерирует csv-файлы. Генератором файлов может быть: 

    • разработанные ABAP-программы, 

    • SAP BW OpenHub. 

В последнем случае легко настроить считывание данных из т.н. BW-запросов, в которых нередко реализуют сложную логику расчета бизнес-показателей пользовательских отчетов. Инструмент создания BW-моделей и -запросов (SAP HANA Studio BWMT) нельзя назвать инструментом “конечного пользователя”, но тем не менее он обладает мощным функционалом, позволяющим в создании даже сложных объектов во многих случаях обходиться без программирования. Однако, верно и то, что с помощью этого инструмента добиться желаемой производительности (см. требования выше) практически не представляется возможным. Поэтому результат работы BW-запроса — [кросс-]табличное представление данных — приходится визуализировать в Excel не стандартным инструментом SAP Analysis for Excel, а просто Excel. Но XLSX-файл нужно ещё подготовить и где-то разместить. А для этого применяются….

  • Python-программы, использующие библиотеки:

    • работы с данными — pandas;

    • генерации XLSX-файлов  — openpyxl или/и xlsxwriter;

    • любые другие библиотеки Python для дополнительных преобразований считанных из файлов данных;

  • Сервер для запуска Python-программ. При наличии лицензий, можно рассмотреть SAP Data Intelligence, но подойдут и другие решения. На самых начальных этапах, при небольшом количестве Python-программ — генераторов XLSX-файлов можно обойтись средствами планирования задач операционной системы

  • Полученный XLSX-файл конечный пользователь может просмотреть как в Excel, так и его opensource-аналогах (LibreOffice, OpenOffice). Последнее особенно важно для компаний, в которых не используются продукты Microsoft Office или планируется от них отказаться. Использование же стандартного on-premise SAP-инструмента для визуализации данных BW-отчетов — SAP Analysis for Excel невозможно без Excel, т.к. технически он является его addOn.

Несколько слов про центральную часть архитектуры —  Python-программы. Принимая во внимание, что генерировать XLSX-файл можно и с помощью ABAP-библиотеки, в Python это делать во многих аспектах удобнее:

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

  • Существенно больше готовых и бесплатных Python-библиотек, которые выполнят необходимые преобразования и расчеты.

  • возможно разрабатывать Python-код для генерации XLSX-файлов без доступа к SAP-системам, практически в offline-режиме. Так удобнее отдавать работу на outsource.

  • проще пользоваться всеми возможностями git-репозиториев. Да, в ABAP это тоже возможно, но это гораздо менее распространено.

  • Более лаконичный код, чем на ABAP. 

Например, при таких исходных данных для визуализации

src =  ['1;1;2020;1;10;30',         '1;1;2020;2;11;31',         '1;1;2021;1;12;32',         '1;1;2021;2;13;33',         '1;2;2020;1;14;34',         '1;2;2020;2;15;35',         '1;2;2021;1;16;36',         '1;2;2021;2;17;37',         '2;1;2020;1;18;38',         '2;1;2020;2;19;39',         '2;1;2021;1;20;40',         '2;1;2021;2;21;41',         '2;2;2020;1;22;42',         '2;2;2020;2;23;43',         '2;2;2021;1;24;44',         '2;2;2021;2;25;45',         ]

следующий компактный код

char_count  = 4 # первые 4 колонки (поля) в каждой строке данных соответствуют аналитикам. Остальные (2 в этом примере) - показатели. column_count = src[0].count(";")+1 # общее число полей в строке с данными src = list(map(lambda s: s.split(';'), src)) src = list(map(lambda row: list(map(lambda e, i: float(e) if i >= char_count else e, row, range(len(row)))), src)) df = pd.DataFrame.from_records(src, columns = list(map(lambda i: chr(65+i), range(column_count))))                 table = pd.pivot_table(df, values='E', index=['A', 'B'], columns=['C', 'D'], aggfunc=np.sum, margins = False)

выполняет преобразование строк в исходном массиве: разбивает строку на поля, разделенные ;. Последние 2 поля, которые по смыслу есть “показатели”, сохраняются как числа float. Первые 4 поля — это аналитики и хранятся как строки.

На выходе кода — кросс-таблица, в которой по строкам — развертка по полям A и B, а по столбцам — развертка по полям C и D. Поле E — один (из двух в исходных данных) показателей, используемый в кросс-таблице.

C    2020        2021 D       1     2     1     2 A B 1 1  10.0  11.0  12.0  13.0   2  14.0  15.0  16.0  17.0 2 1  18.0  19.0  20.0  21.0   2  22.0  23.0  24.0  25.0 

Если добавить код для расчета подитогов и итогов по строкам и столбцам (еще 5 — 6 строк кода), получится

C                    2020                   2021                  all total D                       1     2 total-2020     1     2 total-2021 all total A         B 1         1          10.0  11.0       21.0  12.0  13.0       25.0      46.0           2          14.0  15.0       29.0  16.0  17.0       33.0      62.0           1 total    24.0  26.0       50.0  28.0  30.0       58.0     108.0 2         1          18.0  19.0       37.0  20.0  21.0       41.0      78.0           2          22.0  23.0       45.0  24.0  25.0       49.0      94.0           2 total    40.0  42.0       82.0  44.0  46.0       90.0     172.0 all total all total  64.0  68.0      132.0  72.0  76.0      148.0     280.0 

Очевидно, что это уже почти готовая “матрица” для публикации в XLSX, после чего останется только применить форматирование [опять же, методами Python-библиотеки генерации XLSX] и файл готов. Файл можно публиковать средствами Python или операционной системы, и затем открывать в Excel, LibreOffice и т п.

Что касается производительности и потребления системных ресурсов при выполнении всех шагов процесса, начиная от выгрузки данных в csv из SAP и заканчивая генерацией XSLX-файла в Python-программе, то предложенная архитектура позволяет управлять распределением нагрузки, перенося ее с одних компонент на другие. 

Например, если Python-код потребляет слишком много памяти при выполнении подготовки данных (слишком сложные расчеты или/и миллионы строк в выгрузке), то можно, не меняя степени параллелизации выполнения Python, и не выполняя аппаратного масштабирования, рассмотреть перенос вычислений или/и большее уплотнение данных на стороне SAP-сервера. Возможно и обратное, когда уменьшать нагрузку следует уже на SAP-сервер.


ссылка на оригинал статьи https://habr.com/ru/post/599979/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *