Silverlight 4 报表打印的简单实现

 

我们要实现的报表内容如下图所示:

 

 

报表可以显示报表标题,各个字段名;报表还可以自动分页,显示总页数和当前页数;报表的主体数据绑定图片和各个字段的数据并能自动计算各行数据的合计数;

虽说是一个简单的样式,但麻雀虽小,五脏俱全。都应该能满足大多数场合报表打印的要求。

 

在Silverlight 4中实现这样的报表打印,需要以下几个步骤:

 

定义后台处理控件->定义报表模版->获取数据->填充数据到模版->打印报表

 

一.我们用VisualStudio2010新建一个Silverlight4的项目,并添加一个Silverlight控件项目(System.Windows.Printing.Reporting)

我们需要这个控件来处理分页和打印的各类属性。

添加一个Report.cs类,代码如下:

using System.Collections; using System.Collections.Generic; using System.Windows.Controls; using System.Windows.Markup; namespace System.Windows.Printing.Reporting { public class Report : FrameworkElement { public DataTemplate PageHeaderTemplate { get { return (DataTemplate)GetValue(PageHeaderTemplateProperty); } set { SetValue(PageHeaderTemplateProperty, value); } } public static readonly DependencyProperty PageHeaderTemplateProperty = DependencyProperty.Register("PageHeaderTemplate", typeof(DataTemplate), typeof(Report), new PropertyMetadata(null)); public DataTemplate PageFooterTemplate { get { return (DataTemplate)GetValue(PageFooterTemplateProperty); } set { SetValue(PageFooterTemplateProperty, value); } } public static readonly DependencyProperty PageFooterTemplateProperty = DependencyProperty.Register("PageFooterTemplate", typeof(DataTemplate), typeof(Report), new PropertyMetadata(null)); public DataTemplate ItemTemplate { get { return (DataTemplate)GetValue(ItemTemplateProperty); } set { SetValue(ItemTemplateProperty, value); } } public static readonly DependencyProperty ItemTemplateProperty = DependencyProperty.Register("ItemTemplate", typeof(DataTemplate), typeof(Report), new PropertyMetadata(null)); public DataTemplate ReportFooterTemplate { get { return (DataTemplate)GetValue(ReportFooterTemplateProperty); } set { SetValue(ReportFooterTemplateProperty, value); } } public static readonly DependencyProperty ReportFooterTemplateProperty = DependencyProperty.Register("ReportFooterTemplate", typeof(DataTemplate), typeof(Report), new PropertyMetadata(null)); public IEnumerable ItemsSource { get { return (IEnumerable)GetValue(ItemsSourceProperty); } set { SetValue(ItemsSourceProperty, value); } } public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(Report), new PropertyMetadata(null)); //public ItemCollection ItemsOnCurrentPage //{ // get { return (ItemCollection)GetValue(ItemsOnCurrentPageProperty); } // private set { SetValue(ItemsOnCurrentPageProperty, value); } //} //public static readonly DependencyProperty ItemsOnCurrentPageProperty = // DependencyProperty.Register("ItemsOnCurrentPage", typeof(ItemCollection), typeof(Report), new PropertyMetadata(null)); public string Title { get { return (string)GetValue(TitleProperty); } set { SetValue(TitleProperty, value); } } public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(Report), new PropertyMetadata("Report")); public int CurrentPageNumber { get { return (int)GetValue(CurrentPageNumberProperty); } private set { SetValue(CurrentPageNumberProperty, value); } } public static readonly DependencyProperty CurrentPageNumberProperty = DependencyProperty.Register("CurrentPageNumber", typeof(int), typeof(Report), new PropertyMetadata(0)); public int TotalPageCount { get { return (int)GetValue(TotalPageCountProperty); } private set { SetValue(TotalPageCountProperty, value); } } public static readonly DependencyProperty TotalPageCountProperty = DependencyProperty.Register("TotalPageCount", typeof(int), typeof(Report), new PropertyMetadata(0)); private PrintDocument _printDocument = new PrintDocument(); public PrintDocument PrintDocument { get { return _printDocument; } } public void Print() { CurrentPageNumber = 0; int pageIndex = 0; _printDocument.PrintPage += (s, e) => { if (pageIndex == 0) { BuildReport(e.PrintableArea); TotalPageCount = _pageTrees.Count; CurrentPageNumber = 0; } if (_pageTrees.Count > 0) { CurrentPageNumber++; e.PageVisual = _pageTrees[pageIndex]; } e.HasMorePages = pageIndex < _pageTrees.Count - 1; pageIndex++; }; _printDocument.BeginPrint += (s, e) => { OnBeginPrint(EventArgs.Empty); }; _printDocument.EndPrint += (s, e) => { OnEndPrint(EventArgs.Empty); }; _printDocument.Print(Title); } public event EventHandler EndPrint; protected void OnEndPrint(EventArgs args) { if (EndPrint != null) EndPrint(this, args); } public event EventHandler BeginPrint; protected void OnBeginPrint(EventArgs args) { if (BeginPrint != null) BeginPrint(this, args); } public event EventHandler EndBuildReport; protected void OnEndBuildReport(EventArgs args) { if (EndBuildReport != null) EndBuildReport(this, args); } public event EventHandler BeginBuildReport; protected void OnBeginBuildReport(EventArgs args) { if (BeginBuildReport != null) BeginBuildReport(this, args); } public event EventHandler EndBuildReportItem; protected void OnEndBuildReportItem(EventArgs args) { if (EndBuildReportItem != null) EndBuildReportItem(this, args); } public event EventHandler<PrintingEventArgs> BeginBuildReportItem; protected void OnBeginBuildReportItem(PrintingEventArgs args) { if (BeginBuildReportItem != null) BeginBuildReportItem(this, args); } public event EventHandler<PrintingEventArgs> BeginBuildReportFooter; protected void OnBeginBuildReportFooter(PrintingEventArgs args) { if (BeginBuildReportFooter != null) BeginBuildReportFooter(this, args); } private List<UIElement> _pageTrees = new List<UIElement>(); // Pre-calculates pages. This allows for total page count // as well as better handling of page breaks, and eventual // inclusion of groups and whatnot. If this takes too long, though // it'll exceed the timeout and make the printing fail in a // sandboxed silverlight application. Alternative would be to make // printing a two-step operation: First, build report, Second, user // clicks button to do the actual printing. That approach // introduces issues with data changing in-between the steps. private void BuildReport(Size printableArea) { _pageTrees.Clear(); CurrentPageNumber = 0; OnBeginBuildReport(EventArgs.Empty); if (ItemsSource == null) return; IEnumerable reportItems = ItemsSource; IEnumerator reportItemsEnumerator = reportItems.GetEnumerator(); reportItemsEnumerator.Reset(); StackPanel itemsPanel = null; Grid pagePanel = null; Size itemsPanelMaxSize = new Size(); // create first page pagePanel = GetNewPage(printableArea, out itemsPanel, out itemsPanelMaxSize); // add the items while (reportItemsEnumerator.MoveNext()) { PrintingEventArgs args = new PrintingEventArgs(); args.DataContext = reportItemsEnumerator.Current; OnBeginBuildReportItem(args); // create row. Set data context. FrameworkElement row = ItemTemplate.LoadContent() as FrameworkElement; row.DataContext = args.DataContext; row.Measure(printableArea); // create a new page if we're out of room here if (row.DesiredSize.Height + itemsPanel.DesiredSize.Height > itemsPanelMaxSize.Height) { pagePanel = GetNewPage(printableArea, out itemsPanel, out itemsPanelMaxSize); } itemsPanel.Children.Add(row); itemsPanel.Measure(printableArea); } // create report footer PrintingEventArgs reportFooterEventArgs = new PrintingEventArgs(); reportFooterEventArgs.DataContext = this; OnBeginBuildReportFooter(reportFooterEventArgs); FrameworkElement reportFooter = ReportFooterTemplate.LoadContent() as FrameworkElement; if (reportFooter != null) { reportFooter.DataContext = reportFooterEventArgs.DataContext; reportFooter.Measure(printableArea); // fit the footer into the report if (reportFooter.DesiredSize.Height + itemsPanel.DesiredSize.Height > itemsPanelMaxSize.Height) { pagePanel = GetNewPage(printableArea, out itemsPanel, out itemsPanelMaxSize); } itemsPanel.Children.Add(reportFooter); } OnEndBuildReport(EventArgs.Empty); } private Grid GetNewPage(Size printableArea, out StackPanel itemsPanel, out Size itemsPanelMaxSize) { CurrentPageNumber++; Grid pagePanel = new Grid(); RowDefinition headerRow = new RowDefinition(); headerRow.Height = GridLength.Auto; RowDefinition itemsRow = new RowDefinition(); itemsRow.Height = new GridLength(1, GridUnitType.Star); RowDefinition footerRow = new RowDefinition(); footerRow.Height = GridLength.Auto; pagePanel.RowDefinitions.Add(headerRow); pagePanel.RowDefinitions.Add(itemsRow); pagePanel.RowDefinitions.Add(footerRow); // header FrameworkElement header = PageHeaderTemplate.LoadContent() as FrameworkElement; header.DataContext = this; Grid.SetRow(header, 0); pagePanel.Children.Add(header); header.Measure(new Size(printableArea.Width, printableArea.Height)); // create body to fit in between itemsPanel = new StackPanel(); itemsPanel.Orientation = Orientation.Vertical; itemsPanel.HorizontalAlignment = HorizontalAlignment.Stretch; itemsPanel.VerticalAlignment = VerticalAlignment.Top; Grid.SetRow(itemsPanel, 1); pagePanel.Children.Add(itemsPanel); // create footer FrameworkElement footer = PageFooterTemplate.LoadContent() as FrameworkElement; footer.DataContext = this; Grid.SetRow(footer, 2); pagePanel.Children.Add(footer); footer.Measure(new Size(printableArea.Width, printableArea.Height)); itemsPanelMaxSize = new Size(printableArea.Width, printableArea.Height - footer.DesiredSize.Height - header.DesiredSize.Height); _pageTrees.Add(pagePanel); return pagePanel; } } }

 

添加一个获取数据集的属性PrintingEventArgs.cs

using System.Windows; namespace System.Windows.Printing.Reporting { public class PrintingEventArgs : EventArgs { public object DataContext { get; set; } } }

 

在主项目添加对刚建立的控件的引用,在MainPage.xaml里也添加控件的引用,代码如下:

 

<UserControl x:Class="SilverlightPrintExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:reporting="clr-namespace:System.Windows.Printing.Reporting;assembly=Silverlight.Reporting"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

 

在MainPage.xaml的<Grid></Grid>标签内定义以下模版:

 

二.定义报表模版

 

我们把报表模版分成:表头模版(PageHeaderTemplate),主体数据模版(ItemTemplate),合计数模版(ReportFooterTemplate)和页脚模版(PageFooterTemplate),并使用以上的名称。

 

在这里我们只示范比较简单的模版XAML文件,大家可以根据自己的需要进行修改。

 

1.制作表头模版(PageHeaderTemplate):

 

<!--制作报表模版--> <reporting:Report x:Name="Report" Title="成绩报表打印"> <!--定义表头标题样式--> <reporting:Report.Resources> <Style x:Key="HeaderText" TargetType="TextBlock"> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="TextAlignment" Value="Left" /> <Setter Property="HorizontalAlignment" Value="Stretch" /> </Style> </reporting:Report.Resources> <!--表头模版--> <reporting:Report.PageHeaderTemplate> <DataTemplate> <Grid Margin="1"> <Rectangle Stroke="Black" /> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <TextBlock Text="{Binding Title}" Grid.Row="0" FontSize="16" FontWeight="Bold" Margin="5" HorizontalAlignment="Left" VerticalAlignment="Top" /> <TextBlock Text="{Binding CurrentPageNumber, StringFormat='第 {0}页'}" Grid.Row="0" Margin="1" HorizontalAlignment="Right" VerticalAlignment="Top" /> <Grid Grid.Row="1" HorizontalAlignment="Stretch" Margin="1"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="72" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" Text="会员照片" /> <TextBlock Grid.Column="1" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" Text="姓名" /> <TextBlock Grid.Column="2" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="场地" /> <TextBlock Grid.Column="3" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="01号" /> <TextBlock Grid.Column="4" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="02号" /> <TextBlock Grid.Column="5" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="03号" /> <TextBlock Grid.Column="6" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="04号" /> <TextBlock Grid.Column="7" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="05号" /> <TextBlock Grid.Column="8" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="06号" /> <TextBlock Grid.Column="9" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="07号" /> <TextBlock Grid.Column="10" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="08号" /> <TextBlock Grid.Column="11" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="09号" /> <TextBlock Grid.Column="12" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="10号" /> <TextBlock Grid.Column="13" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="11号" /> <TextBlock Grid.Column="14" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="12号" /> <TextBlock Grid.Column="15" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="13号" /> <TextBlock Grid.Column="16" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="14号" /> <TextBlock Grid.Column="17" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="15号" /> <TextBlock Grid.Column="18" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="16号" /> <TextBlock Grid.Column="19" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="17号" /> <TextBlock Grid.Column="20" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="18号" /> <TextBlock Grid.Column="21" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="总杆" /> <TextBlock Grid.Column="22" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="差点" /> <TextBlock Grid.Column="23" Style="{StaticResource HeaderText}" mce_Style="{StaticResource HeaderText}" TextAlignment="Right" Text="净杆" /> </Grid> </Grid> </Grid> </DataTemplate> </reporting:Report.PageHeaderTemplate>

 

2.制作主体数据模版(ItemTemplate):

<!--主体数据模版--> <reporting:Report.ItemTemplate> <DataTemplate> <Grid HorizontalAlignment="Stretch" Margin="1"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="72" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> </Grid.ColumnDefinitions> <Image Grid.Column="0" Source="{Binding Pic}" Width="72" Height="82" /> <TextBlock Grid.Column="1" Text="{Binding Name}" FontWeight="Bold" /> <TextBlock Grid.Column="2" Text="{Binding ChangDiName}" FontWeight="Bold" /> <TextBlock Grid.Column="3" Text="{Binding P1}" FontWeight="Bold" /> <TextBlock Grid.Column="4" Text="{Binding P2}" FontWeight="Bold" /> <TextBlock Grid.Column="5" Text="{Binding P3}" FontWeight="Bold" /> <TextBlock Grid.Column="6" Text="{Binding P4}" FontWeight="Bold" /> <TextBlock Grid.Column="7" Text="{Binding P5}" FontWeight="Bold" /> <TextBlock Grid.Column="8" Text="{Binding P6}" FontWeight="Bold" /> <TextBlock Grid.Column="9" Text="{Binding P7}" FontWeight="Bold" /> <TextBlock Grid.Column="10" Text="{Binding P8}" FontWeight="Bold" /> <TextBlock Grid.Column="11" Text="{Binding P9}" FontWeight="Bold" /> <TextBlock Grid.Column="12" Text="{Binding P10}" FontWeight="Bold" /> <TextBlock Grid.Column="13" Text="{Binding P11}" FontWeight="Bold" /> <TextBlock Grid.Column="14" Text="{Binding P12}" FontWeight="Bold" /> <TextBlock Grid.Column="15" Text="{Binding P13}" FontWeight="Bold" /> <TextBlock Grid.Column="16" Text="{Binding P14}" FontWeight="Bold" /> <TextBlock Grid.Column="17" Text="{Binding P15}" FontWeight="Bold" /> <TextBlock Grid.Column="18" Text="{Binding P16}" FontWeight="Bold" /> <TextBlock Grid.Column="19" Text="{Binding P17}" FontWeight="Bold" /> <TextBlock Grid.Column="20" Text="{Binding P18}" FontWeight="Bold" /> <TextBlock Grid.Column="21" Text="{Binding TotalGan}" FontWeight="Bold" /> <TextBlock Grid.Column="22" Text="{Binding ChaDian}" FontWeight="Bold" /> <TextBlock Grid.Column="23" Text="{Binding JingGan}" FontWeight="Bold" /> </Grid> </DataTemplate> </reporting:Report.ItemTemplate>

 

 

3.制作各行数据的合计数模版(ReportFooterTemplate):

   该模版一般位于主体数据的右下方

<reporting:Report.ReportFooterTemplate> <DataTemplate> <Grid Margin="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="72" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> <ColumnDefinition Width="30" /> </Grid.ColumnDefinitions> <!--在最后的3格分别显示总杆合计,差点合计和净杆合计--> <TextBlock Grid.Column="19" Text="合计:" TextAlignment="Right" FontWeight="Bold" /> <TextBlock Grid.Column="21" Text="{Binding ZhongGanTotal, StringFormat='{}{0}'}" TextAlignment="Left" FontWeight="Bold" /> <TextBlock Grid.Column="22" Text="{Binding ChaDianTotal, StringFormat='{}{0}'}" TextAlignment="Left" FontWeight="Bold" /> <TextBlock Grid.Column="23" Text="{Binding JingGanTotal, StringFormat='{}{0}'}" TextAlignment="Left" FontWeight="Bold" /> </Grid> </DataTemplate> </reporting:Report.ReportFooterTemplate>

 

 

4.制作页脚模版(PageFooterTemplate):

   该模版一般用来显示当前页数和总页数。

<!--页脚模版--> <reporting:Report.PageFooterTemplate> <DataTemplate> <Grid Margin="1"> <Rectangle Stroke="Black" /> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="5"> <TextBlock Text="{Binding CurrentPageNumber, StringFormat='第{0}页'}" /> <TextBlock Text="{Binding TotalPageCount, StringFormat=' 总页数: {0}'}" /> </StackPanel> </Grid> </DataTemplate> </reporting:Report.PageFooterTemplate>

 

 

在MainPage.xaml里添加一个打印按钮

 

<Button Width="200" Height="100" Content="打印" Click="Print_Report"/>

 

三.获取打印数据

获取打印数据的方式有多种多样,比如:WCF,Webservice,.Net RIA Service等等。在这里我们简单的用一个ObservableCollection

来填充我们需要的数据。

1.定义一个数据模型DataTemplate.cs

using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace SilverlightPrintExample { public class DataTemplate { public string Pic { get; set; }//会员照片 public string Name { get; set; }//会员姓名 public string ChangDiName { get; set; }//场地名称 public string sDate { get; set; }//日期 public int P1 { get; set; } public int P2 { get; set; } public int P3 { get; set; } public int P4 { get; set; } public int P5 { get; set; } public int P6 { get; set; } public int P7 { get; set; } public int P8 { get; set; } public int P9 { get; set; } public int P10 { get; set; } public int P11 { get; set; } public int P12 { get; set; } public int P13 { get; set; } public int P14 { get; set; } public int P15 { get; set; } public int P16 { get; set; } public int P17 { get; set; } public int P18 { get; set; } public int TotalGan { get; set; }//总杆 public decimal ChaDian { get; set; }//差点 public decimal JingGan { get; set; } //净杆 public DataTemplate() { } public static DataTemplate CreateDataTemplate(string _pic, string _name, string _changdiname, string _sdate, int _p1, int _p2, int _p3, int _p4, int _p5, int _p6, int _p7, int _p8, int _p9, int _p10, int _p11, int _p12, int _p13, int _p14, int _p15, int _p16, int _p17, int _p18, int _totalgan, decimal _chadian, decimal _jinggan) { return new DataTemplate { Pic = _pic, Name = _name, ChangDiName = _changdiname, sDate = _sdate, P1 = _p1, P2 = _p2, P3 = _p3, P4 = _p4, P5 = _p5, P6 = _p6, P7 = _p7, P8 = _p8, P9 = _p9, P10 = _p10, P11 = _p11, P12 = _p12, P13 = _p13, P14 = _p14, P15 = _p15, P16 = _p16, P17 = _p17, P18 = _p18, TotalGan = _totalgan, ChaDian = _chadian, JingGan = _jinggan }; } } }

2.定义数据接口GolfData.cs

using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Collections.ObjectModel; namespace SilverlightPrintExample { public class GolfData { readonly ObservableCollection<DataTemplate> golfReportData; public GolfData()//添加一些实验数据 { if (golfReportData ==null) { golfReportData = new ObservableCollection<DataTemplate>(); golfReportData.Add(DataTemplate.CreateDataTemplate("http://www.dengfeng.org/youpeng/Pics/metoo.jpg", "登峰","加州","2010-10-1", 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,18,3,15)); golfReportData.Add(DataTemplate.CreateDataTemplate("http://www.dengfeng.org/youpeng/Pics/metoo.jpg", "登峰", "加州", "2010-10-1", 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 3, 33)); golfReportData.Add(DataTemplate.CreateDataTemplate("http://www.dengfeng.org/youpeng/Pics/metoo.jpg", "登峰", "加州", "2010-10-1", 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 54, 3, 52)); } } public ObservableCollection<DataTemplate> getGolfDataTemplate()//返回我们创建的实验数据 { return new ObservableCollection<DataTemplate> (golfReportData); } } }

3.定义一个各行数据合计数的模型Heji.cs

namespace SilverlightPrintExample { public class Heji { public int ZhongGanTotal { get; set; }//总杆的合计 public decimal ChaDianTotal { get; set; }//差点的合计 public decimal JingGanTotal { get; set; }//净杆的合计 } }

 

这样,我们就可以把以上自定义的数据填充到报表了。

 

四.填充数据到模版

 

在MainPage.cs里,编写如下代码:

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Collections.ObjectModel; namespace SilverlightPrintExample { public partial class MainPage : UserControl { Heji heji;//计算合计数 ObservableCollection<DataTemplate> DataToFill; public MainPage() { InitializeComponent(); GolfData gd = new GolfData(); DataToFill = gd.getGolfDataTemplate(); InitializeReport(); } private void InitializeReport() { Report.EndPrint += (s, e) => { MessageBox.Show("报表成功打印!"); }; Report.BeginBuildReport += (s, e) => { //初始化合计数 heji = new Heji(); }; Report.BeginBuildReportItem += (s, e) => { //处理完一条记录就会触发这个方法,所以我们在这里把合计累加起来 var item = e.DataContext as DataTemplate; heji.ZhongGanTotal += item.TotalGan; heji.ChaDianTotal += item.ChaDian; heji.JingGanTotal += item.JingGan; }; Report.BeginBuildReportFooter += (s, e) => { //合计 e.DataContext = heji; }; Report.ItemsSource = DataToFill; //把数据集给报表 } private void Print_Report(object sender, RoutedEventArgs e) { Report.Print();//打印报表 } } }

 

最后把报表打印出来:

 

五.打印报表

 

 private void Print_Report(object sender, RoutedEventArgs e)
        {
            Report.Print();//打印报表
        }

 

 以上内容只是一个Silverlight简单的报表打印的实现,还有很多功能需要完善,比如打印预览界面的实现。请大家完善它。

建议大家安装个PDF打印软件来调试程序,否则非常的费纸张 :)

 

 全部源码下载:http://download.csdn.net/detail/soft2buy/8172801

 

 

你可能感兴趣的:(report,silverlight,报表,binding,DataTemplate)