Генерация отчётов с помощью Aspose

14 0

Для реализации отчётов в системе Directum RX в основном используется инструмент FastReport, но бывают случаи, когда невозможно использовать его из-за некоторых ограничений.

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

У заказчика была необходимость реализовать отчёт в формате Excel, при изменении данных диаграммы должны подхватывать данные и перестраиваться после генерации отчёта.

В связи с этим, появилась необходимость реализации отчёта другими средствами. В нашем случае для реализации была выбрана библиотека Aspose.Cells.

Получить библиотеку можно на официальном сайте Aspose. Но для самостоятельной разработки новой функциональности потребуется купить лицензию на Aspose.

Настройка студии для работы с Aspose

Для работы с xls-документом из кода, потребуется добавить библиотеку Aspose.Cells. Добавляем библиотеку в модуль через вкладку «Сторонние библиотеки»

 

Простой пример кейса

Для демонстрации работы с документом через Aspose.Cells рассмотрим следующий упрощённый пример задания: реализовать отчёт состоящий из 2-х страниц данных в формате Excel.

  • Виды документов. Данные для отчёта собираем по периоду, который выбирает сотрудник при вызове отчёта.

  • Диаграмма, основанная на данных из первой страницы

 

Подходы к решению

  1. Полная реализация отчёта через код
  2. Реализовать шаблон отчёта с настройкой стилей, внесения неизменных данных, настройка диаграммы через формулы. Из кода в данном случае будут вставляться только ячейки с данными из таблицы

Также в случае необходимости изменить визуальную составляющую диаграмм, статических ячеек или стилей (которые берутся из шаблона) не нужно будет подключать разработчиков, для этого достаточно изменить шаблон документа.

В данной статье описан подход полной реализации отчёта через код.

 

Реализация кейса

Создание нового документа и страниц данных

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

      // Название страниц
      var sheetNameData = "Виды документов";
     
var sheetNameDiagram = "Диаграмма";
      // Создаём документ
      var excelDocument = new Aspose.Cells.Workbook();
      // Создаём листы Excel
      var sheetData = excelDocument.Worksheets.Add(sheetNameData);
      var sheetDiagram = excelDocument.Worksheets.Add(sheetNameDiagram);
     
// Получение ячеек страницы
      var cell = sheetData.Cells[0, 0]; // Ячейка А1
      // Или
     
var cell = sheetData.Cells[“A1”];

 

Изменение стилей ячеек

Для ячеек мы можем устанавливать стили двумя способами.

  1. Взять стиль из другой ячейки и использовать её

// Копирование стиля из другой ячейки
var cellStyle = sheet.Cells["А99"].GetStyle();
sheet.Cells["A3"].SetStyle(cellStyle);

Данный способ будет полезен если у вас есть откуда брать готовые стили. К примеру, настроить стили в шаблоне и подгружать его во время генерации отчёта.

  1. Настроить стиль из кода

      // Определение стиля из кода
      var cellFactory = new Aspose.Cells.CellsFactory();
      var style = cellFactory.CreateStyle();
     
// Жирный шрифт
      style.Font.IsBold = true;
      // Тип рамки: Dotted - линия рамки представлена точками.
      style.Borders.DiagonalStyle = Aspose.Cells.CellBorderType.Dotted;
      // Установка стиля
      sheet.Cells["A3"].SetStyle(style);

 

Заполнение данных

Функция заполнение данных

Для заполнения данных на листы определим функцию.

/// <summary>
/// Добавляет строки на лист.
/// </summary>
/// <param name="document">Aspose.Cells.Workbook документ.</param>
/// <param name="sheetName">Название вкладки.</param>
/// <param name="rows">Данные для заполнения.</param>
/// <param name="startCellAddress">Адрес левой верхней ячейки.</param>
public virtual void AddRowsFromList (Aspose.Cells.Workbook document, string sheetName, List<List<object>> rows,
string startCellAddress)
{
      if (!rows.Any())
      return;
      //Получаем лист Excel, который будем заполнять данными
      var sheet = document.Worksheets.FirstOrDefault(x => x.Name == sheetName);
      if (sheet == null)
      return;
      //Для удобства перебора преобразуем адрес в номер строки и колонки
      var startCell = sheet.Cells[startCellAddress];
      int rowStart = startCell.Row;
      int colStart = startCell.Column;

      for (var rowNum = 0; rowNum < rows.Count; rowNum++)
      {

            var currentRow = rowNum + rowStart;
            var row = rows[rowNum];
            for (var colNum = 0; colNum < row.Count; colNum++)
            {
                var currentCol = colNum + colStart;
               var cell = sheet.Cells[currentRow, currentCol];
            
 // Устанавливаем значения в ячейке
              cell.PutValue(row[colNum]);
            }
      }
}

Получение данных из SQL запроса

Первым делом необходимо определить sql запрос в системе.

Дублирую запрос для удобности копирования:

SELECT kind."name" , COUNT(*)
FROM sungero_content_edoc doc
JOIN sungero_docflow_documentkind kind ON kind.id = doc.documentkind_docflow_sungero
WHERE doc.created between @DateFrom AND @DateTo
GROUP BY kind."name"

 

Далее создаём запрос в базу данных

/// <summary>
/// Получение количества документов в разрезе документопотока.
/// </summary>
/// <param name="dateFrom">Дата начала периода.</param>
/// <param name="dateTo">Дата конца периода.</param>
/// <returns>Список с результатами запроса.</returns>
/// <description>С списком объектов будет удобнее работать при вставке данных на страницу дкоумента.</description>
public List<List<object>> GetDocumentFlow(DateTime dateFrom, DateTime dateTo)
{
      // полученные данные
      List<List<object>> sheet = new List<List<object>>();

      // создаём подключение
      using (var cmd = SQL.GetCurrentConnection().CreateCommand())
      {

            // выбираем созданный ранее sql запрос
            cmd.CommandText = Queries.Module.DocumentFlow;

            // заполняем параметры
            Sungero.Docflow.PublicFunctions.Module.AddDateTimeParameterToCommand(cmd, "@DateFrom", dateFrom);
            Sungero.Docflow.PublicFunctions.Module.AddDateTimeParameterToCommand(cmd, "@DateTo", dateTo);

            // Выполняем и считываем данные
            var reader = cmd.ExecuteReader();
            while (reader.Read())
            {

                  List<object> row = new List<object>();

                  var kindName = reader.GetString(0); //Название вида документа
                  var count = reader.GetInt32(1); //Количество документов
                  // Записываем в строку
                  row.Add(kindName);
                  row.Add(count);
                  // Добавляем строку с данными
                  sheet.Add(row);
            }
            reader.Close();
      }
      return sheet;
}

Имея данные и функцию занесения этих данных в отчёт можем приступить к его генерации.

 

Генерация отчёта

Заполнение страницы с видами документов

/// <summary>
/// Заполнение страницы "DocumentFlow" данными
/// </summary>
/// <param name="excelDocument">Документ</param>
/// <param name="dateFrom">Дата начала периода</param>
/// <param name="dateTo">Дата конца периода</param>
public virtual void DocumentFlowFill(Aspose.Cells.Workbook excelDocument, DateTime dateFrom, DateTime dateTo)
{
      // Название листа данных
      string sheetName = "Виды документов";
      // Получение данных
      var sheetData = GetDocumentFlow(dateFrom, dateTo);
      // Заполнение данных
      AddRowsFromList (excelDocument, sheetName, sheetData, "B4");
      // Установка стилей для ячеек страницы
     
DocumentFlowSetStyles (excelDocument, sheetName);
}

 

Создание диаграммы

В данной главе продемонстрирована лишь малая часть возможностей работы с диаграммами. Чтобы узнать все возможности работы с диаграммами обратитесь к официальной документации.

     //Получаем лист Excel, в который собираемся вставить диаграмму
var worksheet = excelDocument.Worksheets.FirstOrDefault(x => x.Name == "Диаграмма");
// Добавляем диаграмму, и получаем индекс диаграммы
// Вначале указывается тип, далее размер диаграммы, первые два числа – координаты начальной ячейки (левый верхний угол) последние два-координаты конечной ячейки (правый нижний угол)

int chartIndex = worksheet.Charts.Add(Aspose.Cells.Charts.ChartType.Column, 0, 0, 18, 6);
// Получаем доступ к экземпляру недавно добавленной диаграммы
var chart = worksheet.Charts[chartIndex];
// Устанавливаем диапазон значений – Значения используемые на странице с видами       документов.
chart.SetChartDataRange(string.Format("'Количество документов'!$B$3:$C${0}", 3 + countRows), true);

После выполнения данных действий получим следующую диаграмму

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

//Жирный стиль текста
chart.ChartArea.Font.IsBold = true;
 // Убираем отображение заголовка
chart.Title.IsVisible = false;
// Размещаем легенду сверху
chart.Legend.Position = Aspose.Cells.Charts.LegendPositionType.Top;
// Убираем заливку области построения
chart.PlotArea.Area.FillFormat.FillType = Aspose.Cells.Drawing.FillType.None;
 //Устанавливаем тени
chart.ChartArea.ShapeProperties.ShadowEffect.PresetType = PresetShadowType.InsideCenter;

В итоге получим следующий вид у диаграммы

 

Функция генерации отчёта

Так как страниц в отчёте может быть много, лучше будет разнести генерацию каждой из них в отдельную функцию.

/// <summary>
/// Заполнение документа.
/// </summary>
/// <param name="dateFrom">Дата начала периода.</param>
/// <param name="dateTo">Дата конца периода.</param>
/// <returns>Сформированный отчёт.</returns>
public virtual Aspose.Cells.Workbook DocumentFill(DateTime dateFrom, DateTime dateTo)
{
     
var excelDocument = new Aspose.Cells.Workbook();

      IncomingDocumentsFill(excelDocument, dateFrom, dateTo);
      DocumentFlowFill(excelDocument, dateFrom, dateTo);
      DocumentFlowDiagram (excelDocument, dateFrom, dateTo);

     
return excelDocument;
}

Результат

По итогу мы имеем отчёт с следующими страницами данных.

Страница «Виды документов»

Страница «Диаграмма»

Компоненты ASPOSE встроены в Directum его разработчиком для реализации конкретной функциональности. Для самостоятельной разработки новой функциональности вам потребуется купить лицензию на ASPOSE.
14
Авторизуйтесь, чтобы оценить материал.
4
Пока комментариев нет.

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