前言 在近期开发的收银台项目中,需要使用打印机进行小票打印,打印流程的时序图如下所示: 在客户的使用过程中,遇到一个问题,如果机器安装了打印机驱动,那么调用厂商提供的 sdk 进行打印的话,会导致出现小票只打印一半的情况,对此,需要绕过厂商 sdk 使用系统的打印才能够解决这一问题。 在 web 端打印中,需要调用浏览器打印 api 进行网页打印。这意味着,之前后端编写的esc/pos无法复用到,同时,前端还得花费精力来编写 html 以及css 来完成打印内容的排版,这无疑增加了复杂度以及工作量。正打算开始时,得到高人指点。 可以使用 windows api 进行打印 具体参见这篇 在Windows操作系统中,当面临需要直接控制打印机进行打印任务,例如在收银台项目中打印小票时,可能需要绕过特定厂商的SDK,而直接使用操作系统提供的API接口。本篇将详细介绍如何使用C++调用Windows打印API来实现这个功能。 我们需要了解Windows打印API的基本流程。在Windows中,打印过程通常包括以下步骤: 1. 打开打印机(OpenPrinter):通过指定打印机名称获取打印机句柄。如果不确定打印机名称,可以传入NULL以使用默认的本地打印机。 2. 准备文档信息(DOC_INFO_1结构体):定义文档的名称、输出文件(一般为NULL,表示直接发送到打印机)和数据类型(如"RAW",表示不进行格式转换直接打印)。 3. 开始文档打印(StartDocPrinter):通知打印队列一个新文档即将开始。 4. 开始页面打印(StartPagePrinter):标记一个新页面的开始。 5. 写入数据到打印机(WritePrinter):将待打印的数据送入打印机。 6. 结束页面打印(EndPagePrinter):标记页面结束。 7. 结束文档打印(EndDocPrinter):告知打印队列文档打印完成。 8. 关闭打印机(ClosePrinter):释放打印机句柄。 以下是一个使用C++实现的示例代码片段,展示了如何使用上述步骤进行打印: ```cpp #include BOOL RawDataToPrinter(LPSTR szPrinterName, LPBYTE lpData, DWORD dwCount) { HANDLE hPrinter; DOC_INFO_1 DocInfo; DWORD dwJob; DWORD dwBytesWritten; // 打开打印机 if (!OpenPrinter(szPrinterName, &hPrinter, NULL)) { int y = GetLastError(); cout << "openFail" << y << endl; return FALSE; } // 填充文档信息 DocInfo.pDocName = LPSTR("My Document\0"); DocInfo.pOutputFile = NULL; DocInfo.pDatatype = NULL; // 或者 LPWSTR("RAW\0"); // 开始文档打印 if ((dwJob = StartDocPrinter(hPrinter, 1, (LPBYTE)&DocInfo)) == 0) { int x = GetLastError(); cout << "StartDocPrinter Fail" << x << endl; ClosePrinter(hPrinter); return FALSE; } // 开始页面 if (!StartPagePrinter(hPrinter)) { EndDocPrinter(hPrinter); ClosePrinter(hPrinter); return FALSE; } // 写入数据 if (!WritePrinter(hPrinter, lpData, dwCount, &dwBytesWritten)) { EndPagePrinter(hPrinter); EndDocPrinter(hPrinter); ClosePrinter(hPrinter); return FALSE; } // 结束页面 if (!EndPagePrinter(hPrinter)) { EndDocPrinter(hPrinter); ClosePrinter(hPrinter); return FALSE; } // 结束文档 if (!EndDocPrinter(hPrinter)) { ClosePrinter(hPrinter); return FALSE; } // 关闭打印机句柄 ClosePrinter(hPrinter); // 检查写入的数据量是否正确 if (dwBytesWritten != dwCount) return FALSE; return TRUE; } ``` 在这个例子中,`RawDataToPrinter`函数接收打印机名称、打印数据和数据长度作为参数。在实际应用中,你需要确保`szPrinterName`是有效的打印机名称,`lpData`指向要打印的数据,`dwCount`是数据的字节数。 值得注意的是,在遇到问题时,如`StartDocPrinter`失败,可以使用`GetLastError`函数获取错误代码,帮助诊断问题。例如,如果`OpenPrinter`返回的句柄无效,可能是因为打印机名称不正确,这时可以尝试使用系统默认的打印机或手动指定正确的打印机名称。 通过这种方式,可以避免对前端和后端造成额外负担,尤其是当需要复用ESC/POS命令时,直接使用Windows API打印可以更好地控制打印过程,并且减少了前后端的耦合度。然而,这种方法需要对Windows打印机制有深入的理解,以便正确地构造和传递打印数据。
2025-11-25 09:54:24 143KB
1
fix print spooler v2.60 Windows打印修复工具v2.6.0
2023-11-24 10:32:04 289KB Windows打印修复工具v2.
1
平时我们工作与生活中用扫描仪或手机相机拍摄的文件、孩子的作业等图片往往有一些阴影、底灰及各类混淆图片的杂质,看不清楚,而且打印的时候特别浪费墨粉。 如果懂PS的话当然不难处理,但是PS对普通人来说比较复杂,今天这款叫做原本的工具大小还不到1M,可是的功能却非常大,可一键智能去灰底,增强效果,效果超赞! 使用起来也很简单啊,只要点击「打开」,然后导入你需要搞定的文档即可去除黑底,赶紧下载试试吧。
2022-11-20 20:04:01 259KB windows 打印机 文档处理 图片文字处理
1
winform自定义打印设计工具实现,windows打印组件,可自定义设计,静态文本,动态文本,图片,二维码等,代码动态调用进行打印操作,提供入门思路,有兴趣的朋友可以自行修改拓展。
2022-09-23 00:18:40 56.26MB windows c# .net 开发语言
原始打印 .Net库,可绕过打印机驱动程序直接将文件直接发送到Windows打印机。 将PostScript,PCL或其他打印文件类型直接发送到打印机。 在Windows XP到10和Server 2003到2012上需要.Net 4运行时。 用法: using RawPrint; // Create an instance of the Printer IPrinter printer = new Printer(); // Print the file printer.PrintRawFile(PrinterName, Filepath, Filename); 安装: 要安装原始打印,请在运行以下命令 PM> Install-Package RawPrint 2019-09-12版本0.5.0 作业参数现在包括打印机名称。 许可证已移交
2021-12-31 13:08:35 12KB C#
1
当打印客户端系统为Windows7或以下版本,提示windows无法连接到打印机出现错误0x00004005,可下载修复工具安装补丁进行修复。
2021-12-16 22:01:23 1.38MB windows 打印机 win7
通过C++在WINDOWS下封装调用API驱动打印机分页设置打印,工具VS2010
2021-09-10 11:37:54 1.56MB C++打印机
1
监控windows打印机打印文件的事件通知,列举系统打印机详细列表,VS2010项目工程详细源码 。
2021-08-18 23:17:29 136KB Windows 打印机 监控
1
C#中Windows打印组件的使用 PageSetupDialog 页面设置 PrintDialog 打印对话框(选择打印机) printDocument 打印的文档 printPreviewControl 打印预览文档 PrintPreviewDialog 显示打印预览
2021-07-05 12:03:05 53KB C# PageSetupDia PrintDialog 打印控件
1
CaysnPrinter打印示例 - Sample1 For Windows 支持通过网口、串口、USB、并口等接口发送数据到打印机进行打印 支持页模式打印 接口清晰,性能稳定
1