Страница 1 из 2

Динамическое изменение размера страницы отчета

Добавлено: 30 авг 2019, 12:27
ybelyaev
Добрый день.
Имеется отчет, с размещенными в нем следующими бэндами:
  • Report Title
  • Header
  • Data
  • Page Footer
В бэнде Data выводится количество строк, которое не умещается на одной странице отчета по высоте, поэтому отчет становится многостраничным.
Каким образом можно динамически изменять высоту страницы, чтобы данные из всех бэндов умещались на одной странице (пусть и очень большой высоты)?
Свойство страницы Unlimited Height не подходит, поскольку сохраняется разметка - отделение одной страницы от другой синей пунктирной линией, а также простановка номера страницы.

Re: Динамическое изменение размера страницы отчета

Добавлено: 01 сен 2019, 11:48
Aleksey
Здравствуйте,

Как вариант, использовать 2 прохода (DoublePass), в первом проходе проверять позицию последнего компонента на странице и задавать необходимую высоту страницы.

Спасибо.

Re: Динамическое изменение размера страницы отчета

Добавлено: 02 сен 2019, 11:54
ybelyaev
Aleksey, спасибо за ответ.
Поскольку я не силен в C#, немогли бы Вы написать схематичный код и указать, где его нужно разместить в отчете?

Re: Динамическое изменение размера страницы отчета

Добавлено: 02 сен 2019, 17:06
ybelyaev
Установил в настройке отчета Number of Pass = Double Pass, в событие отчета End Render добавил следующий код:

Код: Выделить всё

double maxHeight = 0;
foreach (StiPage page in this.RenderedPages)
{
	double maxPage = 0;
	foreach (StiComponent comp in page.GetComponents())
   	{
        	if (comp.Bottom > maxPage) maxPage = comp.Bottom;
	}
	maxHeight = maxHeight + maxPage + page.Margins.Top + page.Margins.Bottom;
}
StiPage page1 = this.Pages["Page1"];
page1.PageHeight = maxHeight + page1.Margins.Top + page1.Margins.Bottom;
Получил отчет на 3 страницах, вместо 12 первоначально.
Как я понимаю работу алгоритма размещенного выше кода:
первый проход генератора отчетов
  1. на каждой отрисованной странице определяется компонент с максимальной нижней границей, значение которой сохраняется в переменной maxPage
  2. накапливается сумма максимальной нижней границы компонента и размеров полей отступа каждой страницы в переменной maxHeight
  3. задается высота шаблонной страницы Page1 из накопленных значений в maxHeight вместе с нижней и верхней полями отступа
второй проход генератора отчетов
  1. строится повторно страница с новой высотой, заданной на первом проходе генератора
  2. в итоге получаю 3 страницы, а не одну
Как всё же мне получить одностраничный отчет с вычисленной высотой?

Re: Динамическое изменение размера страницы отчета

Добавлено: 04 сен 2019, 13:05
ybelyaev
Попробовал немного другой способ:
  • изменил метод Report() - добавил программно обработчик события окончания рендеринга отчета

Код: Выделить всё

        public Report()
        {
            this.InitializeComponent();
            StiOptions.Engine.GlobalEvents.ReportEndRender += Report_EndRender;
        }
  • сам метод изменяющий высоту страницы выглядит так:

Код: Выделить всё

	private void Report_EndRender(object sender, EventArgs e)
	{
		double maxHeight = 0;
		foreach (StiPage page in this.RenderedPages)
		{
			double max = 0;
			foreach (StiComponent comp in page.GetComponents())
			{
				if (comp.Bottom > max) max = comp.Bottom;
			}
			maxHeight = maxHeight + max + page.Margins.Top + page.Margins.Bottom;
		}
		foreach (StiPage page in this.Pages)
		{
			page.PageHeight = maxHeight;
		}
	}
В итоге с двойных проходом генератора отчет размещяется на меньшем кол-ве страниц, однако никак не на одной.
Что я делаю не так?

Re: Динамическое изменение размера страницы отчета

Добавлено: 06 сен 2019, 10:06
Aleksey
Здравствуйте,

Посмотрите приатаченный пример.

Спасибо.

Re: Динамическое изменение размера страницы отчета

Добавлено: 06 сен 2019, 20:08
ybelyaev
Aleksey, спасибо за предоставленный вариант решения. Развернул его, он работает практически идеально. Есть нюанс по размещению PageFooterBand'а, который заключается в том, что при формировании отчета он то периодически налезает на DataBand, то между ним и DataBand'ом возникает пустое пространство (шириной меньше высоты формата A4, как я полагаю). Как можно победить этот момент, чтобы PageFooterBand размещался сразу ниже DataBand'а? Понимаю, что смысл PageFooterBand'a в размещении внизу страницы, однако нужно, чтобы отчет выглядел нормально, без налезаний или пустых пространств.

Re: Динамическое изменение размера страницы отчета

Добавлено: 09 сен 2019, 14:11
Ivan
Здравствуйте.
спасибо за предоставленный вариант решения. Развернул его, он работает практически идеально.
Есть нюанс по размещению PageFooterBand'а, который заключается в том, что при формировании отчета он то периодически налезает на DataBand,
Не удалось воспроизвести данную ситуацию.
Вышлите пожалуйста ваш вариант отчёта для анализа.
Как можно победить этот момент, чтобы PageFooterBand размещался сразу ниже DataBand'а?
Понимаю, что смысл PageFooterBand'a в размещении внизу страницы, однако нужно, чтобы отчет выглядел нормально, без налезаний или пустых пространств.
PageFooter ВСЕГДА размещается внизу страницы, это его роль.
Вместо PageFooter используйте или Footer, или ReportSummary.

Спасибо.

Re: Динамическое изменение размера страницы отчета

Добавлено: 12 сен 2019, 13:08
ybelyaev
Ivan, спасибо за помощь.
После изменения PageFooter на Footer, либо ReportSummary, отчет стал выглядеть как надо - без налезаний содержимого бэндов или пустого пространства между бэндами в сгенерированном отчете.

Re: Динамическое изменение размера страницы отчета

Добавлено: 12 сен 2019, 16:19
Aleksey
Здравствуйте,

Отлично. Дайте знать, если будут еще вопросы.

Спасибо.