C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C#打印机打印文本和图片

通过C#调取打印机打印文本和图片的多种方法

作者:齐鲁大虾

本文介绍了C#中五种常用的打印方法:使用.NET内置类、WPF打印功能、RDLC报表、第三方库iTextSharp和PDFsharp,以及如何处理异常和异步打印,需要的朋友可以参考下

在C#中调用打印机打印文本和图片有多种方法,以下是最常用的几种方式:

一、使用.NET内置的打印类(最常用)

1.基本打印流程

using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;

public class PrinterHelper
{
    private PrintDocument printDoc = new PrintDocument();
    private string textToPrint;
    private Image imageToPrint;
    
    public PrinterHelper()
    {
        // 订阅打印事件
        printDoc.PrintPage += new PrintPageEventHandler(PrintPageHandler);
    }
    
    // 打印文本
    public void PrintText(string text)
    {
        textToPrint = text;
        imageToPrint = null;
        
        // 显示打印对话框
        PrintDialog printDialog = new PrintDialog();
        printDialog.Document = printDoc;
        
        if (printDialog.ShowDialog() == DialogResult.OK)
        {
            printDoc.Print();
        }
    }
    
    // 打印图片
    public void PrintImage(Image image)
    {
        imageToPrint = image;
        textToPrint = null;
        
        PrintDocument pd = new PrintDocument();
        pd.PrintPage += (sender, e) =>
        {
            // 居中打印图片
            Rectangle rect = e.MarginBounds;
            e.Graphics.DrawImage(imageToPrint, rect);
        };
        
        pd.Print();
    }
    
    // 同时打印文本和图片
    private void PrintPageHandler(object sender, PrintPageEventArgs e)
    {
        // 获取打印图形对象
        Graphics g = e.Graphics;
        
        // 设置字体
        Font font = new Font("宋体", 12);
        Brush brush = Brushes.Black;
        
        // 如果有文本,打印文本
        if (!string.IsNullOrEmpty(textToPrint))
        {
            // 计算文本区域
            RectangleF textRect = new RectangleF(
                e.MarginBounds.Left,
                e.MarginBounds.Top,
                e.MarginBounds.Width,
                e.MarginBounds.Height / 2);
                
            // 打印文本(支持换行)
            g.DrawString(textToPrint, font, brush, textRect);
        }
        
        // 如果有图片,打印图片
        if (imageToPrint != null)
        {
            // 计算图片区域(文本下方)
            RectangleF imageRect = new RectangleF(
                e.MarginBounds.Left,
                e.MarginBounds.Top + e.MarginBounds.Height / 2 + 20,
                e.MarginBounds.Width,
                e.MarginBounds.Height / 2 - 20);
                
            // 保持图片纵横比
            float ratio = Math.Min(
                imageRect.Width / imageToPrint.Width,
                imageRect.Height / imageToPrint.Height);
                
            float width = imageToPrint.Width * ratio;
            float height = imageToPrint.Height * ratio;
            
            // 居中显示
            float x = imageRect.Left + (imageRect.Width - width) / 2;
            float y = imageRect.Top + (imageRect.Height - height) / 2;
            
            g.DrawImage(imageToPrint, x, y, width, height);
        }
    }
}

2.打印预览功能

using System.Drawing.Printing;
using System.Windows.Forms;

public class PrintPreviewHelper
{
    public void ShowPrintPreview(string text, Image image = null)
    {
        PrintDocument printDoc = new PrintDocument();
        printDoc.PrintPage += (sender, e) =>
        {
            // 打印内容
            PrintContent(e.Graphics, e.MarginBounds, text, image);
        };
        
        // 显示打印预览对话框
        PrintPreviewDialog previewDlg = new PrintPreviewDialog();
        previewDlg.Document = printDoc;
        previewDlg.ShowDialog();
    }
    
    private void PrintContent(Graphics g, Rectangle marginBounds, string text, Image image)
    {
        // 打印文本
        if (!string.IsNullOrEmpty(text))
        {
            Font font = new Font("宋体", 11);
            RectangleF textArea = new RectangleF(
                marginBounds.Left,
                marginBounds.Top,
                marginBounds.Width,
                marginBounds.Height * 0.6f);
                
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Near;
            format.LineAlignment = StringAlignment.Near;
            
            g.DrawString(text, font, Brushes.Black, textArea, format);
        }
        
        // 打印图片
        if (image != null)
        {
            RectangleF imageArea = new RectangleF(
                marginBounds.Left,
                marginBounds.Top + marginBounds.Height * 0.6f + 10,
                marginBounds.Width,
                marginBounds.Height * 0.4f - 10);
                
            // 保持纵横比
            DrawImageCentered(g, image, imageArea);
        }
    }
    
    private void DrawImageCentered(Graphics g, Image image, RectangleF area)
    {
        float ratio = Math.Min(area.Width / image.Width, area.Height / image.Height);
        float width = image.Width * ratio;
        float height = image.Height * ratio;
        float x = area.Left + (area.Width - width) / 2;
        float y = area.Top + (area.Height - height) / 2;
        
        g.DrawImage(image, x, y, width, height);
    }
}

3.高级打印功能

using System.Drawing.Printing;
using System.Collections.Generic;

public class AdvancedPrinter
{
    // 获取所有打印机
    public List<string> GetAvailablePrinters()
    {
        List<string> printers = new List<string>();
        foreach (string printer in PrinterSettings.InstalledPrinters)
        {
            printers.Add(printer);
        }
        return printers;
    }
    
    // 设置默认打印机
    public void SetDefaultPrinter(string printerName)
    {
        PrinterSettings settings = new PrinterSettings();
        settings.PrinterName = printerName;
    }
    
    // 打印多页文档
    public void PrintMultiPageDocument(List<string> pages, string printerName = null)
    {
        PrintDocument printDoc = new PrintDocument();
        
        if (!string.IsNullOrEmpty(printerName))
        {
            printDoc.PrinterSettings.PrinterName = printerName;
        }
        
        int currentPage = 0;
        
        printDoc.PrintPage += (sender, e) =>
        {
            if (currentPage < pages.Count)
            {
                // 打印当前页
                PrintSinglePage(e.Graphics, e.MarginBounds, pages[currentPage]);
                currentPage++;
                
                // 如果还有更多页,继续打印
                e.HasMorePages = currentPage < pages.Count;
            }
        };
        
        printDoc.Print();
    }
    
    private void PrintSinglePage(Graphics g, Rectangle bounds, string content)
    {
        Font font = new Font("Arial", 10);
        g.DrawString(content, font, Brushes.Black, bounds);
    }
}

二、使用WPF的打印功能

1.WPF打印基础

using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;

public class WPFPrinter
{
    // 打印文本
    public void PrintTextWPF(string text)
    {
        FlowDocument doc = new FlowDocument();
        Paragraph paragraph = new Paragraph();
        paragraph.Inlines.Add(text);
        doc.Blocks.Add(paragraph);
        
        PrintDialog printDialog = new PrintDialog();
        if (printDialog.ShowDialog() == true)
        {
            doc.PageHeight = printDialog.PrintableAreaHeight;
            doc.PageWidth = printDialog.PrintableAreaWidth;
            printDialog.PrintDocument(
                ((IDocumentPaginatorSource)doc).DocumentPaginator, 
                "打印文档");
        }
    }
    
    // 打印图片
    public void PrintImageWPF(string imagePath)
    {
        PrintDialog printDialog = new PrintDialog();
        if (printDialog.ShowDialog() == true)
        {
            Image image = new Image();
            BitmapImage bitmap = new BitmapImage(new Uri(imagePath, UriKind.RelativeOrAbsolute));
            image.Source = bitmap;
            image.Stretch = Stretch.Uniform;
            
            // 调整大小以适应页面
            image.Width = printDialog.PrintableAreaWidth - 100;
            image.Height = printDialog.PrintableAreaHeight - 100;
            
            printDialog.PrintVisual(image, "打印图片");
        }
    }
}

2.WPF打印自定义内容

using System.Windows.Media;

public class CustomWPFPrinter
{
    public void PrintCustomContent()
    {
        PrintDialog printDialog = new PrintDialog();
        if (printDialog.ShowDialog() == true)
        {
            // 创建要打印的可视化对象
            DrawingVisual visual = new DrawingVisual();
            
            using (DrawingContext context = visual.RenderOpen())
            {
                // 绘制文本
                FormattedText text = new FormattedText(
                    "打印测试",
                    System.Globalization.CultureInfo.CurrentCulture,
                    FlowDirection.LeftToRight,
                    new Typeface("Arial"),
                    32,
                    Brushes.Black);
                    
                context.DrawText(text, new Point(100, 100));
                
                // 绘制矩形
                context.DrawRectangle(
                    Brushes.LightGray,
                    new Pen(Brushes.Black, 2),
                    new Rect(50, 50, 200, 100));
            }
            
            printDialog.PrintVisual(visual, "自定义打印");
        }
    }
}

三、打印报表(使用RDLC报表)

1.安装必要的NuGet包

<!-- 在.csproj文件中添加 -->
<PackageReference Include="Microsoft.ReportingServices.ReportViewerControl.WinForms" Version="150.1480.0" />

2.创建和打印RDLC报表

using Microsoft.Reporting.WinForms;
using System.Data;

public class ReportPrinter
{
    public void PrintReport(DataTable data, string imagePath = null)
    {
        // 创建报表
        LocalReport report = new LocalReport();
        report.ReportPath = @"Report.rdlc"; // RDLC文件路径
        
        // 添加数据源
        ReportDataSource dataSource = new ReportDataSource("DataSet1", data);
        report.DataSources.Add(dataSource);
        
        // 如果有图片,添加参数
        if (!string.IsNullOrEmpty(imagePath))
        {
            ReportParameter param = new ReportParameter("ImagePath", imagePath);
            report.SetParameters(param);
        }
        
        // 渲染报表
        byte[] pdfBytes = report.Render("PDF");
        
        // 打印PDF(需要PDF打印支持)
        // 或者使用ReportViewer控件预览
        PrintReportDirectly(report);
    }
    
    private void PrintReportDirectly(LocalReport report)
    {
        PrintDialog printDialog = new PrintDialog();
        
        if (printDialog.ShowDialog() == DialogResult.OK)
        {
            // 创建打印文档
            PrintDocument printDoc = new PrintDocument();
            printDoc.PrinterSettings = printDialog.PrinterSettings;
            
            // 打印报表
            report.PrintToPrinter(printDialog.PrinterSettings,
                                 printDialog.PageSettings,
                                 false);
        }
    }
}

四、使用第三方库(推荐用于复杂打印)

1.使用iTextSharp打印PDF

using iTextSharp.text;
using iTextSharp.text.pdf;

public class PdfPrinter
{
    public void CreateAndPrintPdf(string text, string imagePath)
    {
        // 创建PDF文档
        Document document = new Document();
        
        // 保存PDF文件
        PdfWriter.GetInstance(document, new FileStream("output.pdf", FileMode.Create));
        document.Open();
        
        // 添加文本
        Paragraph paragraph = new Paragraph(text);
        document.Add(paragraph);
        
        // 添加图片
        if (!string.IsNullOrEmpty(imagePath))
        {
            Image image = Image.GetInstance(imagePath);
            image.ScaleToFit(400, 400);
            document.Add(image);
        }
        
        document.Close();
        
        // 打印PDF
        PrintPdf("output.pdf");
    }
    
    private void PrintPdf(string pdfPath)
    {
        Process process = new Process();
        process.StartInfo.FileName = pdfPath;
        process.StartInfo.Verb = "print";
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        process.Start();
    }
}

2.使用PDFsharp

using PdfSharp.Drawing;
using PdfSharp.Pdf;
using PdfSharp.Pdf.Printing;

public class PdfSharpPrinter
{
    public void PrintWithPdfSharp(string text, XImage image)
    {
        // 创建PDF文档
        PdfDocument document = new PdfDocument();
        PdfPage page = document.AddPage();
        
        XGraphics gfx = XGraphics.FromPdfPage(page);
        XFont font = new XFont("Arial", 12);
        
        // 绘制文本
        gfx.DrawString(text, font, XBrushes.Black,
                      new XRect(50, 50, page.Width - 100, page.Height - 100),
                      XStringFormats.TopLeft);
        
        // 绘制图片
        if (image != null)
        {
            gfx.DrawImage(image, 50, 150, 200, 200);
        }
        
        // 保存临时文件并打印
        string tempFile = Path.GetTempFileName() + ".pdf";
        document.Save(tempFile);
        
        // 使用PDF查看器打印
        PdfFilePrinter printer = new PdfFilePrinter(tempFile);
        printer.Print();
        
        // 清理临时文件
        File.Delete(tempFile);
    }
}

五、实用扩展方法

using System.Drawing;
using System.Drawing.Printing;

public static class PrintingExtensions
{
    // 扩展方法:直接打印字符串
    public static void Print(this string text, Font font = null)
    {
        font = font ?? new Font("宋体", 12);
        
        PrintDocument pd = new PrintDocument();
        pd.PrintPage += (sender, e) =>
        {
            e.Graphics.DrawString(text, font, Brushes.Black, 
                                 e.MarginBounds.Left, 
                                 e.MarginBounds.Top);
        };
        
        pd.Print();
    }
    
    // 扩展方法:直接打印图片
    public static void Print(this Image image, bool fitToPage = true)
    {
        PrintDocument pd = new PrintDocument();
        pd.PrintPage += (sender, e) =>
        {
            Rectangle rect = fitToPage ? e.MarginBounds : 
                new Rectangle(100, 100, image.Width, image.Height);
            e.Graphics.DrawImage(image, rect);
        };
        
        pd.Print();
    }
    
    // 批量打印
    public static void BatchPrint(this List<PrintJob> jobs, string printerName)
    {
        foreach (var job in jobs)
        {
            PrintDocument pd = new PrintDocument();
            pd.PrinterSettings.PrinterName = printerName;
            
            pd.PrintPage += (sender, e) =>
            {
                if (job.Text != null)
                    e.Graphics.DrawString(job.Text, job.Font, Brushes.Black, 100, 100);
                
                if (job.Image != null)
                    e.Graphics.DrawImage(job.Image, 100, 200);
            };
            
            pd.Print();
        }
    }
}

public class PrintJob
{
    public string Text { get; set; }
    public Image Image { get; set; }
    public Font Font { get; set; } = new Font("Arial", 12);
}

六、完整示例程序

using System;
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;

namespace PrintDemo
{
    public partial class MainForm : Form
    {
        private PrintDocument printDoc;
        private string currentText;
        private Image currentImage;
        
        public MainForm()
        {
            InitializeComponent();
            
            printDoc = new PrintDocument();
            printDoc.PrintPage += PrintDoc_PrintPage;
        }
        
        private void btnPrintText_Click(object sender, EventArgs e)
        {
            currentText = txtContent.Text;
            currentImage = null;
            
            PrintDialog dlg = new PrintDialog();
            dlg.Document = printDoc;
            
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                printDoc.Print();
            }
        }
        
        private void btnPrintImage_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog dlg = new OpenFileDialog())
            {
                dlg.Filter = "图片文件|*.jpg;*.png;*.bmp";
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    currentImage = Image.FromFile(dlg.FileName);
                    currentText = null;
                    printDoc.Print();
                }
            }
        }
        
        private void btnPreview_Click(object sender, EventArgs e)
        {
            PrintPreviewDialog previewDlg = new PrintPreviewDialog();
            previewDlg.Document = printDoc;
            previewDlg.ShowDialog();
        }
        
        private void PrintDoc_PrintPage(object sender, PrintPageEventArgs e)
        {
            Graphics g = e.Graphics;
            Rectangle margins = e.MarginBounds;
            
            // 设置高质量
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            
            float yPos = margins.Top;
            
            // 打印文本
            if (!string.IsNullOrEmpty(currentText))
            {
                Font textFont = new Font("宋体", 11);
                SizeF textSize = g.MeasureString(currentText, textFont, margins.Width);
                
                g.DrawString(currentText, textFont, Brushes.Black, 
                           new RectangleF(margins.Left, yPos, margins.Width, textSize.Height));
                
                yPos += textSize.Height + 20;
            }
            
            // 打印图片
            if (currentImage != null)
            {
                float availableHeight = margins.Bottom - yPos;
                float ratio = Math.Min(
                    (float)margins.Width / currentImage.Width,
                    availableHeight / currentImage.Height);
                    
                float width = currentImage.Width * ratio;
                float height = currentImage.Height * ratio;
                float x = margins.Left + (margins.Width - width) / 2;
                
                g.DrawImage(currentImage, x, yPos, width, height);
            }
        }
    }
}

七、最佳实践建议

  1. 异常处理
try
{
    printDoc.Print();
}
catch (InvalidPrinterException ex)
{
    MessageBox.Show($"打印机错误: {ex.Message}");
}
catch (Exception ex)
{
    MessageBox.Show($"打印错误: {ex.Message}");
}
  1. 异步打印
public async Task PrintAsync(string content)
{
    await Task.Run(() =>
    {
        PrintDocument pd = new PrintDocument();
        pd.PrintPage += (sender, e) =>
        {
            e.Graphics.DrawString(content, new Font("Arial", 12), 
                                 Brushes.Black, 100, 100);
        };
        pd.Print();
    });
}
  1. 打印设置保存
public class PrintSettings
{
    public string PrinterName { get; set; }
    public bool Landscape { get; set; }
    public PaperSize PaperSize { get; set; }
    
    public void ApplyTo(PrintDocument doc)
    {
        doc.PrinterSettings.PrinterName = PrinterName;
        doc.DefaultPageSettings.Landscape = Landscape;
        if (PaperSize != null)
            doc.DefaultPageSettings.PaperSize = PaperSize;
    }
}

总结

选择打印方法:

  1. 简单需求:使用PrintDocument
  2. WPF应用:使用PrintDialog.PrintVisual()PrintDialog.PrintDocument()
  3. 复杂报表:使用RDLC或第三方库(如iTextSharp)
  4. 批量打印:使用扩展方法和队列

注意事项:

以上就是通过C#调取打印机打印文本和图片的多种方法的详细内容,更多关于C#打印机打印文本和图片的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文