Excel in Javascript

2,027 views

Published on

General concepts of building spreadsheet engine

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,027
On SlideShare
0
From Embeds
0
Number of Embeds
72
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Excel in Javascript

  1. 1. Excel на JavaScript! Viktor Turskyi CTO at WebbyLab Kyiv.js 2013
  2. 2. Бизнес задача Запускать XLS файлы со сложными математическими моделями в браузере и чтобы без сервера
  3. 3. Требования к производительности: 1. Возможность запуска крупных моделей (до 2-х миллионов ячеек, 400тыс формул, 1млн Excel функций, 50 листов) 2. Поддержка цепей вычисления на сотни тысяч ячеек 3. Высокая производительность 4. Небольшой размер файла
  4. 4. Требования к окружению ● Офлайн работа в браузере ● Работа на сервере ● Работа на планшетах(iOS, Android)
  5. 5. От заказчика получили 1. Дизайн интерфейса 2. 12 мб xls файл c формулами вида: =IF($F$36 + $AF128 <= 101; SUMPRODUCT( ($S128:OFFSET ($S128;$F$36-1;0)) * ($AG$55:OFFSET($AG$55;$F$36-1;0)) * ('Sheet25'!BY84:OFFSET('Sheet25'!BY84;$F$36-1;0) + 'Sheet25'!BY194: OFFSET('Sheet25'!BY194; $F$36-1; 0) ) ); SUMPRODUCT( ($S128:$S$155) * ($AG$55:OFFSET($AG$55;100-$AF128;0)) * ('Sheet25'!BY84:BY$111 + 'Sheet25'!BY194:BY$221) ) )
  6. 6. Почему не Google Docs API: 1. Работает только в онлайн 2. Очень медленный 3. Проблемы при конвертации некоторых xls 4. Максимум 40 тыс формул в файле
  7. 7. Вопрос №0: это возможно? :) С помощью JavaScript все возможно ;)
  8. 8. Вопрос №1: Достаточно ли у JS производительности? 1. Определяем целевые платформы (движки) a. Браузеры и их версии b. iOS устройства c. Android устройства 2. Пишем синтетический мини бенчмарк a. Математический вычисления b. Длинные цепи вычислений
  9. 9. Вопрос №2: Как вычитать данные с XLS файла? ● Необходимо вычитать значения ● Необходимо вычитать формулы ● Необходимо вычитать называние листов ● Необходимо вычитать имена диапазонов и ячеек
  10. 10. Варианты: ● Nodejs модули - не способны даже вычитать значения, сваливаются на огромных файлах. ● Ruby/Python/Perl/PHP - нет возможности получить формулы или имена ячеек
  11. 11. Что сработало? Perl (100 строк) + Windows + Win32::OLE + Excel + документация VBA = тупой дамп в JSON сырых данных.
  12. 12. Вопрос №3: Вычитали и что? 1. Нужно разобрать гору сырых данных 2. Нужно проанализировать все формулы 3. Нужно отслеживать завимости между формулами 4. Нужно это как-то хранить 5. Нужно реализовать множество функций c Excel 6. Нужен движок, который все выполнит
  13. 13. Вопрос №4: Как разобрать формулу в JS? 1. 2. 3. 4. 5. 6. Учет приоритета операторов Инфиксные/префиксные операторы Функции Ссылки на ячейки Ссылки на диапазоны Именованные адреса
  14. 14. Неправильное решение Самописный лексер и парсер: 1. Сложно 2. Долго 3. Дорого Отказались с первыми существенными проблемами приоритета операторов.
  15. 15. Правильное решение - ANTLR 1. 2. 3. 4. Генератор парсеров (включая JS) Лексический и синтаксический анализ На выходе AST (Abstract Syntax Tree) Лучшее из всего, что есть под JS (и не только) Мы используем версию 3.3 (в версии 3.4 баг в JS генераторе) http://www.antlr.org/
  16. 16. Примеры формул Formula: '=1+2*3' JS AST: [ '+', 1, [ '*', 2, 3] ] Formula: '=A1+B1' JS AST: [‘+’, ['=', 0, 0, 0], ['=', 0, 1, 0] ] Formula: ‘=SUM(B5:B100, 42)' JS AST: [ 'SUM', [ 'RANGE', 0, 1, 4, 1, 99 ], 42 ]
  17. 17. Компоненты движка ● LocalRunner - работает с файлом и определяет порядок вычислений ● Formula Evaluator - вычисляет формулу ● Address Parser - парсит адреса введенные пользователем ● Functions - реализация Excel функций
  18. 18. Реализация EXCEL функций ● Одна функция - один класс ● Все функции без побочных эффектов ● Используется принцип внедрения завимостей для подключения ● node-qunit для тестирования Пример вызова: SQRT([ 9 ]) вернет 3 SUM([2, [5, 6, 7, 9], 1 ]) вернет 30
  19. 19. Вопрос №5: зависимости ячеек A1=1 A2=A1+1 A3=A1+A2 Ячейка А1 влияет на A2 и A3 Ячейка A2 влияет на А3
  20. 20. Что представляют собой зависимости? По сути, мы имеем направленный ациклический граф (храним в JSON вместе с AST)
  21. 21. При изменении ячейки пересчитывать зависимые На тестовых файлах работает, а в реальной жизни - нет. Причина - множественные пересчеты одних и тех же ячеек.
  22. 22. Топологическая сортировка Позволяет нам вычислять ячейку один раз. На тестовых файлах работает, в реальной жизни - нет. Причина - переполнение стека вызовов.
  23. 23. Что делать? Не используйте рекурсию, сами управляйте стеком и обходите граф. Результат на реальной модели: Без сортировки - 1час С сортировкой - 6 секунд
  24. 24. Как работать с диапазонами ячеек? SUM( [ [ 21, 22, 23, 31, 32, 33 ] ] ); SUM( [ new ArrayRange([21, 22, 23, 31, 32, 33]) ] ); SUM( [ new ModelRange(model, ‘B2:C4’ ) ] );
  25. 25. Оптимизация Обращайте внимание на: 1. Рекурсивные алгоритмы 2. Большие JSON файлы(40мб повалит ваш браузер) 3. Лимиты по помяти в NodeJS (иногда невозможно обойти) 4. Копирования данных в памяти
  26. 26. Инструменты 1. ANTLR для синтаксического анализа 2. Web Workers для повышения отзывчивости интерфейса 3. Browserify для использования CommonJS модулей в браузере 4. Qunit для тестирования
  27. 27. Поддержка разных окружений Для сервера - nodejs Для браузера - browserify Для планшетов - phonegap
  28. 28. Живая демонстрация
  29. 29. Viktor Turskyi viktor@webbylab.com http://koorchik.blogspot.com http://search.cpan.org/~koorchik/ https://github.com/koorchik WebbyLab http://webbylab.com
  30. 30. WebbyLab ищет Junior Frontend Developer http://www.work.ua/jobs/1433919/

×