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>
View Code

注:在沒有為列提供明確的寬度時,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();
            }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM