Использование сторонних библиотек в прикладном коде на примере работы с Open XML

28 3

Для модификаций системы Directum RX применяется инструмент разработки DDS (Directum RX Development Studio). DDS позволяет создавать новые решения, модули, отчеты, типы сущностей или с помощью перекрытия элементов изменять базовые решения. В случаях, когда стандартная функциональность инструмента не позволяет решить определенную задачу, разработчику доступно использование классов из списка разрешенных классов и конструкций платформы .Net или использование сторонних библиотек в прикладном коде (подробно о подключении сторонних сборок описано в справке).

Сторонние библиотеки применяются также в случае необходимости использования классов, которые не входят в список разрешенных в прикладном коде. При этом необходимая функциональность реализуется как библиотека в среде Visual Studio, которая добавляется в решение и используется в прикладном коде.

Рассмотрим пример подключения сторонних сборок Open XML SDK для решения задачи чтения данных из excel-документа в систему Directum RX.

 

Пример использования Open XML для чтения excel-документов

В карточку нового типа документа «Заявка на закупку ТМЦ» добавлена табличная часть «Номенклатура» с определенным набором столбцов. Имеется шаблон excel-документа, повторяющий набор столбцов табличной части «Номенклатура». Шаблон заполняется данными вне системы и затем данные импортируются в таблицу номенклатуры документа.

Для реализации чтения данных из excel-документа используется Open XML SDK - это инструмент, предоставляющий классы для работы с документами форматов docx и xlsx. Инструмент является бесплатным (MIT) и не требует наличия MS Office.

Чтобы использовать классы Open XML в прикладном коде добавляем библиотеку DocumentFormat.OpenXml.dll и файл метаданных DocumentFormat.OpenXml.xml в сторонние сборки модуля, определяем область действия «Клиент и сервер».

 

Получить необходимые библиотеки можно при помощи диспетчера пакетов Nuget в среде разработки Visual Studio. Полученные библиотеки импортировать в инструменте разработки Directum RX.

 

После импорта библиотеки в прикладном коде можно использовать пространства имен и классы данной библиотеки. В нашем примере мы задействуем в серверном коде пространства имен для работы с excel-документом:

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml;

и объявим серверный метод чтения данных из excel-документа:

/// <summary>
/// Получить структуры данных из файла Excel.
/// </summary>
/// <returns>Матрица полей.</returns>
public static List<string[]> GetDataFromExcel(System.IO.Stream body)
{
  var result = new List<string[]>();
  
  using (var document = SpreadsheetDocument.Open(body, false))
  {
    var workbookPart = document.WorkbookPart;
    var stringTablePart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
    var stringTable = stringTablePart.SharedStringTable;
    var worksheetPart = workbookPart.WorksheetParts.First();
    var sheet = worksheetPart.Worksheet;
    var cells = sheet.Descendants<Cell>();
    var rows = sheet.Descendants<Row>();
    var maxElements = rows.First().Elements<Cell>().Count();
    
    foreach (var row in rows)
    {
      var rowData = new string[maxElements];
      for (var i = 0; i < maxElements; i++)
        rowData[i] = string.Empty;

      foreach (var cell in row.Elements<Cell>())
      {
        if (cell.CellValue != null)
        {
          var innerText = cell.DataType != null && cell.DataType == CellValues.SharedString ? 
                                                        stringTable.ChildElements[int.Parse(cell.CellValue.Text)].InnerText :
                                                        cell.CellValue.InnerText;
          rowData[CellReferenceToIndex(cell)] = innerText;
        }
      }
      
      // В обработку попадают строки, над которыми проводились какие-либо действия в редакторе,
      // включая пустые. Если в строке все ячейки пустые, то завершаем обработку.
      if (!string.IsNullOrWhiteSpace(rowData.Max()))
        result.Add(rowData);
      else
        break;
    }
  }
  
  return result;
}

В клиентском коде по действию на ленте вызывается метод GetDataFromExcel() и заполняется табличная часть данными из excel-документа. Результат представлен на скриншотах ниже.




 

Использование сторонних библиотек позволяет расширять возможности инструмента разработки Directum RX, повторно использовать имеющиеся библиотеки .Net и обходить ограничение использования запрещенных конструкций и классов в прикладной разработке Directum RX.

Андрей Посаженников
  • А почему бы не сделать напрямую из nuget? Это очень удобно.
  • Что с версионированием? Руками? Как обновлять версии? 
  • Что с конфликтами версий, когда на предприятии ставится несколько решений от разных разработчиков и там разные версии одной библиотеки?
  • Как насчет зависимостей? OpenXML зависит только от системных библиотек, другие сборки могут зависеть от сборок, которые не подключены.
  • Можно ли использовать библиотеки контролов, чтобы расширять функционал? Например нарисовать диаграмму Ганта/календарь или еще какой то сложный контрол? 

 

 

Алексей Вятчанин

Андрей, благодарю за проявленный интерес к статье.

>>А почему бы не сделать напрямую из nuget? Это очень удобно.
Согласен, оформим соответствующее пожелание к инструменту разработки.

>>Что с версионированием? Руками? Как обновлять версии?
На данный момент обновление библиотек необходимо делать вручную.

>>Что с конфликтами версий, когда на предприятии ставится несколько решений от разных разработчиков и там разные версии одной библиотеки?
Сторонняя библиотека может использоваться только в рамках того решения или модуля, в который она добавлена. Соответственно если в разработку импортируются решения, использующие одну библиотеку, проблем быть не должно.

>>Как насчет зависимостей? OpenXML зависит только от системных библиотек, другие сборки могут зависеть от сборок, которые не подключены.
Действительно, в таком случае я бы рекомендовал всю логику оформить в виде API сторонней сборки с необходимыми зависимостями, импортировать в DDS и вызывать ее методы в прикладном коде.

>>Можно ли использовать библиотеки контролов, чтобы расширять функционал? Например нарисовать диаграмму Ганта/календарь или еще какой то сложный контрол?
Да, в качестве примера приведу решение Диаграмма Ганта для модуля "Проекты".

У вас имеется какая-то практическая необходимость или теоретический интерес?

Что скажете насчёт использования Open XML для построения отчетов и добавления удобного функционала для этого?  

Авторизуйтесь, чтобы написать комментарий