miniblink49 网页打印与 PDF 导出实战:从参数配置到故障排查
【免费下载链接】miniblink49a lighter, faster browser kernel of blink to integrate HTML UI in your app. 一个小巧、轻量的浏览器内核,用来取代wke和libcef项目地址: https://gitcode.com/GitHub_Trending/mi/miniblink49
miniblink49 是用于把 HTML 界面嵌进自研应用的轻量 Blink 内核,它内置了完整的打印模块:打印设置(方向、页眉页脚、背景)、静默打印、PDF 导出、位图输出一应俱全,接口集中在 C API 层,接上手就能用。
能力全景速览
先划清边界:打印相关的能力项就下面这几样,全部是mb前缀的 C 函数,声明在 mbvip/core/mb.h。
| 能力项 | 说明 | 典型用法 |
|---|---|---|
| 常规打印 | 走系统打印流程,可弹预览窗口 | mbUtilPrint |
| 静默打印 | 不弹界面直接送打印机 | mbUtilsSilentPrint |
| PDF 导出 | 输出分页 PDF 数据流 | mbUtilPrintToPdf |
| 位图导出 | 整页截图式输出 | mbUtilPrintToBitmap |
| PDF 页面数据 | 逐页读取已渲染 PDF | mbGetPdfPageData |
| 默认设置 | 改边距、背景、页眉页脚默认值 | mbUtilSetDefaultPrinterSettings |
| 流程回调 | 监听开始/预览/打印中三个阶段 | mbOnPrinting |
源码定位速查
想改行为之前,先知道代码在哪。打印逻辑都在 mbvip/printing/ 目录里:
- mbvip/printing/Printing.h:
printing::Printing类,负责预览窗口创建、枚举本地/网络打印机、执行打印、在 Blink 线程取 PDF 数据; - mbvip/printing/PrintingSetting.h:默认边距、纸张等全局默认值,比如
g_edgeDistance[4]对应上下左右四个边距; - mbvip/printing/PdfViewerPlugin.h:PDF 查看插件,PDF 预览和取数都经过它;
mbvip/core/mb.h:mbPrintSettings、mbDefaultPrinterSettings两个结构体和全部打印 API 的声明处。
打印参数逐项配
打印参数只有一个入口结构体mbPrintSettings,配完传给mbUtilPrint即可。三个最常调的开关:
📐方向:isLandscape控制横向/纵向,内部映射到 GDI 的DMORIENT_LANDSCAPE / DMORIENT_PORTRAIT。改错它是最常见的"内容被裁边"原因。
📄页眉页脚:isPrintPageHeadAndFooter,默认关。开启后页脚会占据约 0.5cm 高度,长页面要留意正文实际可用高度变小。
🎨背景:isPrintBackgroud(注意原拼写)。关掉背景后 CSS 背景色、图片背景全部不输出,打印稿变"白底"。
mbPrintSettings s; s.isLandscape = TRUE; s.isPrintPageHeadAndFooter = FALSE; s.isPrintBackgroud = TRUE; mbUtilPrint(webView, frameId, &s);其余字段如isPrintToMultiPage、边距、份数也在同一结构体里,改哪段代码影响哪块输出,对照字段名就能判断。
PDF 导出三步走
PDF 导出独立于普通打印,主线是"预览 → 导出 → 落盘":
- 预览:不需要你搭界面。打印流程内部会创建预览 WebView 并经 PDF 插件取页面图像,
mbOnPrinting的回调里kPrintintStepPreview阶段即可拿到预览 HDC 自己画。 - 导出:调
mbUtilPrintToPdf,它把打印参数送进 Blink 线程,逐页产出 PDF 数据,通过你注册的mbPrintPdfDataCallback回传。 - 落盘:回调里收到的
mbPdfDatas是分页数据(getData取页、getDataSize取长度),写文件、压缩、上传都由你接管。
// 回调里拿到分页 PDF 数据,自行写盘 void onPdfReady(mbWebView view, void* param, const mbPdfDatas* datas) { for (int i = 0; i < datas->pageCount; ++i) writeToFile(pageName(i), datas->pages[i].data, datas->pages[i].size); }注意getData返回的指针只在回调期间有效,别跨线程持有。
纸张 / 打印机 / 质量调优
高级参数不单独开接口,而是收敛在默认值和 DEVMODE 两层:
- 默认值:
mbUtilSetDefaultPrinterSettings改mbDefaultPrinterSettings,覆盖边距(edgeDistanceLeft等四个)、背景开关、页眉页脚开关,适合给报表类页面设一套全局模板。 - 纸张与打印机:
Printing构造后自动枚举本地和网络打印机,并缓存每台机器的DEVMODE。纸张类型由m_userSelectPaperType指定,副本数m_copies、单双面m_duplex同样走 DEVMODE 下发。 - 报表打印场景:源码里留了个针对 HP 打印机的特殊处理——某些机型必须强制指定纸张类型,否则输出不居中。如果你的用户群里有特定品牌打印机,建议按机型维护一张"纸张类型"映射表。
- 文档预览场景:走 PDF 导出而不是直接送打印机,让用户先看到
kPrintintStepPreview的预览结果,确认再执行,避免废纸。
性能与资源三件事
打印流程涉及预览窗口、PDF 生成、DEVMODE 缓存,资源开销不小,三条建议各一句话:
- ⚡延迟初始化:
printing::Printing对象在用户真正点打印时才创建,别随 WebView 常驻。原因是它内部持有预览 WebView 和 PDF 数据访问器,常驻就是白白占内存。 - 异步调用:PDF 数据在 Blink 线程生成、经
onJsQuery异步回传,你的回调里只做接收和写盘。原因是生成耗时与页面规模成正比,阻塞 UI 线程会卡死窗口。 - 及时释放:
PdfDataVisitor和DevnameToDeviceMode都带 RAII 析构,让对象随作用域结束销毁,不要手动裸持有DEVMODE指针。原因是DEVMODE缓冲按dmSize + dmDriverExtra动态分配,泄漏会累积。
故障速查表
| 现象 | 常见原因 | 解法 |
|---|---|---|
| 打印出来是空白/白底 | 背景开关被关,CSS 背景全部不输出 | isPrintBackgroud置TRUE,或改用color: !important类方案 |
| 内容偏移、不居中 | 个别打印机(源码点名 HP)默认纸张类型不对 | 通过默认设置强制指定对应paperType |
| PDF 导出收不到数据 | 没注册回调,或回调里跨线程使用了临时指针 | 检查mbUtilPrintToPdf的callback参数非空,数据在回调内同步落盘 |
| 预览有图、打印缺页眉 | 页眉页脚开关与预览设置不一致 | 确认isPrintPageHeadAndFooter与界面上的选择一致,重新发起打印 |
结语
打印这块的复杂度在于系统打印机差异,而 miniblink49 把枚举、预览、DEVMODE 这些脏活都收进了mbvip/printing/。下一步:打开 mbvip/printing/ 目录读一遍Printing.h,然后在你的工程里跑通第一个mbUtilPrint调用,再换成mbUtilPrintToPdf落一份 PDF 出来。
【免费下载链接】miniblink49a lighter, faster browser kernel of blink to integrate HTML UI in your app. 一个小巧、轻量的浏览器内核,用来取代wke和libcef项目地址: https://gitcode.com/GitHub_Trending/mi/miniblink49
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考