Пример #1
0
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="report">report document</param>
		/// <param name="data">multiple report data</param>
		/// <exception cref="ArgumentException">Need at least two ReportData objects</exception>
		public MultipleReportPaginator(ReportDocument report, IEnumerable<ReportData> data)
		{
			using (var counter = new TimeCounter("\tMultipleReportPaginator Total:		{0}", true, true))
			{
				if (data == null)
					throw new ArgumentException("Need at least two ReportData objects");

				// create a list of report paginators and compute page counts
				_pageCount = 0;
				foreach (ReportData rd in data)
				{
					if (rd == null)
						continue;
					ReportPaginator paginator = new ReportPaginator(report, rd);
					_reportPaginators.Add(paginator);
					paginator.PageShift = _pageCount;
					paginator.TotalPageCount = _pageCount;
					counter.ShowTick("\tMultipleReportPaginator Paginator:	{0}");
					DocumentPage dp = paginator.GetPage(0);
					if ((dp != DocumentPage.Missing) && (dp.Size != Size.Empty))
						_pageSize = paginator.PageSize;
					_pageCount += paginator.PageCount;
					counter.ShowTick("\tMultipleReportPaginator PageCount:	{0}");
				}
				counter.ShowTick("\tMultipleReportPaginator Paginators:	{0}");
				foreach (ReportPaginator paginator in _reportPaginators)
					paginator.TotalPageCount = _pageCount;
				if (_reportPaginators.Count <= 0)
					throw new ArgumentException("Need at least two ReportData objects");
				counter.ShowTick("\tMultipleReportPaginator PageCount:	{0}");
			}
		}
Пример #2
0
		/// <summary>
		/// Helper method to create page header or footer from flow document template
		/// </summary>
		/// <param name="data">enumerable report data</param>
		/// <returns></returns>
		/// <exception cref="ArgumentNullException">data</exception>
		public XpsDocument CreateXpsDocument(IEnumerable<ReportData> data)
		{
			using (var counter = new TimeCounter("CreateXpsDocument Total:		{0}", true, true))
			{
				if (data == null)
					throw new ArgumentNullException("data");
				int count = 0;
				ReportData firstData = null;
				foreach (ReportData rd in data) { if (firstData == null) firstData = rd; count++; }
				if (count == 1)
					return CreateXpsDocument(firstData); // we have only one ReportData object -> use the normal ReportPaginator instead

				MemoryStream ms = new MemoryStream();
				Package pkg = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
				string pack = "pack://report.xps";
				PackageStore.RemovePackage(new Uri(pack));
				PackageStore.AddPackage(new Uri(pack), pkg);
				XpsDocument doc = new XpsDocument(pkg, CompressionOption.NotCompressed, pack);
				XpsSerializationManager rsm = new XpsSerializationManager(new XpsPackagingPolicy(doc), false);
				//DocumentPaginator paginator = ((IDocumentPaginatorSource)CreateFlowDocument()).DocumentPaginator;
				counter.ShowTick("CreateXpsDocument Prepare:	{0}");

				MultipleReportPaginator rp = new MultipleReportPaginator(this, data);
				counter.ShowTick("CreateXpsDocument Paginator:	{0}");
				rsm.SaveAsXaml(rp);
				counter.ShowTick("CreateXpsDocument SaveAsXaml:	{0}");
				return doc;
			}
		}
Пример #3
0
		/// <summary>
		/// Creates a flow document of the report data
		/// </summary>
		/// <returns></returns>
		/// <exception cref="ArgumentException">Flow document must have a specified page height</exception>
		/// <exception cref="ArgumentException">Flow document must have a specified page width</exception>
		/// <exception cref="ArgumentException">"Flow document must have only one ReportProperties section, but it has {0}"</exception>
		public FlowDocument CreateFlowDocument(out Hint hints)
		{
			using (var counter = new TimeCounter("\t\t\tReportDocument Total	{0}"))
			{
				FlowDocument res = GetFlowDocument();
				counter.ShowTick("\t\t\t\tReportDocument Load XAML:	{0}");

				if (res.PageHeight == double.NaN)
					throw new ArgumentException("Flow document must have a specified page height");
				if (res.PageWidth == double.NaN)
					throw new ArgumentException("Flow document must have a specified page width");

				// remember original values
				_pageHeight = res.PageHeight;
				_pageWidth = res.PageWidth;

				// search report properties
				DocumentWalker walker = new DocumentWalker();
				List<SectionReportHeader> headers = walker.Walk<SectionReportHeader>(res);
				List<SectionReportFooter> footers = walker.Walk<SectionReportFooter>(res);

				var hintList = walker.Walk<ReportHint>(res);
				hints = Hint.None;
				foreach (var hint in hintList)
				{
					hints |= hint.Hint;
					// remove properties section from FlowDocument
					DependencyObject parent = hint.Parent;
					if (parent is FlowDocument) { ((FlowDocument)parent).Blocks.Remove(hint); parent = null; }
					if (parent is Section) { ((Section)parent).Blocks.Remove(hint); parent = null; }
				}

				List<ReportProperties> properties = walker.Walk<ReportProperties>(res);
				if (properties.Count > 0)
				{
					if (properties.Count > 1)
						throw new ArgumentException(String.Format("Flow document must have only one ReportProperties section, but it has {0}", properties.Count));
					ReportProperties prop = properties[0];
					if (prop.ReportName != null)
						ReportName = prop.ReportName;
					if (prop.ReportTitle != null)
						ReportTitle = prop.ReportTitle;
					if (headers.Count > 0)
						PageHeaderHeight = headers[0].PageHeaderHeight;
					if (footers.Count > 0)
						PageFooterHeight = footers[0].PageFooterHeight;

					// remove properties section from FlowDocument
					DependencyObject parent = prop.Parent;
					if (parent is FlowDocument) { ((FlowDocument)parent).Blocks.Remove(prop); parent = null; }
					if (parent is Section) { ((Section)parent).Blocks.Remove(prop); parent = null; }
				}

				// make height smaller to have enough space for page header and page footer
				res.PageHeight = _pageHeight - _pageHeight * (PageHeaderHeight + PageFooterHeight) / 100d;

				// search image objects
				List<Image> images = new List<Image>();
				walker.Tag = images;
				walker.VisualVisited += new DocumentVisitedEventHandler(walker_VisualVisited);
				walker.Walk(res);

				// load all images
				foreach (Image image in images)
				{
					if (ImageProcessing != null)
						ImageProcessing(this, new ImageEventArgs(this, image));
					try
					{
						if (image.Tag is string)
							image.Source = new BitmapImage(new Uri("file:///" + Path.Combine(_xamlImagePath, image.Tag.ToString())));
					}
					catch (Exception ex)
					{
						// fire event on exception and check for Handled = true after each invoke
						if (ImageError != null)
						{
							bool handled = false;
							lock (ImageError)
							{
								ImageErrorEventArgs eventArgs = new ImageErrorEventArgs(ex, this, image);
								foreach (var ed in ImageError.GetInvocationList())
								{
									ed.DynamicInvoke(this, eventArgs);
									if (eventArgs.Handled) { handled = true; break; }
								}
							}
							if (!handled)
								throw;
						}
						else
							throw;
					}
					if (ImageProcessed != null)
						ImageProcessed(this, new ImageEventArgs(this, image));
					// TODO: find a better way to specify file names
				}

				return res;
			}
		}