当前位置:首页 > 工具 > 正文内容

WPF 流文档处理与打印功能实现

访客 工具 2026年5月23日 3

WPF 提供了两种文档模型:固定文档和流文档。

固定文档采用预定义布局,适合精确打印需求,例如报表或出版物,其遵循 XPS 标准。流文档则具备自适应性,能够根据显示区域动态调整内容布局,适用于屏幕阅读场景,比如应用程序的帮助文档。

WPF 使用不同的控件来承载这两类文档:

  • DocumentViewer:用于展示固定文档。
  • FlowDocumentReaderFlowDocumentPageViewerFlowDocumentScrollViewer:专为流文档设计。其中 FlowDocumentScrollViewer 支持滚动浏览,而 FlowDocumentPageViewer 则按页展示文档内容。

构建流文档

流文档由一系列内容元素构成,这些元素分为两类:Block(块级)和 Inline(内联)。

Block 元素

这类元素通常作为容器使用,常见的包括:

  • Paragraph:表示段落,可包含多个内联元素。
  • List:用于创建项目符号或编号列表。
  • Table:用于组织表格结构的数据。
  • Section:无默认样式,主要用于包装一组块元素以便统一设置格式。
  • BlockUIContainer:可在文档中嵌入任意 UI 控件。

常用的格式控制属性有:LineHeight 设置行高,TextAlignment 指定文本对齐方式。

示例:使用 Paragraph 显示文本

<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";

创建列表项

<Paragraph>Top programming languages</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>

构建表格

<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>
    </TableRowGroup>
</Table>

组合内容区块

<Section FontSize="20" Background="Red" Paragraph.LineHeight="1">
    <Paragraph>this is first paragraph</Paragraph>
    <Paragraph>this is second paragraph</Paragraph>
</Section>

插入控件

<BlockUIContainer>
    <Button Content="Click Me"/>
</BlockUIContainer>

Inline 元素

此类元素必须位于 Block 内部,常用于富文本渲染:

  • Run:承载纯文本内容。
  • Span:可用于包裹其他内联元素。
  • LineBreak:强制换行。
  • InlineUIContainer:嵌入 UI 元素。
  • AnchoredBlock:如 Figure 或 Floater,用于浮动定位。

基本用法

<Paragraph>
    <Run>Hello World</Run>
</Paragraph>

实现文档打印

通过将 FlowDocument 转换为 XPS 文档,并利用 XpsDocumentWriter 进行写入操作,可以完成打印任务。

生成内存中的 XPS 文件

MemoryStream memoryStream = new MemoryStream();
Package pkg = Package.Open(memoryStream, FileMode.Create, FileAccess.ReadWrite);
Uri docUri = new Uri("pack://temp.xps");
PackageStore.RemovePackage(docUri);
PackageStore.AddPackage(docUri, pkg);
XpsDocument xpsDoc = new XpsDocument(pkg, CompressionOption.Normal, docUri.ToString());

执行打印流程

XpsDocumentWriter xpsWriter = XpsDocument.CreateXpsDocumentWriter(xpsDoc);

using (FileStream fs = File.Open("OrderTemplate.xaml", FileMode.Open))
{
    FlowDocument doc = (FlowDocument)XamlReader.Load(fs);
    xpsWriter.Write(((IDocumentPaginatorSource)doc).DocumentPaginator);
    
    docViewer.Document = xpsDoc.GetFixedDocumentSequence(); // 预览
}

xpsDoc.Close();
memoryStream.Dispose();

相关文章

Trojan服务器搭建与配置

一、整体架构(先对齐认知)Clash Meta (PC / iOS / Android)        ↓ TLS   Trojan Server (443)        ↓     InternetTrojan 的核心是: TLS + HTTPS 流量伪装 看起来像正常网站 非常适合...

Tailscale 的详细用法

Tailscale 是一种基于 WireGuard 协议 的 零配置 VPN(虚拟私有网络)服务,让设备之间能够 安全、加密地直接连接,就像它们在同一个本地网络一样。它的核心特点是 简单、安全、跨平台。Tailscale 非常适合 没有公网 IP、两台电脑不在同一局域网 的场景。 简单来说,Tailscale 是什么?Tailscale 是一款让你的各种设备(电脑、服务器、手机...

Clash Tun 模式 导致 爱快(iKuai SD-Wan)内网域名无法访问

一、Clash  DNS 配置dns:  enable: true  listen: 0.0.0.0:53  ipv6: true  enhanced-mode: redir-host  nameserver:    - 223.5.5.5    - 223.6.6.6iKuai 内网域名 ...

深入解析Node.js运行环境与异步I/O架构

深入解析Node.js运行环境与异步I/O架构

核心定义与价值Node.js本质上是一个JavaScript运行环境,而非编程语言或应用框架。它赋予了JavaScript脱离浏览器在服务端、命令行工具及网络应用中执行的能力。其核心意义在于:用单一语言打通前后端开发壁垒。基于事件驱动与非阻塞I/O的架构特性,Node.js在处理API网关、实时通信及微服务等I/O密集型场景时表现卓越,已成为现代后端工程的主流选择。浏览器沙箱限制1995年Java...

ADO.NET SQL参数化查询的最佳实践

在 ADO.NET 中执行 SQL 查询时,参数化查询是一种关键的安全措施和性能优化手段。它通过将 SQL 命令和用户提供的数据分开处理,有效防止了 SQL 注入攻击,并有助于数据库缓存执行计划。下面总结了几种常用的参数化查询方式。 1. 使用 SqlParameter 对象(推荐) 这是最推荐的参数化查询方式。通过显式创建 SqlParameter 对象,您可以精确控制参数的类...

基于ELK的日志集中化分析系统搭建

构建统一日志管理平台的必要性 在分布式架构中,各服务节点独立运行,日志分散存储于不同主机。传统通过命令行工具如grep、awk逐个检索日志的方式,在数据量庞大时效率极低,难以实现快速定位问题。为提升运维效率,需建立集中式日志处理体系,具备日志采集、传输、存储、分析与告警能力。 ELK技术栈核心组件解析 Elasticsearch:分布式搜索引擎,支持全文检索、实时数据分析和高可用集群部署,...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。