company_banner

Продуктивность в разработке Office Add-ins

    В разговорах об Office Add-ins (надстройки Office) часто упоминается «продуктивность». Это логично, ведь главная цель разработчиков – повышение продуктивности в работе конечных пользователей. Но продуктивность важна и для самих разработчиков. Эта статья о продуктивности в разработке. Речь пойдёт о новом JavaScript API для Office и о том, какие инструменты мы применяем для создания новых решений.




    Office Add-in за 1 день


    В декабре 2015 года меня пригласили поучаствовать в рабочей сессии по Office 365 как консультанта по созданию надстроек Office. На мероприятии собрались команды, интересующиеся продвижением своих продуктов в Office Store. Цель – за два дня погрузиться в тонкости JavaScript API для Office, сформировать концепты будущих решений и реализовать прототипы.

    На второй день в промежутках между ответами на вопросы участников у меня оставалось свободное время. Это позволило начать работу над новой идеей. В VSTO-версии расширения XLTools для Excel есть популярная среди пользователей функция – календарь для ввода дат. Мне давно хотелось реализовать её и для Office Store, но руки не доходили. А т.к. темой рабочей сессии была продуктивность, идея вписывалась как нельзя лучше, поскольку календарь в разы увеличивает скорость работы с документами, в которых требуется ввод дат.

    Задуманная функциональность


    Для примера возьмем стандартный шаблон для Excel из доступных онлайн – «Список дел»:



    Чтобы создать такой документ, откройте в Excel меню Файл > Создать > Ввести в поле «Поиск шаблонов в сети» название шаблона «Список дел».

    На экране выше видно, что в таблице присутствуют два поля с типом «Дата»: «Дата начала» и «Дата выполнения». Каждый, кому приходилось работать с датами в Excel, знает, что ввод дат сопряжён с некоторыми сложностями. Вот если бы можно было просто выбирать дату из календаря!

    Так и родилась идея. Поразмыслив, я вывел следующий список требований:
    1. Ввод даты в выбранную ячейку в один клик;
    2. Автоматическое выделение даты в календаре при выборе ячейки со значением;
    3. Наглядное отображение информации о выбранной дате (день недели, номер недели);
    4. Локализация под форматы дат в разных регионах;
    5. «Встраивание» календаря непосредственно в документ без необходимости установки дополнительных компонент.


    Реализация


    Я использую Visual Studio. Подходят и другие инструменты, такие как Napa или другой редактора кода, но с точки зрения производительности и удобства, Visual Studio – лучший вариант, т.к. позволяет за минуту создать готовый к запуску и отладке проект надстройки Office. В Napa и других сторонних редакторах отладка Office Add-ins пока не представляется возможной.

    Создание проекта


    Открываем Visual Studio > File > New > Project > Templates > Office/SharePoint > Apps > Выбираем тип приложения «App for Office». Отмечу, что на момент написания статьи Microsoft заменила название «App» на «Add-in». Наверняка в будущем поменяется и название проекта.



    Далее задаем тип приложения. Т.к. надстройка встраиваться в тело документа, выбираем тип «Content» – идеально подходит для решения поставленной задачи. Отличие типа Task pane от Content наглядно демонстрирует нижеприведённый рисунок.


    На последнем шаге нам предлагается выбрать шаблон проекта (Basic App – базовый, Document Visualization App – посложнее) и набор поддерживаемых офисных программ: Access, Excel, PowerPoint. Выбираем Basic App и поддержку Excel. Нажимаем Finish. Проект создан и готов к запуску (F5) и отладке.


    Проектирование и реализация UI


    Давайте ещё раз пройдёмся по требованиям и подумаем, как реализовать каждое из них. Начать стоит с последнего – «встраивание». Тут кроется отличительная особенность нового типа Office Add-ins. По сравнению с традиционными VSTO они не требуют установки дополнительных компонент. Т.е. если создать Excel-документ, добавить в него надстройку из Office Store и отправить документ коллегам, им не потребуется ничего дополнительно устанавливать для работы надстройки. Это ровно то, чего так не хватало пользователям VSTO-версии календаря XLTools.

    Календарь не предусматривает сложного UI. В интернете есть море свободно распространяемых JavaScript-библиотек, реализующих функционал отображения календаря. Я выбрал библиотеку Pikaday, удовлетворяющую остальным нашим требованиям на 100%. Библиотека позволяет:
    • Отображать календарь непосредственно на веб-странице приложения;
    • «Вешать» обработчик на событие «Выбор даты из календаря» (onSelect);
    • Выставлять значение выбранной в календаре даты из кода (setDate);
    • Переводить название дней недели и месяцев на нужные языки.



    Конечно, зачастую мы решаем более сложные задачи, требующие уникального дизайна. Здесь стоит обратить внимание на вышедший недавно фреймворк Office UI Fabric, предоставляющий набор CSS-классов и UI-компонентов, заранее стилизованных под офисные приложения. Стили и компоненты адаптированы для работы под все платформы, поддерживаемые Office: Mobile Apps, Web, Desktop. Использование Office UI Fabric в разы упрощает проектирование и разработку UI. Это как Bootstrap, только специально для разработчиков Office Add-ins.

    На UI ушло девять строк кода. Подключение CSS и JavaScript в файле Home.html:

        <link href="pikaday.css" rel="stylesheet" type="text/css" />
        <script src="pikaday.js" type="text/javascript"></script>
    


    Инициализация календаря в методе Office.initialize в файле Home.js:

    var calOptions = {
            showWeekNumber: true, // календарь должен отображать номера недель
            defaultDate: new Date() // по умолчанию выделяем в календаре текущую дату
        };
    
        var placeholder = $("body"); // в качестве «родительского элемента» берем body
        var picker = new Pikaday(calOptions); // инициализируем объект календаря
        placeholder.append(picker.el); // добавляем элемент календаря в body
    

    Обработка выбора даты в календаре


    Pikaday позволяет «навесить» обработчик на событие изменения даты в календаре. Получив дату, мы проставляем её в текущую выделенную ячейку, используя метод из Office API — setSelectedDataAsync:

    calOptions.onSelect = function (date) { // задаем обработчик события изменения даты
    
       	date = getLocaleShortDateString(date); // преобразуем объект Date в строку
    
           Office.context.document.setSelectedDataAsync(date, // передаем дату в виде строки
    { 
        coercionType: Office.CoercionType.Text // тип значения – «Текст»
    }, 
    function (asyncResult) { // обработчик статуса изменения значения ячейки
               if (asyncResult.status == "failed") {
                    	app.showNotification("Failed", asyncResult.error.message, 'error');
               	    }
           	}
    );
       };    
    

    В примере для работы с датой используется функция getLocaleShortDateString. Она необходима, т.к. Excel воспринимает даты как числа и отображает их в виде даты, только если у ячейки задан соответствующий формат. Проблема кроется в том, что число в ячейку мы записать можем, а вот изменить формат ячейки текущее JavaScript API не позволяет. К счастью, нашёлся обходной способ. Чтобы получить в ячейке именно дату, нужно проставить её в виде текста, соблюдая выбранный у пользователя формат региона (локали). Функция getLocaleShortDateString как раз используется для преобразования объекта Date в текстовый локализованный формат. Узнать, какой именно региональный стандарт выбран у пользователя, можно через свойство объекта context – Office.context.displayLanguage.

    function getLocaleShortDateString(d) {
        var f = getLocaleDateString(), 
     y = d.getFullYear(), 
     m = d.getMonth() + 1, 
     d = d.getDate();
    
        function z(s) {
            s = '' + s; return s.length > 1 ? s : '0' + s;
        }
    
        f = f.replace(/yyyy/, y); f = f.replace(/yy/, String(y).substr(2));
        f = f.replace(/MM/, z(m)); f = f.replace(/M/, m);
        f = f.replace(/dd/, z(d)); f = f.replace(/d/, d);
    
        return f;
    }
    function getLocaleDateString() {
    
        var formats = {
            "en-US": "M/d/yyyy",
            "ru-RU": "dd.MM.yyyy",
    	  ... // еще более 200 форматов
    		
        };
    
        return formats[Office.context.displayLanguage] || 'dd/MM/yyyy';
    }
    


    Подсветка выбранной даты в календаре


    JavaScript API для Excel позволяет обрабатывать событие изменения выделенной области ячеек. Используем это, чтобы отследить изменение пользователем выделенной ячейки:

    // обработчик изменения выделения        
    Office.context.document.addHandlerAsync(Office.EventType.DocumentSelectionChanged,
                function (eventArgs) {
                    // запрашиваем значение выделенной ячейки
                    Office.context.document.getSelectedDataAsync(Office.CoercionType.Text, 
                        {
                            // говорим, что нам необходимо фактическое значение (число)
                            valueFormat: Office.ValueFormat.Unformatted 
                        }, function (ufResult) {
                            if (ufResult.status != "failed") {
                                var value = ufResult.value;
    
                                // если не число - ничего не делаем
                                if (isInt(value) && value > 0) 
                                {
                                    // переводим число в дату
                                    var date = getJsDateFromExcel(value); 
    
                                    // работаем только с датами +-50 лет от текущей даты
                                    if (new String(date) != "InvalidDate" && 
      date.getYear() > new Date().getYear() - 50 &&
      date.getYear() < new Date().getYear() + 50) 
     				    {
    					 // подсвечиваем значение в календаре
                                        picker.setDate(date, true);
                                    }
                                }
                            }
                        });
                });
    

    «Поймав» момент выделения новой ячейки пользователем, проверяем, является ли выбранное значение датой. Чтобы получить значение из выделенной ячейки, используем функцию Office.context.document.getSelectedDataAsync, говорим ей, что вернуть нужно не отформатированное значение. В случае с датой, значением будет целое число (даты со временем не рассматриваем). Далее идут проверки на соответствие значения дате. Определить на 100%, является ли значение в ячейке датой, не представляется возможным. Так, если пользователь выберет ячейку с числом, соответствующим числовому представлению даты – алгоритм посчитает, что это и есть дата. Чтобы минимизировать количество ложных срабатываний на числа, задаём ограничение: проверка даты на +-50 лет от текущего года. Если значение подходит по всем критериям, используем для подсветки метод setDate календаря Pikaday.

    Локализация



    Сейчас Office Store поддерживает 40 языков. В примерах выше уже показано, как локализовать значение даты. Помимо даты, локализации требует также UI. В случае с календарем Pikaday всё просто:

    var myLanguage = Office.context.displayLanguage.split("-")[0];
    
    if (myLanguage == "ru") {
    calOptions.firstDay = 1;
    calOptions.i18n = {
    previousMonth: 'Предыдущий месяц',
    nextMonth: 'Следующий месяц',
    months: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 
      'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
    weekdays: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 
         'Четверг', 'Пятница', 'Суббота'],
    weekdaysShort: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
    };
    }
    

    Для начала поддерживаем 2 языка: русский и английский. Pikaday по умолчанию англоязычный. Для перевода на русский проверяем текущий регион пользователя и подставляем новые значения для текстовых надписей, если язык интерфейса русский.

    Работа с XLTools.net Calendar




    Выводы


    Меньше чем за один день мне удалось создать Office Add-in, готовый к публикации в Office Store. Такая скорость возможна благодаря опыту и готовым решениям, накопленным годами в веб-разработке. Плюсом является простота JavaScript API для Office, так же как и наличие готового фреймворка Office UI Fabric для построения UI.

    Из сложностей можно отметить, что отладка надстроек на разных платформах – неординарная задача. Уже после отправки приложения на проверку в Office Store мне пришлось побороться с отладкой, т.к. первая версия надстройки не прошла проверку из-за ошибок в работе на iPad и в Web-е. С проблемами отладки я справился и напишу об этом отдельную статью.

    Недавно надстройка XLTools.net Calendar успешно прошла проверку и теперь доступна для скачивания в Office Store. За две недели мы набрали 1832 скачивания, получили 1 отзыв и 4 максимальных оценки в Office Store. Много положительных отзывов и запросов на доработку функциональности пришло по email. В ближайшее время планируем выпустим усовершенствованный календарь с новыми опциями. Следите за обновлениями!





    Об авторе


    Петр Ляпин -Технический директор ООО «ВейвПоинт»

    Более 10 лет опыта внедрения проектов по автоматизации
    бизнес-процессов. Работал со множеством российских и
    зарубежных компаний. Основатель проекта XLTools.net.
    Microsoft
    382,28
    Microsoft — мировой лидер в области ПО и ИТ-услуг
    Поделиться публикацией

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

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое