MVVM DataGrid生成为xps文件 实现对DataGrid的打印

我在网上找过一些打印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

posted on 2014-04-13 22:53  mitnickgeek  阅读(310)  评论(2编辑  收藏  举报

导航