基于WPF实现打印机连接与打印功能
一、项目配置
-
创建WPF项目
dotnet new wpf -n WpfPrinterDemo cd WpfPrinterDemo
-
添加必要引用
System.Printing
(用于打印机管理)System.Windows.Controls
(界面控件)
二、界面设计 (MainWindow.xaml)
<Window x:Class="WpfPrinterDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="打印机Demo" Height="450" Width="800"><Grid><!-- 打印预览区域 --><ScrollViewer VerticalScrollBarVisibility="Auto" Margin="10"><FlowDocument x:Name="PrintDocument" PagePadding="20"FontFamily="Arial"FontSize="14"><Paragraph><Run Text="WPF打印机测试文档"/><LineBreak/><Bold>当前时间:</Bold><TextBlock Text="{Binding Source={x:Static sys:DateTime.Now}, StringFormat='yyyy-MM-dd HH:mm:ss'}"/></Paragraph></FlowDocument></ScrollViewer><!-- 控制按钮 --><StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Center" Orientation="Horizontal" Margin="10"><Button Content="打印预览" Width="120" Margin="5" Click="PreviewPrint"/><Button Content="直接打印" Width="120" Margin="5" Click="DirectPrint"/><Button Content="选择打印机" Width="120" Margin="5" Click="SelectPrinter"/></StackPanel></Grid>
</Window>
三、核心代码实现 (MainWindow.xaml.cs)
using System;
using System.Printing;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;namespace WpfPrinterDemo
{public partial class MainWindow : Window{private PrintDialog _printDialog;private PrintQueue _selectedPrinter;public MainWindow(){InitializeComponent();InitializePrinter();}// 初始化打印机连接private void InitializePrinter(){_printDialog = new PrintDialog();_printDialog.PrintTicket.PageOrientation = PageOrientation.Portrait;_printDialog.PrintTicket.PageMediaSize = PageMediaSize.A4;}// 打印预览private void PreviewPrint(object sender, RoutedEventArgs e){if (_printDialog.ShowDialog() == true){_printDialog.PrintDocument(PrintDocument.DocumentPaginator, "WPF打印预览");}}// 直接打印private void DirectPrint(object sender, RoutedEventArgs e){try{if (_selectedPrinter == null)throw new Exception("请先选择打印机");var writer = PrintQueue.CreateXpsDocumentWriter(_selectedPrinter);writer.Write(PrintDocument);MessageBox.Show("打印任务已发送");}catch (Exception ex){MessageBox.Show($"打印失败: {ex.Message}");}}// 选择打印机private void SelectPrinter(object sender, RoutedEventArgs e){var printServer = new PrintServer();var printers = printServer.GetPrintQueues();var dialog = new PrintDialog();dialog.PrintQueue = printers.FirstOrDefault(p => p.Name.Contains("HP LaserJet")); // 示例选择HP打印机_selectedPrinter = dialog.PrintQueue;}}
}
四、关键功能说明
1. 打印设置配置
// 设置打印参数
_printDialog.PrintTicket.PageOrientation = PageOrientation.Landscape; // 横向打印
_printDialog.PrintTicket.PageMediaSize = PageMediaSize.A5; // 纸张尺寸
_printDialog.PrintTicket.CopyCount = 2; // 打印份数
2. 打印内容生成
// 动态添加内容
var paragraph = new Paragraph();
paragraph.Inlines.Add(new Run("动态添加的文本内容"));
PrintDocument.Blocks.Add(paragraph);
3. 打印机管理
// 获取所有打印机
var printers = new PrintServer().GetPrintQueues();// 筛选特定打印机
var targetPrinter = printers.FirstOrDefault(p => p.Name.Contains("Zebra"));
参考代码 wpf连接打印机实例demo www.youwenfan.com/contentcsh/59183.html
五、高级功能扩展
1. 打印预览增强
// 添加页眉页脚
PrintDocument.Header = new HeaderFooter {HeaderTemplate = (DataTemplate)XamlReader.Load(@"<DataTemplate><TextBlock Text='机密文档' FontSize='16' HorizontalAlignment='Center'/></DataTemplate>")
};
2. 图像打印支持
// 添加图片到打印内容
var image = new Image {Source = new BitmapImage(new Uri("logo.png", UriKind.Relative)),Width = 200,Height = 100
};
PrintDocument.Blocks.Add(new Paragraph(image));
3. 打印队列监控
// 监听打印状态
var printJob = _selectedPrinter.AddJob("TestJob");
printJob.Start();
printJob.End();
六、部署注意事项
-
权限配置
-
需要
System.Printing
程序集引用 -
在
App.manifest
中添加:<requestedExecutionLevel level="asInvoker" uiAccess="false" />
-
-
打印机驱动
- 确保目标打印机已安装正确驱动
- 测试环境推荐使用HP LaserJet系列
-
异常处理
try {// 打印操作 } catch (PrintSystemException ex) {Debug.WriteLine($"打印系统错误: {ex.Message}"); } catch (IOException ex) {Debug.WriteLine($"I/O错误: {ex.Message}"); }
七、测试用例
测试场景 | 预期结果 |
---|---|
点击"打印预览" | 弹出预览窗口显示正确内容 |
选择不存在打印机 | 弹出错误提示 |
连续打印10份 | 生成10个独立打印任务 |
打印特殊字符 | 正确显示Unicode字符 |
八、扩展应用场景
-
标签打印系统
// Zebra打印机ZPL指令 string zplCode = "^XA^FO50,50^A0N,25,25^FDHello World^FS^XZ"; using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(zplCode))) {_selectedPrinter.AddJob("LabelJob", stream, true); }
-
多联单据打印
// 设置多份副本 _printDialog.PrintTicket.CopyCount = 3; _printDialog.PrintTicket.Duplexing = Duplexing.OneSided;