- Простота развертки (не надо каждый раз при обновлении разворачивать на клиентах msi'ники)
- Возможность просмотра как в навигаторе (настроив папку на отображения отчета по URL), так и вне его (просто в браузере).
- Так как физически отчет находится на сервере – это значит, что удобно использовать MSSQL Server напрямую для выборки данных для отчета (хотя никто не мешает задействовать и DV API)
Silverlight предоставляет возможность создавать действительно «богатые» интерфейсы (rich UI) декларативно на языке XAML (так же, как и в WPF). Например, небольшими усилиями можно сделать таблицу, похожую на ту, что используется в навигаторе:
При том, что исходный код страницы на C# выглядит очень минималистично:
using System.Windows.Data;
namespace IDoc.DvWebReports
{
public partial class MainPage
{
public MainPage()
{
InitializeComponent();
//генерация набора тестовых данных:
Tasks = new PagedCollectionView(TaskInfo.GetTaskInfoForTest());
//группировка:
Tasks.GroupDescriptions.Add(new PropertyGroupDescription("Author"));
Tasks.GroupDescriptions.Add(new PropertyGroupDescription("Executer"));
}
///
/// Поручения
///
public PagedCollectionView Tasks { get; set; }
}
}
А представление этих тестовых данных (через Binding) полностью настраивается декларативно в XAML по средствам дизайнера в Visual Studio или такого интересного инструмента, как Expression Blend. На создание такого «фейкового» отчета у меня ушло меньше часа.
Теперь перейдем к «реальным отчетам». В качестве примера, рассмотрим отчет о кол-ве созданных в системе карточек (в виде круговой диаграммы). Silverlight – это, по сути, клиентская часть, поэтому в проекте SL приложения мы не можем получить прямой доступ к данным (например, по средствам ADO.NET). Поэтому нам необходима отдельная служба, которую очень просто реализовать, используя технологию WCF. Ну и наконец, нам нужен ASP.NET проект, который будет хостом для нашего клиентского xap пакета (Silverlight приложения) и нашей службы WCF (с basicHttpBinding, т.к. только этот вид привязки поддерживается сильверлайтом). Структура солюшна в VS выглядит следующим образом:
Для развертки всего решения достаточно воспользоваться командой Publish и опубликовать на удаленном сервере прямо с машины разработчика.
В качестве доступа к данным в своём примере я использовал “недо-ОRM” LINQ to SQL, в котором накидал в дизайнере пару нужных для отчета таблиц и составил вот такой запрос:
///
/// Получить информацию по кол-вам карточек в системе
///
public static CardsCountInfoRow[] GetCardCountsInfo(string connectionString,
DateTime rangeStart, DateTime rangeEnd)
{
using (var dataContext = CreateDataContext(connectionString))
{
var result =
from instancesGroup in
(from instance in dataContext.dvsys_instances
join instanceDate in dataContext.dvsys_instances_dates
on instance.InstanceID equals instanceDate.InstanceID
where
//Не удалена
(!instance.Deleted.HasValue || !instance.Deleted.Value) &&
//Не шаблон
(!instance.Template.HasValue || !instance.Template.Value) &&
//создана в указанный период
instanceDate.CreationDateTime >= rangeStart &&
instanceDate.CreationDateTime <= rangeEnd
group instance by instance.CardTypeID into g
select new { CardTypeID = g.Key, Count = g.Count()})
join def in dataContext.dvsys_carddefs
on instancesGroup.CardTypeID equals def.CardTypeID
select new CardsCountInfoRow(instancesGroup.Count, def.Icon,
def.CardTypeID, def.XMLSchema);
return result.ToArray();
}
}
Исходный код страницы отчета:
using System;
using System.Windows;
using DvReports.Reporting;
namespace DvReports
{
public partial class MainPage
{
public MainPage()
{
InitializeComponent();
RangeStart = new DateTime(DateTime.Now.Year, 1, 1);
RangeEnd = DateTime.Now;
}
///
/// Начало периода создания карточек
///
public DateTime RangeStart { get; set; }
///
/// Окончание периода создания карточек
///
public DateTime RangeEnd { get; set; }
private void btShowData_Click(object sender, RoutedEventArgs e)
{
var client = new ReportServiceClient();
client.GetCardCountsInfoCompleted += GetCardCountsInfoCompleted;
//посылаем запрос службе
client.GetCardCountsInfoAsync(RangeStart,
RangeEnd == DateTime.MinValue ? DateTime.MaxValue : RangeEnd);
}
//пришел ответ
private void GetCardCountsInfoCompleted(object sender, GetCardCountsInfoCompletedEventArgs e)
{
pieChart.Visibility = Visibility.Visible;
//отдаем данные диаграмме
pieChart.DataContext = e.Result;
}
}
}
Далее на XAML описал представление, развернул сайт на IIS и указал в одной из папок дв его отображение по URL:
На этом не остановился, и там же сделал ещё один отчет – отчет по продолжительностям сессий у сотрудников:
Тут используется обычный компонент ListBox с применением такой интересной "фичи", как DataTemplate – шаблон представления данных элемента, который удобно создавать в Expression Blend:
Для исполнения Silverlight приложений на клиентах, у них должен быть установлен Silverlight Runtime (~9mb), при этом наличие исполняемой среды .NET какой-либо версии не обязательно. Cовместимость Silverlight с различными операционными системами можно увидеть в таблице тут
Некоторые ссылки по теме:
Step by step руководство по созданию Silverlight + WCF приложения- Видео-доклады на techdays.ru по Silverlight и WCF
Исходники демонстрационных приложений: DvReportsSample и DataGridSample
Читать дальше
3 коммент.:
А возможно определить текущего пользователя, чтобы отчет был сформирован с учетом его прав?
Теоретически да, но я вижу только давольно сложный способ с созданием собственной карточки-хоста (с WebBrowser) которая бы запускала отчет с нужными параметрами.
могли бы вы перезалить Исходники демонстрационных приложений, либо отправить их на почту a1exander.so8ol@gmail.com
________________________________
С уважением Александр
Отправить комментарий