Опубликован: 05.08.2010 | Уровень: специалист | Доступ: свободно
Самостоятельная работа 7:

Создание отчетов Crystal Reports.NET в графическом режиме

Настройка отчета

Теперь подошла очередь присоединить наш отчет к созданному объектному источнику данных и настроить его (отчет).

  • Перейдите в графический режим дизанера отчетов Report Designer и выполните команду контекстного меню Database/Database Expert
  • Раскройте узел Project Data и поместите в правый список таблицу Customers

Обратите внимание, что эксперты, вызываемые в режиме Report Designer, отличаются только заголовками окон от вкладок мастера Standard Report Creation Wizard, который мы использовали в предыдущем упражнении. Ну и правильно, проще подставлять новые заголовки, чем дублировать весь инструмент, да и нам попривычнее будет!

  • Щелкните на кнопке OK и отчет окажется подключенным к созданному ранее строго типизированному источнику данных
  • Откройте панель Field Explorer через меню Crystal Reports, контекстное меню Report Designer или щелчком на пиктограмме панели интсрументов 'Crystal Reports - Main' и разверните в ней узел Database Fields/Customers
  • Перетащите в секцию Details формы отчета поля CustomerID, CompanyName, Address, Region и распределите их равномерно по ширине листа. Позже мы скорректируем ширину рабочих полей, когда настроим приложение на просмотр отчета.

После отпускания кнопки мыши одновременно в секции Page Header тоже появится заголовок поля текстового типа, который можно отредактировать. Имена столбцов в секции Details не редактируются, а редактируется только их формат через команду Format Object контекстного меню. Следует иметь ввиду, что вертикальный размер секции Details определяет междустрочное расстояние выводимой в рабочую область отчета информации.

  • Перейдите на вкладку Main Report Preview эксперта Report Designer

Здесь можно увидеть, что в рабочей области отчета вместо реальных данных таблицы Customers подставляются дежурные значения, генерируемые Crystal Reports. Это происходит потому, что мы не напрямую соединились с БД, как это было в предыдущем упражнении, а через набор данных. На этапе проектирования созданный нами ранее типизированный набор данных заполнен только схемой таблицы Customers, поэтому Crystal Reports видит сейчас только названия полей и их типы. Но сам типизированный набор пока не содержит реальных данных таблицы и в отчет помещаются случайные данные, чтобы можно было представить их будущее расположение

  • Вернитесь на вкладку Main Report и поместите в секцию Report Header из раздела Special Fields панели Field Explorer поле Report Title
  • Выполните команду меню Crystal Reports/Report/Summary Info и заполните поле Title названием отчета, например, 'Отчет компании Рога и Копыта'
  • Настройте стиль заголовка по своему вкусу через контекстное меню поля Report Title, выполнив команду Format Object. Проследите через режим Main Report Preview, чтобы текст заголовка помещался в поле
  • Поместите в секцию Report Header из раздела Special Fields панели Field Explorer поля Data Date и Data Time и настройте их стиль по вкусу, вызвав через контекстное меню командой Format Object окно Format Editor. Проследите через режим Main Report Preview, чтобы содержимое помещалось в поле. Пользуйтесь групповым выделением полей отчета и перемещением в рамках секции с помощью клавиатурных стрелок.

Система Crystal Reports позволяет очень красиво и тонко настроить отчет, но в данном упражнении нам пока достаточна выполненных простых возможностей.

Интеграция отчета в приложение

Вспомните, что Crystal Reports может работать в двух режимах: Pull -выталкивание и Push -заталкивание. Мы в данном упражнении хотим реализовать режим Push и для этого подготовили форму простого отчета вручную с помощью Report Designer. Это форма отчета должна храниться в отдельном файле CrystalReport1.rpt вместе со сборкой и загружаться приложением из кода. Мы также подготовили типизированный источник данных NorthwindDataSet, который имеет все необходимые настройки для связи с БД и выборки нужных нам данных. Строка соединения хранится в конфигурационном файле. На форме Form1 размещен объект с именем crystalReportViewer1 для отображения отчета на этапе выполнения. Теперь осталось связать все вместе с помощью кода.

  • Перейдите в режим Form Designer для формы Form1 и двойным щелчком на ее заголовке (потому что в клиентской области размещен объект CrystalReportViewer ) создайте обработчик события Load, который заполните так
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
    
using CrystalDecisions.Shared;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Windows.Forms;
    
namespace WinReport2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
    
        private void Form1_Load(object sender, EventArgs e)
        {
            // Создаем адаптер типизированного набора, в котором уже
            // содержатся все настройки для извлечения нужных данных
            // Классы сгенерированы оболочкой при создании набора данных
            NorthwindDataSetTableAdapters.CustomersTableAdapter adapter = 
                new WinReport2.NorthwindDataSetTableAdapters.CustomersTableAdapter();// Сгенерированный класс
            // Извлекаем данные из БД
            NorthwindDataSet.CustomersDataTable table = adapter.GetData();// Сгенерированные составной класс
    
            // Создаем объект документа отчета
            ReportDocument reportDocument = new ReportDocument();
            // Загружаем шаблон отчета
            reportDocument.Load("CrystalReport1.rpt");// !!! Должен стоять перед загрузкой данными
            // Заталкиваем (Push) данные по шаблону 
            reportDocument.SetDataSource(table as DataTable);// !!! Должен стоять после загрузки отчета
            //reportDocument.Database.Tables["Customers"].SetDataSource(dataSet.Tables["Customers"]);// Вариант
            crystalReportViewer1.ReportSource = reportDocument;// Привязываем к элементу отображения отчета
    
            // Донастраиваем объект отображения отчета
            crystalReportViewer1.ShowGroupTreeButton = false;// Отключить кнопку
            crystalReportViewer1.DisplayGroupTree = false;   // Отключить панель
    
            // Вариант. Если передается параметр Test типа DateTime
            //reportDocument1.SetParameterValue("Test", DateTime.Now);
            //crystalReportViewer1.ReportSource = reportDocument;
        }
    }
}

Обратите внимание, что мы вначале создаем объект, производный от класса DataTable, и извлекаем в него данные из базы в соответствии с настройками набора данных NorthwindDataSet через созданный в нем адаптер CustomersTableAdapter. Далее создаем объект отчета ReportDocument и загружаем в него созданный шаблон отчета CrystalReport1.rpt.

  • Проследите, чтобы настройки файла CrystalReport1.rpt заставляли оболочку копировать шаблон в каталог размещения исполнимой сборки приложения (точно также, как файл БД) при его компиляции

Особенно важно, чтобы шаблон отчета CrystalReport1.rpt оказался в объекте отчета ReportDocument раньше загрузки туда самих данных, поскольку во время загрузки он выполняет форматирование данных, пропуская их через себя. А далее мы связываем объект просмотра с самим отчетом и попутно донастраиваем его. Вот пока и все, наступил момент истины!

  • Запустите приложение и полюбуйтесь на результат, который вы и я сами сделали вручную, можно сказать, с нуля

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


Алексей Бабушкин
Алексей Бабушкин

При выполнении в лабораторной работе упражнения №1 , а именно при выполнении нижеследующего кода:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using Microsoft.Xna.Framework.Graphics;

   

namespace Application1

{

    public partial class MainForm : Form

    {

        // Объявим поле графического устройства для видимости в методах

        GraphicsDevice device;

   

        public MainForm()

        {

            InitializeComponent();

   

            // Подпишемся на событие Load формы

            this.Load += new EventHandler(MainForm_Load);

   

            // Попишемся на событие FormClosed формы

            this.FormClosed += new FormClosedEventHandler(MainForm_FormClosed);

        }

   

        void MainForm_FormClosed(object sender, FormClosedEventArgs e)

        {

            //  Удаляем (освобождаем) устройство

            device.Dispose();

            // На всякий случай присваиваем ссылке на устройство значение null

            device = null;       

        }

   

        void MainForm_Load(object sender, EventArgs e)

        {

            // Создаем объект представления для настройки графического устройства

            PresentationParameters presentParams = new PresentationParameters();

            // Настраиваем объект представления через его свойства

            presentParams.IsFullScreen = false; // Включаем оконный режим

            presentParams.BackBufferCount = 1;  // Включаем задний буфер

                                                // для двойной буферизации

            // Переключение переднего и заднего буферов

            // должно осуществляться с максимальной эффективностью

            presentParams.SwapEffect = SwapEffect.Discard;

            // Устанавливаем размеры заднего буфера по клиентской области окна формы

            presentParams.BackBufferWidth = this.ClientSize.Width;

            presentParams.BackBufferHeight = this.ClientSize.Height;

   

            // Создадим графическое устройство с заданными настройками

            device = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware,

                this.Handle, presentParams);

        }

   

        protected override void OnPaint(PaintEventArgs e)

        {

            device.Clear(Microsoft.Xna.Framework.Graphics.Color.CornflowerBlue);

   

            base.OnPaint(e);

        }

    }

}

Выбрасывается исключение:

Невозможно загрузить файл или сборку "Microsoft.Xna.Framework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" или один из зависимых от них компонентов. Не удается найти указанный файл.

Делаю все пунктуально. В чем может быть проблема?

Юрий Макушин
Юрий Макушин
Россия, Москва, РЭА им. Плеханова, 2004