ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

从 HTML 报表到 A4 纸:miniblink49 打印与 PDF 导出的三条调用链

从 HTML 报表到 A4 纸:miniblink49 打印与 PDF 导出的三条调用链 从 HTML 报表到 A4 纸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你大概率遇到过这种需求后台管理端里一张 HTML 报表要么打出来盖章要么导出 PDF 存档但不想为了这一页去引一个 PDF 生成库、自己拼坐标。miniblink49 打印与 PDF 导出其实共用同一条渲染链路只是最后一步分别落到 GDI 设备和内存回调。读完这篇你能分清三条调用链各自在哪触发、参数该往哪个结构体里填。它是怎么把网页变成纸面输出的打印这件事在 miniblink49 里不是截图塞给打印机而是 Blink 先按mbPrintSettings描述的画布把文档渲染好再决定往哪送。Printing 这个类构造时只吃一个mbWebView和一个mbWebFrameHandlerun()一调用就开始动先createPreviewWin()建一个你看不到的第二视图成员里那个m_mbPreview文档就绪后走getPreview()出预览真正取 PDF 数据时切到 Blink 线程跑getPdfDataInBlinkThread()。要打纸面就走另一条doPrint()→doPrintImpl()后者拿的是 Windows 的DEVMODE也就是 GDI 那套设备模式。设备从哪来enumPrinters()会同时跑enumLocalPrinters()和enumNetworkPrinters()本地直连、域里共享的网络机、以及装了的虚拟 PDF 打印机都能被列出来每台设备配一份DEVMODE缓存在DevnameToDeviceMode里。PDF 那条线产出的数据装在mbPdfDatas页数 每页指针 每页长度三件套交给PdfDataVisitor逐页getData()/getDataSize()读出最后经mbPrintPdfDataCallback还给你。整条链顺着 Printing.cpp 都能摸到落点。三步跑通第一份打印任务最小路径就三步拿到 view 和 frameId → 填一个mbPrintSettings→ 调mbUtilPrint。别小看那个结构体它是值类型、没有内置默认值{}初始化后边距全 0、开关全关想让背景色出来你得显式置位。mbPrintSettings s {}; s.structSize sizeof(s); s.isPrintBackgroud TRUE; // 报表带底色时必须开 BOOL ok mbUtilPrint(view, frameId, s);参数对照参数作用默认行为dpi渲染/打印分辨率结构体无默认建议按设备填 96 或 300width/height输出画布尺寸px0交给布局自适应marginTopBottomLeftRight页边距px0不加额外边距isPrintPageHeadAndFooter打印页眉页脚false不打印isPrintBackgroud打印背景与图形false需手动置 TRUEisLandscape横向排版false纵向isPrintToMultiPage允许内容跨页falsePDF 导出与纸张、页边距的精细控制PDF 导出不走打印机走mbUtilPrintToPdf签名比mbUtilPrint多两个参数一个回调、一个透传的param。回调里拿到mbPdfDatascount是页数第i页数据在datas[i]、长度sizes[i]拼成一个文件还是逐页存由你定。static void onPdf(mbWebView v, void* p, const mbPdfDatas* d) { for (int i 0; i d-count; i) // 逐页落盘 savePage(i, d-datas[i], d-sizes[i]); } mbUtilPrintToPdf(view, frameId, s, onPdf, nullptr);页面里常用 JS 触发native_printToPDF最终汇到同一份mbPrintSettings。设备来源由 Printing 内部枚举来源对应函数说明本地打印机enumLocalPrinters直连的 GDI 驱动设备网络打印机enumNetworkPrinters域内共享的网络设备虚拟 PDF 打印机同enumPrinters输出.pdf文件而非纸面纸张与边距走mbDefaultPrinterSettings它和上面那个结构体不同——带一个内联构造函数所以有真实默认值控制项字段单位 / 取值默认纸张paperTypeDMPAPER_*A499A4页边距edgeDistanceLeft/Top/Right/Bottom毫米左0 顶10 右0 底10份数copies份1方向isLandscape纵/横纵向画布mbPrintSettings.width/heightpx0mbDefaultPrinterSettings d {}; d.structSize sizeof(d); d.paperType 9; // DMPAPER_A4 d.edgeDistanceTop 10; // 单位 mm mbUtilSetDefaultPrinterSettings(view, d);上线前要做的三件事Printing一实例化就会拉起那个隐藏的第二视图m_mbPreview预览和取 PDF 都靠它。所以别在窗口初始化时就把打印模块准备好等用户真的点了打印或导出 PDF再实例化、再调mbUtilPrintToPdf首次成本才只落在需要的那一刻。PDF 回调交回的mbPdfDatas指向内核管理的内存用PdfDataVisitor逐页读完就好别在 UI 线程把整包数据长期攥在手里更不要跨页面还持有。mbvip/printing/ 里那段针对 HP 打印机的注释值得注意某些机型不强制用它的默认paperType就会打印不居中所以复用一个视图前把上次的设置复位避免上一单的纸张泄漏到下一单。getPdfDataInBlinkThread()顾名思义在 Blink 线程取数回调很可能不落在 UI 线程。把写文件、拼字节这种事丢到工作线程或 PostTask 里去做消息循环就不会被一次大导出的 IO 卡住。出问题时先查这两处现象先查这里依据打印出来是空白页isPrintBackgroud是否置位背景/图片是否加载完才触发mbPrintSettings零初始化后该字段为 falsePDF 导出失败 / 文件为空回调里d-count是否为 0磁盘空间与写文件权限mbPdfDatas.count是页数0 即没产出先按三步那节把mbUtilPrint跑通、打印出第一张带背景的 A4确认链路没断再回头接mbUtilPrintToPdf做存档。想改纸张和边距时记住两个结构体各有各的默认值。链路通了之后剩下的就是把参数表填进你的业务里。【免费下载链接】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),仅供参考
返回列表