1. 程式人生 > >用WPF做報表控制元件(六)

用WPF做報表控制元件(六)

報表列印

前面的幾項功能,我做的控制元件都比DevExpress的報表控制元件效能要好,唯獨這個列印要差一些。但這也能用,畢竟列印的功能使用不多,四十頁紙之內速度還是可以的。

報表控制元件使用FlowDocument來列印。我們需要把資料重新填充到FlowDocument裡面。如下面的程式碼所示,把資料拼成一個XAML的字串,然後渲染出頁面:

StringBuilder flow_doc = new StringBuilder();
flow_doc.Append("<FlowDocument xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" FontSize=\"12\" FontFamily=\"微軟雅黑\">");
flow_doc.Append("<FlowDocument.Resources><Style TargetType=\"Table\" x:Key=\"BorderedTable\"><Setter Property=\"CellSpacing\" Value=\"0\"></Setter><Setter Property=\"BorderThickness\" Value=\"1\"></Setter><Setter Property=\"BorderBrush\" Value=\"#000\"></Setter></Style><Style TargetType=\"TableCell\" x:Key=\"BorderedCell\"><Setter Property=\"BorderThickness\" Value=\"0.5\"></Setter><Setter Property=\"BorderBrush\" Value=\"#000\"></Setter><Setter Property=\"Padding\" Value=\"3\"></Setter></Style></FlowDocument.Resources>");

StringBuilder table = new StringBuilder();
table.Append("<Table Style=\"{StaticResource BorderedTable}\"><Table.Columns>");
table.Append(sb);
table.Append("</Table.Columns><TableRowGroup Name=\"rowsDetails\">");
table.Append("</TableRowGroup></Table>");

flow_doc.Append(table);
flow_doc.Append("</FlowDocument>");

FlowDocument本身是有分頁功能的,但它遇到了DataGrid一開始遇到的問題:表頭怎麼放進去呢?

我使用的策略是:把FlowDocument的內容限制在頁面的下方,上方留出一點點空白。然後在每一頁紙渲染的過載函式裡,把表頭作為圖片畫進去!

先把表頭儲存成一張圖片,放在記憶體裡。

Global.HeadBmp = new RenderTargetBitmap((int)HeadGridContaner.ActualWidth, (int)HeadGridContaner.ActualHeight, 96d, 96d, PixelFormats.Default);
Global.HeadBmp.Render(HeadGridContaner);

然後我們需要繼承DocumentPaginator類,過載其GetPage函式,把表頭的圖片畫進去。

public override DocumentPage GetPage(int pageNumber)
{
    DocumentPage page = m_paginator.GetPage(pageNumber);
    ContainerVisual newpage = new ContainerVisual();

    DrawingVisual header = new DrawingVisual();
    using (DrawingContext ctx = header.RenderOpen())
    {
        ctx.DrawImage(Global.HeadBmp, new Rect() { X = 50, Y = 50, Width = Global.HeadBmp.Width, Height = Global.HeadBmp.Height });
    }

    newpage.Children.Add(page.Visual);
    newpage.Children.Add(header);

    //調整到A4紙大小
    double ratio = 1123 / page.Size.Width;
    newpage.Transform = new ScaleTransform(ratio, ratio);
    return new DocumentPage(newpage, new Size() { Width = page.Size.Width * ratio, Height = page.Size.Height * ratio }, new Rect() { X = page.BleedBox.X * ratio, Y = page.BleedBox.Y * ratio, Width = page.BleedBox.Width * ratio, Height = page.BleedBox.Height * ratio }, new Rect() { X = page.ContentBox.X * ratio, Y = page.ContentBox.Y * ratio, Width = page.ContentBox.Width * ratio, Height = page.ContentBox.Height * ratio });
}

至此,報表控制元件的功能基本完成。完整的程式碼下載:https://download.csdn.net/download/lweiyue/10646218