在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#打印机打印文本和图片的资料请关注代码网其它相关文章!
发表评论