我有一个 ICommand,PrintReport。它的执行函数执行以下操作:
void printReport(object o)
{
var dialog = new PrintDialog()
{
CurrentPageEnabled = true,
UserPageRangeEnabled = true
};
if (dialog.ShowDialog() == true)
{
var size = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight);
FlowPaginator.PageWidth = size.Width;
FlowPaginator.PageHeight = size.Height;
CreateReport(size);
dialog.PrintDocument(new FlowPaginator(document) { PageSize = size }, string.Empty);
}
}
FlowPaginator 是 DocumentPaginator 的一个子类,当我创建 FlowDocument 时,我找不到直接在其中添加 Header 和 Footer 的方法,因此我将它们添加到此类中。首先,我创建 FlowDocument 文档,然后将其传递给 PrintDocument 方法中的新 FlowPaginator。
void CreateReport(Size pageSize)
{
document = new FlowDocument()
{
PageWidth = pageSize.Width,
PageHeight = pageSize.Height,
PagePadding = new Thickness(FlowPaginator.Margin,
Header(pageSize).DesiredSize.Height,
FlowPaginator.Margin,
FlowPaginator.Margin)
};
var table = new Table()
{
FontFamily = SystemFonts.MessageFontFamily,
FontStyle = SystemFonts.MessageFontStyle,
FontSize = 11.0,
CellSpacing = 0,
Columns =
{
new TableColumn(){ Width = new GridLength(ColumnWidth) },
new TableColumn(){ Width = new GridLength(pageSize.Width - (2.0 * FlowPaginator.Margin) - (4 * ColumnWidth)) },
new TableColumn(){ Width = new GridLength(ColumnWidth) },
new TableColumn(){ Width = new GridLength(ColumnWidth) },
new TableColumn(){ Width = new GridLength(ColumnWidth) },
}
};
var rowNum = 1;
foreach (var item in Reportables)
{
var rowGroup = new TableRowGroup();
var row = new TableRow();
row.Cells.Add(new TableCell(new Paragraph(new Run(item.Date.ToString("dd/MM/yyyy")))));
row.Cells.Add(new TableCell(new Paragraph(new Run(item.Particulars))));
row.Cells.Add(new TableCell(new Paragraph(new Run(item.Receivable.ToString("#,##0;(#,##0);- ")))) { TextAlignment = TextAlignment.Right });
row.Cells.Add(new TableCell(new Paragraph(new Run(item.Receipt.ToString("#,##0;(#,##0);- ")))) { TextAlignment = TextAlignment.Right });
row.Cells.Add(new TableCell(new Paragraph(new Run(item.Balance.ToString("#,##0;(#,##0);- ")))) { TextAlignment = TextAlignment.Right });
if (rowNum % 2 == 0) row.Background = Brushes.LightBlue;
rowGroup.Rows.Add(row);
table.RowGroups.Add(rowGroup);
rowNum++;
}
document.Blocks.Add(table);
}
为了在 Flowdocument 的每一页上都留出空间放置 Header,我调用了一个函数 Header(pageSize).DesiredSize.Height,该函数在 PagePadding 中返回一个 UIElement。并且对于我的表格报告的每一列,我指定了 TableColumn Width。FlowPaginator 类中包含以下内容:
public class FlowPaginator : DocumentPaginator
{
public static double PageWidth, PageHeight;
public const double Margin = 96.0;
DocumentPaginator paginator;
public FlowPaginator(FlowDocument document)
{
paginator = ((IDocumentPaginatorSource)document).DocumentPaginator;
}
public override bool IsPageCountValid => paginator.IsPageCountValid;
public override int PageCount => paginator.PageCount;
public override Size PageSize { get => paginator.PageSize; set => paginator.PageSize = value; }
public override IDocumentPaginatorSource Source => paginator.Source;
public override DocumentPage GetPage(int pageNumber)
{
return new DocumentPage(new ContainerVisual()
{
Children =
{
LedgerVM.Header(PageSize),
paginator.GetPage(pageNumber).Visual,
Footer(++pageNumber)
}
});
}
UIElement Footer(int pageNo){ ... }
}
在 GetPage 中,我必须调用 CreateReport 方法中使用的相同静态 Header 函数来添加页眉,然后添加填充内容,最后必须调用同一类的另一个函数 Footer 来获取每页的页脚。
我想对 FlowDocument 的第二列使用 GridUnitType.Star,对其余 4 列使用 GridLength.Auto,但到目前为止我还没有找到任何方法可以做到这一点,而且我还想在创建 FlowDocument 时直接在其中添加 Header/Footer,有什么方法可以做到这一点,或者可以进一步简化这个过程吗?
Note:此问题总结整理于:May printing this FlowDocument be simplified?