СТАТЬЯ |
05.03.03
|
© Эндрю Браст (Andrew Brust)
Переведено БНТП по заказу Interface Ltd.
Теперь можно рассмотреть, как используется технология XML Web Services в Crystal Reports for Visual Studio .NET. Значительным достижением в этой области является удачная разработка достаточно сложных функций с легко реализуемыми преимуществами; например, отчеты могут публиковаться как Web-службы и использоваться в качестве ReportSource для элемента управления CrystalReportViewer.
Чтобы создать Web-службу для XML-отчетов из файла CustomersBasic.rpt, откройте
Visual Studio .NET и создайте новый проект ASP.NET Web Service под именем MSDNCrystalWebService.
Удалите файл Service1.asmx, который добавляется к проекту по умолчанию, и вместо
него добавьте CustomersBasic.rpt. Затем щелкните правой кнопкой мыши по CustomersBasic.rpt
в Solution Explorer и выберите в контекстном меню пункт Publish as Web Service
(см. Рисунок 10).
Рис. 10.
В результате в проект будет добавлен файл Web-службы, CustomersBasicService.asmx. Теперь будем компоновать проект. Вернитесь в приложение Windows Forms и установите для cvwMain.ReportSource URL-адрес Report Web Service согласно следующей строке текста программы:
cvwMain.ReportSource = "http://localhost/MSDNCrystalWebService/"
_
& "CustomersBasicService.asmx"
В качестве альтернативы вы можете добавить веб-ссылку для этого asmx-файла в проекте и затем указать cvwMain.ReportSource в экземпляре класса Web Service.
cvwMain.ReportSource = New localhost.stomersBasicService()
Можно ли создать интерфейс XML Web Services в Crystal Reports так же легко, как и Web-службу? Внимательно изучите программу файла класса, который расположен с небольшим отступом под файлом CustomersBasic.rpt (чтобы увидеть файл, щелкните по кнопке Show All Files в Solution Explorer). В программе этого файла содержатся два класса: CustomersBasic и CachedCustomersBasic.
CustomersBasic является первичным классом, который необходим для реализации строго типизированного отчета; если вы посмотрите на процедуры атрибутов этого отчета, то увидите его со всеми разделами, которые наследуются из ReportClass и охватывают элементы коллекции ReportDefinition.Sections. В свою очередь, CachedCustomersBasic реализует интерфейс IcachedReports для создания кешированного отчета и в своем методе CreateReport создает экземпляр CustomersBasic (первый класс). С помощью интерфейса, подобного интерфейсу IcachedReports и использующего WebMethods, можно вывести отчет в виде XML Web Service.
Теперь взгляните на программу файла класса, который расположен под файлом CustomersBasicService.asmx. Этот файл также содержит два класса, но, в отличие от предыдущего файла, в нем один класс вложен в другой. CustomersBasicService наследуется из класса ReportServiceBase, который, в свою очередь, открывает веб-методы, необходимые для публикации отчета в виде XML Web Service. CustomersBasicService содержит класс CachedWebCustomersBasic, который, по своему существу, имеет точно такую же реализацию, что и уже рассмотренный класс CachedCustomersBasic. Различие можно найти в конструкторе:
Public Sub New(ByVal webServiceParam As CustomersBasicService)
Me.webService = webServiceParam
End Sub
Этот конструктор вызывается из конструктора CustomersBasicService, чтобы указать в нем атрибут webService кешированного отчета:
Public Sub New()
Me.ReportSource = New CachedWebCustomersBasic(Me)
End Sub
Подведем итоги: ReportClass в Crystal Report создает возможные строго типизированные отчеты; интерфейс IcachedReports позволяет создавать кешированные экземпляры ReportClass; и, наконец, ReportServiceBase создает интерфейс Web Services для строго типизированных отчетов, который благодаря атрибуту webService совместим с интерфейсом IcachedReports.
Кстати, вы не забыли о компоненте ServerFileReport, который я создал, перетащив из Server Explorer? В нем также задействуется технология Web Services. Если вы вернетесь в проект Windows Form, то заметите, что у sfrCustomersBasic имеется атрибут WebServiceURL указывающий на .asmx-файл общего вида. Адрес URL будет выглядеть примерно следующим образом: localhost/crystalreportwebformviewer/ServerFileReportService.asmx. Несмотря на то, что этот URL-адрес стандартен, атрибут ReportPathProperty класса sfrCustomersBasic, указывая на \MSDN\ CustomersBasic.rpt, задает относительный путь и имя отчета, который требуется запустить.
С первого взгляда кажется странным, что компонент ServerFileReport требует запуска отчета через соединение HTTP/SOAP с локальным компьютером. Однако, благодаря этому вы можете легко запустить отчеты Crystal Reports for Visual Studio .NET, существующие на удаленном компьютере: просто щелкните правой кнопки мыши по узлу Servers в окне Server Explorer и выберите Add Server, затем подключитесь к любому серверу в ваших сетях LAN/WAN и запустите на удаленном компьютере требуемые отчеты Crystal Reports for Visual Studio .NET. Данная возможность позволяет легко развертывать отчеты по всему предприятию: для этого установите среду Visual Studio .NET на сервере и скопируйте rpt-файлы в соответствующую папку, после чего эти rpt-файлы без какой-либо специальной программы станут доступны для всей организации (по протоколу SOAP). В этом случае вам даже не потребуется такой относительно простой процесс, как выбор пункта "Publish as Web Service", который выполняется после щелчка правой кнопки мыши по отчету в проекте ASP.NET, поскольку все, что вам будет нужно сделать, так это скопировать файл в соответствующую папку.
Недостаток использования операции перетаскивания объектов в Server Explorer заключается в том, что в нем можно просматривать только те объекты сервера, которые постоянно находятся в сетях LAN/WAN разработчика, а не за брандмауэром. Но тут есть одна хитрость: пока известны адрес URL и значение атрибута ReportPath при подключенном к сети Internet сервере (с брандмауэром или нет), вы сможете создать новый экземпляр CrystalDecisions.ReportSource.ServerFileReport и задать в нем значения этих атрибутов, указав их в программе.
Интерфейс SOAP так удобен и прост, что Crystal Reports for Visual Studio .NET применяет его в качестве оболочки программ сортировки для своего более раннего продукта, сервера Crystal Enterprise. Узел Crystal Enterprise под Crystal Services в Server Explorer можно использовать для просмотра отчетов, содержащихся на любом сервере Crystal Enterprise в сети LAN/WAN, а также для использования этих отчетов в качестве допустимых значений ReportSources для элемента управления CrystalReportViewer при повторном применении SOAP. В этом случае отчеты Crystal Enterprise будут доступны для любых подключенных к сети Internet генераторов отчетов Crystal Reports for Visual Studio .NET с правильным адресом URL и идентификатором объекта.
До сих пор все, что я сделал на клиентском компьютере, было выполнено в приложении Windows Forms, однако отчеты можно также представлять и в веб-приложениях ASP.NET. К счастью, Crystal Reports for Visual Studio .NET поддерживает технологию ASP.NET. Теперь я покажу, как представлять отчеты в виде документов HTML или документов Acrobat (PDF), используя элемент управления ASP.NET Web Forms CrystalReportViewer. Кроме того, я рассмотрю кэширование и использование кешированных данных.
Поскольку Web Forms CrystalReportViewer работает аналогично Windows Forms, изложение основных операций займет не слишком много времени. Для начала создайте в среде Visual Studio .NET новое веб-приложение ASP.NET Web Application и, используя функцию Add Existing Item, добавьте в проект CustomersBasic.rpt. Затем задайте местоположение данных для отчетов, вернувшись к таблице Customers, и в целях тестирования используйте вход с пустым паролем. Переименуйте WebForm по умолчанию в ViewReport.aspx и добавьте к нему элемент управления Web Forms CrystalReportViewer, задав для его атрибута ID значение cvwMain. Поскольку на этапе разработки элемент управления Web Forms CrystalReportViewer не имеет атрибута ReportSource, следует задать этот атрибут в событии Page_Load в ViewReport.aspx следующим образом:
cvwMain.ReportSource = Server.MapPath("CustomersBasic.rpt")
Запустив приложение, убедитесь в эффективности данной процедуры. Этот отчет является чистым HTML-документом несмотря на то, что в нем поддерживаются функции поиска, навигации, масштабирования и других элементов управления просмотром (кроме печати - об этом речь пойдет позже), хотя и с помощью переадресации (postback). Можно попробовать и другие способы загрузки отчета, которые я уже рассматривал: создание отчета из строго типизированного набора DataSet или из набора DataSet без контроля типов, из хранимой процедуры с помощью ReportDocument или разработчика компонентов ServerFileReport и т.п. Можно скопировать в событие Page_Load в ViewReport.aspx программу, которую я уже использовал для настройки учетной информации отчета и значений параметров, а также для манипулирования объектами ADO.NET. Это аналогично тому, что я уже делал, и я не буду повторяться, хотя опция ReportDocument требует некоторого объяснения.
Теперь давайте рассмотрим функции Crystal Reports for Visual Studio .NET для
кешированных отчетов. Перетащите разработчик компонентов ReportDocument на плоскость
разработки ViewReport.aspx и выберите ProjectName.CustomersBasic из Name: комбинированного
списка в диалоговом окне Choose a ReportDocument, не нажимая кнопку OK. Обратите
внимание на флажок "Generate cached strongly typed report" ("Создать
кешированный строго типизированный отчет") (см. рис.11).
Рис. 11 Функция кешированных отчетов
Установите этот флажок. Щелкните по кнопке OK и назовите созданный компонент как ccbMain. Затем, свяжите элемент управления просмотра с этим объектом в событии Page_Load с помощью следующей строки программы:
cvwMain.ReportSource = ccbMain
Перетащите элементы управления Data Time и Print Time в раздел заголовка страницы отчета. Эти элементы управления можно найти в окне Field Explorer под узлом Special Fields. Затем запустите приложение и просмотрите отчет. Когда вы его запустите в первый раз, элементы управления Data Time и Print Time должны быть одинаковыми (или же очень похожими). Но если вы обновите страницу, то увидите, что Print Time продолжает обновляться, а Data Time остается одним и тем же. Теперь скопируйте текущий адрес URL обозревателя в буфер обмена и закройте обозреватель. Откройте окно нового обозревателя и вставьте в него указанный адрес URL для просмотра отчета в новом сеансе (без перестройки сборки из Visual Studio .NET). Вы увидите, что исходная временная метка будет отображаться в Data Time.
Теперь закройте обозреватель и вернитесь в Visual Studio .NET. Снова перетащите дизайнер компонентов ReportDocument на плоскость разработки ViewReport.aspx и выберите ProjectName.CustomersBasic, сняв флажок "Generate cached strongly typed report". Щелкните по кнопке OK и назовите созданный компонент как "cbsMain". После завершения данной операции свяжите элемент управления просмотра с созданным объектом в событии Page_Load, внеся в программу имя нового компонента:
cvwMain.ReportSource = cbsMain
Запустив приложение, просмотрите отчет и обновите несколько раз страницу. При этом вы увидете, как будет изменяться элемент управления Data Time при каждом обновлении. Эта операция наглядно продемонстрирует вам основное различие между кешированными и некешированными отчетами: кэширование позволяет избежать лишних обращений к базе данных, когда уже есть требуемые данные.
Когда вы используете атрибуты DataDefinition или Database объекта cbsMain (экземпляр моего некешированного ReportDocument) для задания значений параметров или атрибутов входа в таблицы, обратите внимание, что ccbMain (экземпляр кешированного ReportDocument) не имеет таких атрибутов. Как использовать кешированные отчеты по отношению к защищенным таблицам и параметризованным хранимым процедурам? Ключ лежит в программе, расположенной позади строго типизированного отчета. Снова щелкните по кнопке Show All Files (Показать все файлы) в Solution Explorer, перейдите к CustomersBasic.rpt и откройте позади него файл программы. Вы уже были здесь, но сейчас вам следует открыть программу для класса CachedCustomersBasic, содержащуюся в этом файле.
Обратите внимание, что программа создает новый экземпляр некешированного класса CustomersBasic для своего метода CreateReport, поскольку CachedCustomersBasic в действительности содержит CustomersBasic. Таким образом, я могу написать настраиваемую программу в этом общедоступном методе, чтобы иметь доступ к атрибутам Database и DataDefinition как созданного экземпляра класса CustomersBasic, так и интерфейса с защищенными объектами базы данных и параметризованными хранимыми процедурами. Если я применяю этот метод, то при создании нового экземпляра кешированного отчета будет создаваться соответствующий сконфигурированный экземпляр некешированного строго типизированного отчета.
Теперь прокрутите несколько вниз, чтобы увидеть снабженную комментариями программу для другого важного метода, GetCustomizedCacheKey. Этот метод генерирует уникальный ключ, который определяет, будет ли использоваться копия кешированного отчета для выполнения запроса. Если ключ совпадает с ключом кешированного отчета, то будет использоваться кешированная копия. Если не совпадает, то данные будут выбираться заново.
Если вы убрали из программы комментарии, то специальная функция BuildCompleteCacheKey сгенерирует уникальный ключ для конкретного отчета. Раскомментированная программа, которая во всем остальном оставлена без изменений, выполняется так же как программа с комментариями. Если этот ключ не модифицируется, то Crystal Reports неявно использует алгоритм BuildCompleteCacheKey для создания вашего ключа. Это подходит для многих случаев. Но что делать, если вам требуется модифицировать ключ? Предположим, вы узнали, что в какой-то момент времени ваши данные значительно изменились. Тогда вы могли бы приписать к ключу кеша свою строку, чтобы обеспечить его изменение в этот момент времени или после него. Приведем тривиальный пример: раскомментируйте программу в GetCustomizedCacheKey и вставьте перед оператором Return следующую строку:
key &= DatePart(DateInterval.Minute, Now())
Эта строка прозволяет генерировать новый ключ кеша в тот момент, когда текущее время изменяется на одну минуту. В событии Page_Load класса ViewReport.aspx укажите ccbMain для cvwMain.ReportSource, затем запустите приложение и обновите несколько раз страницу. При этом вы увидите изменение в Data Time, которые происходят, когда минутный отсчет фактического времени увеличивается на единицу. Подобным образом можно приписать к ключу кеша значения различных параметров и другие детали, связанные с данными, чтобы избежать обработки одних и тех же кешированных данных при прогонах отчета. Можно создать собственный ключ, не просто прибавляя кое-какие строки к ключу кеша по умолчанию, но написав его целиком с самого начала; но этот метод я не буду рекомендовать хотя бы потому, что это все равно, что изобретать колесо.
Конечно, эти изменения в классе строго типизированных отчетов весьма полезны, но они связаны с некоторым риском, поскольку при обновлении отчета Visual Studio .NET попытается переписать файл класса этого отчета и, если не принять соответствующих мер, то вы потеряете внесенные изменения. Чтобы этого избежать, вам следует создать собственный класс, реализующий IcachedReport с программой из класса CachedCustomersBasic. После этого вы сможете создать в ViewReport.aspx, а именно в событии Page_Load, экземпляр этого класса и указать на него в cvwMain.ReportSource. На Figure 12 показана программа для данного класса (включая программу, использующую объект ASP.NET Request для задания значения поля параметра отчета и для добавления этого значения в ключ кеша), а также программа (см. ниже), демонстрирующая код события Page_Load, который требуется для ее использования.
Private Sub Page_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim mcrMain As New cMSDNCachedReport()
McrMain.ASPRequest = Request
CvwMain.ReportSource = mcrMain
End Sub
Сильная сторона элемента управления Web Forms CrystalReportViewer заключается в том, что он представляет отчеты в виде документов HTML, но в этом и его слабость. С одной стороны, такое представление отчетов содействует максимальной совместимости Crystal Reports for Visual Studio .NET и клиентских обозревателей; с другой, язык HTML не предусматривает точное постраничное разбиение при выводе на печать.
Чтобы обойти проблемы, связанные с печатью, следует преобразовать отчет в формат Adobe Acrobat (PDF). Вы можете написать довольно простую программу ASP.NET, которая позволила бы программным способом преобразовать отчет в формат PDF и затем перенаправила бы ваш обозреватель на этот файл. Таким образом, пользователь может запросить отчет через событие Postback и получить адрес PDF-версии отчета, которую он будет печатать. На Figure 13 показана программа, позволяющая выполнить эту операцию. Для простоты я использую некешированный объект cbsMain компонента ReportDocument для генерирования отчета.
Если вы для представления отчетов собираетесь использовать PDF-файлы, вам следует узнать о недостатках этого метода. Во-первых, чтобы удовлетворить многочисленным пользователям, вы должны дать уникальные имена созданным PDF-файлам; программа на Figure 13 использует постоянную текстовую строку, поэтому она годится только для демонстрации предлагаемого метода. Во-вторых, в какой-то момент времени PDF-файлы должны быть окончательно отредактированы, и, в зависимости от количества готовых отчетов на вашем приложении, весь файловый ввод-вывод, связанный с созданием и доводкой PDF-файлов, может при неправильном управлении и настройке значительно замедлить функцию масштабируемости. При создании приложений ASP.NET с помощью Crystal Reports for Visual Studio .NET рекомендуется изучить программу просмотра со стороны клиента и составить стратегию печати, поскольку у каждой опции имеется свой набор значимых аргументов "за" и "против".
В этой статье я подробно рассмотрел возможности генератора отчетов Crystal Reports for Visual Studio .NET, хотя за ее рамками осталось много интересного материала, требующего отдельного исследования. Ничего более не желая, я рассчитываю на то, что вы после ее прочтения осознаете богатство предоставляемых возможностей и прекрасную интеграцию этого инструмента с .NET Framework и Visual Studio .NET.
Дополнительная информация
За дополнительной информацией обращайтесь в компанию Interface Ltd.
INTERFACE Ltd. |
|