最简单windows纯文本打印方案是用writeprinter直发原始数据:先openprinter获取句柄,再startdocprinter声明docinfoa.lpszdatatype="raw",接着writeprinter发送ansi编码字符串(中文需widechartomultibyte转acp),结尾加\r\n,最后enddocprinter。

用 WritePrinter 直接发文本到打印机最简单
Windows 打印纯文本,绕开 GDI 和文档流是最轻量的做法——直接打开打印机句柄,把字符串当原始数据写进去。前提是目标打印机支持文本模式(绝大多数本地 USB/网络打印机都支持,但某些 PCL/PostScript 驱动在“仅限图形模式”下会静默丢弃纯文本)。
关键步骤:调用 OpenPrinter 获取句柄 → StartDocPrinter 声明一个“原始”类型文档 → WritePrinter 发送 UTF-8 或 ANSI 字符串 → EndDocPrinter 结束。不用创建 DC,不依赖字体或设备上下文。
常见错误:WritePrinter 返回成功但没出纸——大概率是没调 StartDocPrinter 或传了错误的 DOCINFOA;或者字符串末尾缺 \r\n 导致换行不生效;再或者打印机驱动被设为“后台打印”且缓冲区未刷出(加 ClosePrinter 前调一次 FlushPrinter 可缓解)。
DOCINFOA 的 lpszDatatype 必须设为 "RAW"
这是整个流程能否走通的开关。如果填 "TEXT" 或留空,系统会尝试做 GDI 文本渲染,结果要么失败(StartDocPrinter 返回 0),要么输出乱码或空白页。
正确写法示例:
DOCINFOA di = {};
di.cbSize = sizeof(DOCINFOA);
di.lpszDocName = "MyTextPrint";
di.lpszDatatype = "RAW"; // ← 必须是这个字符串,大小写敏感
di.lpszOutput = nullptr;
注意点:
通过 SSH 隧道从 Android 设备在互联网上对 Windows PC 实现完整远程控制的设置与使用指南,适用于远程桌面访问、安全 RDP 等。
-
lpszDatatype是 ANSI 字符串,不能传宽字符指针 - 值必须是字面量
"RAW",不能是变量或动态拼接(某些旧驱动校验指针内容) - 部分虚拟打印机(如 Microsoft Print to PDF)不支持 RAW 模式,会直接拒绝
StartDocPrinter
中文文本要转成本地 ANSI 编码,别用 UTF-8 直发
Windows 打印子系统对 RAW 数据不做编码转换。如果你用 std::string 存 UTF-8 中文然后直接 WritePrinter,打印机收到的是乱码字节流——除非打印机明确声明支持 UTF-8(极少数新型标签打印机才支持)。
正确做法是调用 WideCharToMultiByte 转成当前系统 ACP(如简体中文 Win10 默认是 GBK):
std::wstring wstr = L"测试打印"; int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr); std::string ansi(len, '\0'); WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, &ansi[0], len, nullptr, nullptr);
容易踩的坑:
- 忘了末尾的 null terminator(
WideCharToMultiByte第二个参数传-1才会包含) - 用
CP_UTF8替代CP_ACP—— 大部分激光/喷墨打印机不认 - 没检查返回值,转码失败时
ansi是空字符串,结果打出来什么都没有
记得加 \r\n 换行,别指望打印机自动 wrap
纯文本打印没有布局引擎,所有换行、缩进、居中都得你自己算好。打印机只认 \r\n(CRLF),单 \n 在某些驱动下会被忽略或变成奇怪符号。
实操建议:
- 每行结尾手动拼
"\r\n",不要依赖std::endl(它只写\n) - 行宽按打印机实际宽度控制(比如标准 A4 纸用等宽字体约 80 字符/行,超长会截断或换页)
- 需要空行?写两个
\r\n;需要顶部留空?开头加若干\r\n - 避免使用制表符
\t—— 不同打印机 tab stop 位置不同,极易错位
驱动兼容性比想象中脆弱:同一段代码,在 HP LaserJet 上正常,在兄弟 MFC-J690DW 上可能首行偏移 2cm,原因往往是默认页边距或“模拟 DOS 打印”开关状态不同。真要稳定,得在打印机属性里关掉“高级打印功能”和“后台处理”,并确认端口设为“LPT1:”或“USB001”这类直连端口而非“Microsoft XPS Document Writer”。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










