我在网上找过一些打印DataGrid数据的文章,但是都是寥寥几句,说得不甚清楚,评论中也看到和我有同样问题的同仁,和我同等水平的同学问题都未因那寥寥几句得到解决,自己鼓捣了半天后,写出了这样的方法,用于将DataGrid的数据用.xps文件保存,这样就可以通过xps Viewer打印了。
将DataGrid的数据打印为xps文件,我的方法是事先定义一个FixedPage.xaml,该FixedPage.xaml就是要打印的页的布局,同时这个FixedPage.xaml的各个控件需要定义其x:Name属性,这是为了在操作FixedPage的类中能够通过FindName()方法找到该控件,并对其操作。比如现在要对FixedPage中的DataGrid进行数据绑定,该DataGrid的x:Name="dg",该FixedPage实例为fp,则DataGrid dg = fp.FindName("dg") as DataGrid; dg.ItemsSource = paraCollection;
FixedPage代码,FixedPage的样式就是要打印的页面的样式,FixedPage是建立的UserControl将<UserControl></UserControl>标签改为<FixedPage></FixedPage>标签得到的,在<UserControl></UserControl>标签下设计好UI在修改为<FixedPage></FixedPage>,为FixedPage的需要被操作的控件设置x:Name
LcHistoryEventViewFixedPage.xaml
<FixedPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Name="Window" UseLayoutRounding="True" Width="Auto" Height="Auto"> <Grid x:Name="LayoutRoot" DataContext="{Binding ParaCollectionDetail}"> <Grid.RowDefinitions> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> <RowDefinition></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition></ColumnDefinition> </Grid.ColumnDefinitions> <TextBlock Name="tb" Grid.Row="0" Grid.Column="1" Text=""></TextBlock> <Label Grid.Row="1" Grid.Column="0" Content="打印时间"></Label> <TextBlock Name="currentTime" Grid.Row="1" Grid.Column="1" Text="{Binding SysTime}"></TextBlock> <DataGrid Grid.Row="2" ItemsSource="{Binding ParaDetail}" Name="dg" IsSynchronizedWithCurrentItem="False"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Path=DeviceNid}" Header="设备NID" CanUserSort="True"/> <DataGridTextColumn Binding="{Binding Path=event_code}" Header="事件代码" CanUserSort="True" /> <DataGridTextColumn Binding="{Binding Path=Event_FlagName}" Header="事件标志" CanUserSort="True" /> <DataGridTextColumn Binding="{Binding Path=Occur_Time}" Header="发生时间" CanUserSort="True" /> </DataGrid.Columns> </DataGrid> <Label Name="StrPageBar" Grid.Row="3" Grid.Column="1" Content="{Binding StrPageBar}"></Label> </Grid> </FixedPage>
PrintHelper.cs 该类的方法通过获取FixedPage的路径
这里就是通过FixedPage的地址取得FixedPage页后,对FixedPage的控件直接操作,对其进行数据绑定。
这里如果不使用FixedPage对象数组,对该数组进行操作,那么无论有多少数据,无论DataGrid有几行生成的.xps文件都只有一页,DataGrid数据都无法完全显示。
这里我通过一个CacheIndex去记录打印完一页之后,需要从DataGird的第几行数据开始打印下一页,通过paraCache保存当前要打印页的第CacheIndex至CacheIndex+iSize条数据,也就是所有数据集PageData的第CacheIndex至CacheIndex+iSize条数据。
using System; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using PrintXPS.Service.Entity; using PrintXPS.Utils; namespace PrintXPS.Service { public class PrintHelper { /// <summary> /// 将DATAGRID 内容保存为XPS打印文件 /// </summary> /// <param name="PageSize">每页显示数据条数</param> /// <param name="PageData">DATAGRID数据集合</param> /// <param name="FixedPageAddress">FIXEDPAGE文件路径</param> /// <param name="EffectiveTime">参数生效时间</param> public static void PrintDataPage(int PageSize, PrintCtrls PageData, string FixedPageAddress, string EffectiveTime) { ICollectionView paraCollection; int iCount = PageData.Count; if (iCount == 0) { MessageBox.Show(string.Format("未查询到相应数据,无法打印!")); return; } int CacheIndex = 0;//记录索引 int iPageCount = PageBarXPS.getPageCount(PageSize, iCount)[0]; int iPageCount1 = iPageCount; int PageAmount = PageBarXPS.getPageCount(PageSize, iCount)[1]; FixedPage[] tt = new FixedPage[iPageCount]; if (PageAmount != 0) { iPageCount = iPageCount - 1; PrintCtrls paraCache = new PrintCtrls(); Uri printViewUri = new Uri(FixedPageAddress, UriKind.Relative); tt[iPageCount] = (FixedPage)Application.LoadComponent(printViewUri); for (int i = iPageCount * PageSize; i < iCount; i++) { paraCache.Add(PageData[i]); } DataGrid dg = tt[iPageCount].FindName("dg") as DataGrid; TextBlock tb1 = tt[iPageCount].FindName("tb") as TextBlock; tb1.Text = EffectiveTime; TextBlock tb2 = tt[iPageCount].FindName("currentTime") as TextBlock; tb2.Text = DateTime.Now.ToString(); Label l1 = tt[iPageCount].FindName("StrPageBar") as Label; l1.Content = PageBarXPS.createPageBar(PageSize, iCount, iPageCount1); paraCollection = new CollectionView(paraCache); dg.ItemsSource = paraCollection; } for (int i = 0; i < iPageCount; i++) { PrintCtrls paraCache = new PrintCtrls(); Uri printViewUri = new Uri(FixedPageAddress, UriKind.Relative); tt[i] = (FixedPage)Application.LoadComponent(printViewUri); for (; CacheIndex < PageSize * (i + 1); CacheIndex++) { paraCache.Add(PageData[CacheIndex]); } DataGrid dg = tt[i].FindName("dg") as DataGrid; TextBlock tb1 = tt[i].FindName("tb") as TextBlock; tb1.Text = EffectiveTime; TextBlock tb2 = tt[i].FindName("currentTime") as TextBlock; tb2.Text = DateTime.Now.ToString(); Label l1 = tt[i].FindName("StrPageBar") as Label; l1.Content = PageBarXPS.createPageBar(PageSize, iCount, i + 1); paraCollection = new CollectionView(paraCache); dg.ItemsSource = paraCollection; } if (FileHelper.SaveXPS(tt, true, iPageCount1)) MessageBox.Show(string.Format("文件保存成功")); else MessageBox.Show("取消文件保存"); } } }
将FixedPage生成为的.xps文件的方法
FixedDocument的实例写入创建的XpsDocument的实例,就将FixedPage页写入了.xps文件,DataGrid的数据就保存成了.xps文件,便可以打印了。
FileHelper.cs
using System; using System.IO; using System.Windows; using System.Windows.Documents; using System.Windows.Markup; using System.Windows.Xps; using System.Windows.Xps.Packaging; using Microsoft.Win32; namespace PrintXPS.Utils { public class FileHelper { private string GetXPSFromDialog(bool isSaved) { if (isSaved) { SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "XPS Document files (*.xps)|*.xps"; saveFileDialog.FilterIndex = 1; if (saveFileDialog.ShowDialog() == true) { return saveFileDialog.FileName; } else { return null; } } else return string.Format("{0}\\temp.xps", Environment.CurrentDirectory);//制造一个临时存储 } /// <summary> /// 这个静态方法主要是显示选择对话框以提供文件的保存位置 /// 将传入的FixedPage对象数组(多页)写入到.xps文件 /// </summary> /// <param name="page"></param> /// <param name="page"></param> /// <param name="isSaved"></param> /// <returns></returns> public static bool SaveXPS(FixedPage[] page, bool isSaved, int iPageCount) { FixedDocument fixedDoc = new FixedDocument();//创建一个文档 fixedDoc.DocumentPaginator.PageSize = new Size(96 * 8.5, 96 * 11); PageContent[] pageContent = new PageContent[iPageCount]; for (int i = 0; i < iPageCount; i++) { pageContent[i] = new PageContent(); ((IAddChild)pageContent[i]).AddChild(page[i]); fixedDoc.Pages.Add(pageContent[i]);//将对象加入到当前文档中 } FileHelper fh = new FileHelper(); string containerName = fh.GetXPSFromDialog(isSaved); if (containerName != null) { try { File.Delete(containerName); } catch (Exception e) { MessageBox.Show(e.Message); } XpsDocument <span style="background-color: rgb(255, 255, 255);">_xpsDocument = new XpsDocument(containerName, FileAccess.Write);</span> XpsDocumentWriter xpsdw = XpsDocument.CreateXpsDocumentWriter(_xpsDocument); xpsdw.Write(fixedDoc);//写入XPS文件 _xpsDocument.Close(); return true; } else return false; } } }
处理数据分页的类
//PageBar.cs namespace PrintXPS.Utils { public class PageBarXPS { /// <summary> /// 创建FixedPage的PageBar /// </summary> /// <param name="iSize">总页数</param> /// <param name="iCount">每页记录数</param> /// <param name="curPageNo">当前页号</param> /// <returns></returns> public static string createPageBar(int iSize, int iCount, int curPageNo) { string strPageBar = string.Empty; int Size = iSize; int Count = iCount; int iPageCount = 0; int iLastPageCount = 0; int iCurPageNo = curPageNo; if ((iCount / iSize) == 0) { iPageCount = 1; } else { iPageCount = iCount / iSize; iLastPageCount = iCount - iPageCount * iSize; if (iLastPageCount == 0) { iPageCount = iCount / iSize; } else { iPageCount = iCount / iSize + 1; } } strPageBar = "第" + iCurPageNo + "页//" + "共" + iPageCount + "页"; return strPageBar; } /// <summary> /// 获得页数即需要创建的fixedPage数,A[0]为页数,A[1]为最后一页记录数 /// </summary> /// <param name="iSize"></param> /// <param name="iCount"></param> /// <returns></returns> public static int[] getPageCount(int iSize, int iCount) { int Size = iSize; int Count = iCount; int iPageCount = 0; int iLastPageCount = 0; int[] result = new int[2]; if ((iCount / iSize) == 0) { iPageCount = 1; iLastPageCount = iCount; } else { iPageCount = iCount / iSize; iLastPageCount = iCount - iPageCount * iSize; if (iLastPageCount == 0) { iPageCount = iCount / iSize; iLastPageCount = iCount; } else { iPageCount = iCount / iSize + 1; } } result[0] = iPageCount; result[1] = iLastPageCount; return result; } } }
源码 下载地址:http://ishare.iask.sina.com.cn/f/22825271.html?retcode=0