WPF文档介绍(FlowDocument),并做打印输出
一、序论
WPF文档分为两大类,固定文档和流文档。
固定文档是指已经排好版,准备打印的文档,所有内容的位置都是固定的,使用XPS(XML Paper Specification,XML页面规范)标准。对于需要以原封不动的格式进行打印的文档是很重要的(如表格和出版物)。
流文档是为在计算机上查看而设计的文档,内容会调整自身以适应容器。用于屏幕上阅读非常理想(如软件中的帮助)。
WPF通过使用不同容器为这两种类型的文档提供支持,固定文档的容器是DocumentViewer,流文档的容器时FlowDocumentReader、FlowDocumentPageViewer和FlowDocumentScrollViewer,本文主要流文档。
- FlowDocumentReader:该容器显示整个文档,内容太多时自动使用滚动条移动文档,不支持分页和多列显示。
- FlowDocumentPageViewer:该容器将流文档分成多页,FlowDocumentPageViewer的开销比FlowDocumentReader大。
- FlowDocumentScrollViewer:允许滚动和分页,开销最大。
二、流文档
WPF流内容元素构成流文档,它主要由以下2部分组成:
Block元素(块元素)用于分组其他内容元素。
- List
- Paragraph
- Section
- Table
- BlockUIContainer
Inline元素(内联元素)被嵌入到块级别元素的内联级别元素
- Run
- Span
- LineBreak
- InlineUIContainer
- AchhoredBlock(Figure和Floater)
Block元素
设置内容元素格式的常用属性:LineHeight:为嵌套的文本内容设置行间距;TextAlignment:为嵌套的文本内容设置水平对齐方式(可以说Left、Right、Center)。
1.Paragraph它表示文本段落,技术上说段落不包含文本--而是包含内联级别元素的集合,存储在Paragraph.Inline集合中。TextIndent属性设置第一行的缩进量。
<FlowDocumentScrollViewer>
<FlowDocument>
<Paragraph Name="paragraph">Hello this is China</Paragraph>
<Paragraph>This is a second paragraph</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
((Run)paragraph.Inlines.FirstInline).Text="again";
2.List元素表示项目符号或数字列表,可以通过MarkerStyle属性进行选择。
<Paragraph>Top program language</Paragraph>
<List>
<ListItem>
<Paragraph>C#</Paragraph>
<Paragraph>C++</Paragraph>
</ListItem>
</List>
<Paragraph>To-do List</Paragraph>
<List MarkerStyle="Decimal">
<ListItem>
<Paragraph>WPF</Paragraph>
</ListItem>
<ListItem>
<Paragraph>Winform</Paragraph>
</ListItem>
</List>
3.Table元素
步骤:
在Table元素中放置TableRowGroup元素;TableRowGroup元素中为每一列添加TableRow元素;在每个TableRow元素中添加TableCell元素;在每个TableCell元素中放置块级别元素。
<Table BorderBrush="Black" BorderThickness="1"> <Table.Columns> <TableColumn Width="*"/> <TableColumn Width="3*"/> <TableColumn Width="*"/> </Table.Columns> <TableRowGroup Paragraph.TextAlignment="Left"> <TableRow FontWeight="Bold"> <TableCell BorderBrush="Black" BorderThickness="1"> <Paragraph>Rank</Paragraph> </TableCell> <TableCell> <Paragraph>Name</Paragraph> </TableCell> <TableCell> <Paragraph>Population</Paragraph> </TableCell> </TableRow> <TableRow> <TableCell> <Paragraph>1</Paragraph> </TableCell> <TableCell> <Paragraph>Rome</Paragraph> </TableCell> <TableCell> <Paragraph>1000000</Paragraph> </TableCell> </TableRow> <TableRow> <TableCell> <Paragraph>1</Paragraph> </TableCell> <TableCell> <Paragraph>Luoyang(HuNan),China</Paragraph> </TableCell> <TableCell> <Paragraph>3210000</Paragraph> </TableCell> </TableRow> <TableRow> <TableCell> <Paragraph>1</Paragraph> </TableCell> <TableCell> <Paragraph>Peshawar,pkeuysd</Paragraph> </TableCell> <TableCell> <Paragraph>1003400</Paragraph> </TableCell> </TableRow> </TableRowGroup> </Table>
注:在没有为列提供明确的宽度时,wpf将为所有列平均分配空间。
4.Section元素
Section元素本身没有任何内置的格式化设置,而是用于在某个方便的包中封装其他块级别元素,方便为整个部分应用常用格式。
<Section FontSize="20" Background="RED" Paragraph.LineHeight="1">
<Paragraph>this is first paragraph</Paragraph>
<Paragraph>this is second paragraph</Paragraph>
</Section>
5.BlockUIContainer元素
用来放控件。
<BlockUIContainer>
<Button HorizontalAlignment="Left" Name="hhhh" Content="this is BlockUIContainer"/>
</BlockUIContainer>
内联元素
1.Run元素包含实际文本
<Paragraph>
<Run>Hello World</Run>
</Paragraph>
Run会隐式创建
四、实际案例
参考:用WPF实现打印及打印预览 - guogangj - 博客园 (cnblogs.com)
设计的思路就是:文档模版(xaml)+数据(.net对象)
三、固定文档
写入内存的XPS文档
MemoryStream ms = new MemoryStream();//准备在内存中存储内容 Package package = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite); Uri DocumentUri = new Uri("pack://InMemoryDocument.xps"); PackageStore.RemovePackage(DocumentUri); PackageStore.AddPackage(DocumentUri, package); XpsDocument xpsDocument = new XpsDocument(package, CompressionOption.Fast, DocumentUri.AbsoluteUri);
使用完XPS文档之后,可关闭流以释放内存。
一个完整的打印功能
//构造一个基于内存的xps document MemoryStream ms = new MemoryStream(); Package package = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite); Uri DocumentUri = new Uri("pack://InMemoryDocument.xps"); PackageStore.RemovePackage(DocumentUri); PackageStore.AddPackage(DocumentUri, package); XpsDocument xpsDocument = new XpsDocument(package, CompressionOption.Fast, DocumentUri.AbsoluteUri); //将flow document写入基于内存的xps document中去 XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDocument); using (FileStream fs=File.Open(@"C:\Users\Yan\Desktop\WPF工程\WpfPrintDemo\OrderDocument.xaml", FileMode.Open)) { FlowDocument flowDocument = (FlowDocument)XamlReader.Load(fs); writer.Write(((IDocumentPaginatorSource)flowDocument).DocumentPaginator); docViewer.Document = xpsDocument.GetFixedDocumentSequence();//界面DocumentViewer预览 xpsDocument.Close(); ms.Dispose(); }
浙公网安备 33010602011771号