通过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);
}
}
}
}
七、最佳实践建议
- 异常处理:
try
{
printDoc.Print();
}
catch (InvalidPrinterException ex)
{
MessageBox.Show($"打印机错误: {ex.Message}");
}
catch (Exception ex)
{
MessageBox.Show($"打印错误: {ex.Message}");
}
- 异步打印:
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();
});
}
- 打印设置保存:
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;
}
}
总结
选择打印方法:
- 简单需求:使用
PrintDocument类 - WPF应用:使用
PrintDialog.PrintVisual()或PrintDialog.PrintDocument() - 复杂报表:使用RDLC或第三方库(如iTextSharp)
- 批量打印:使用扩展方法和队列
注意事项:
- 始终处理打印异常
- 大型图片先调整大小再打印
- 考虑使用异步打印避免UI阻塞
- 提供打印预览功能改善用户体验
以上就是通过C#调取打印机打印文本和图片的多种方法的详细内容,更多关于C#打印机打印文本和图片的资料请关注脚本之家其它相关文章!
