ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ToolJet 多标签页批量打印:用 Tabs 组件与 JavaScript 查询实现一键导出 PDF 报告

ToolJet 多标签页批量打印:用 Tabs 组件与 JavaScript 查询实现一键导出 PDF 报告 ToolJet 多标签页批量打印用 Tabs 组件与 JavaScript 查询实现一键导出 PDF 报告【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet本指南以 ToolJet 2.50.0-LTS 版本文档为基础完整讲解如何在 ToolJet 应用中实现「一次点击打印/导出所有标签页数据」的能力典型场景是发票批量打印、多记录报告导出。读完本文你将掌握 Tabs 组件与currentTab暴露变量的联动方式、actions.setVariable/unsetVariable变量操作的用法以及利用事件处理器串联多条 JavaScript 查询、实现循环遍历标签页并最终生成 PDF 的完整方案。应用界面设计UI of the App在 ToolJet 首页点击Create new app按钮上的省略号从模板中选择一个「每个记录对应一组标签页」的应用。本指南以Lead Management System线索管理系统应用为例进行讲解。示例应用包含以下关键组件Tabs 组件tabs1每个标签页代表一类线索记录。示例应用共有 4 个标签页id 依次为 0 到 40、1、2、3。按钮组件默认的Create Lead按钮之外再添加一个Download PDF按钮用于一次性打印所有标签页的数据。该按钮需要配置两个事件具体细节见下文。从 Tabs 组件的源码可以看到ToolJet 的 Tabs 组件frontend/src/AppBuilder/WidgetManager/widgets/tabs.js对外暴露了currentTab、currentTabTitle、isVisible、isDisabled、isLoading等变量其中currentTab当前激活标签页的 id数字currentTabTitle当前激活标签页的标题。后续脚本中使用的{{components.tabs1.currentTab}}、{{variables.tabIndex}}正是读取了这些暴露变量与自定义变量。Tabs 组件还注册了setTab显示名Set current tab等可被事件系统调用的动作这是实现「程序化切换标签页」的基础。从数据库加载数据Load Data from Database数据来源使用lead_management_system表在fetchLeads查询中Table name参数选择lead_management_systemOperations参数选择List rows点击查询面板中的Run按钮加载数据。数据成功加载到各标签页、应用运行符合预期后即可进入下一步。打印多个标签页的数据Printing Data from Multiple Tabs实现思路是创建若干条JavaScript 查询通过**事件处理器Event Handler**将这些查询按顺序串联执行循环遍历所有标签页、逐个收集 HTML最后统一输出到打印窗口生成 PDF。在创建查询之前先给Download PDF按钮添加两个事件事件动作说明On clickSet variable设置一个键为lastSelectedTab的变量值为{{components.tabs1.currentTab}}用于保存点击按钮前当前选中的标签页 idOn clickRun query选择名为viewTabs的查询在按钮被点击时运行注意viewTabs查询将在下文创建因此需要先完成查询创建再回到按钮上补充该事件。创建查询Creating Queries整个方案由三条 JavaScript 查询协作完成viewTabs循环控制、getTabsHTML收集当前标签页 HTML、printPDF输出打印窗口。下面逐条讲解。viewTabs 查询循环控制viewTabs是一条 JavaScript 查询负责循环遍历所有标签页。它通过setVariable动作维护一个tabIndex变量记录「当前要打印哪个标签页」。示例应用中循环条件为tabIndex 4即 id 0 到 3 共 4 个标签页。if ((variables?.tabIndex ?? undefined) undefined) { await actions.setVariable(tabIndex, 0); // 若 tabIndex 未设置则初始化为 0 } else if (parseInt(variables.tabIndex) 4){ await actions.setVariable(tabIndex, (parseInt(variables.tabIndex) 1).toString()); // 否则将 tabIndex 加 1 }这段代码的逻辑首次执行时tabIndex未定义将其置为0后续执行时只要当前值小于 4 就自增 1从而驱动循环推进。需要注意的是变量值以字符串形式存储比较与自增时都需要parseInt转换。该查询需要配置 3 个事件事件 1切换标签页在viewTabs查询中点击New event handler事件类型选择Query SuccessAction选择Control component在事件的Run only if参数中填写{{parseInt(variables.tabIndex) 4}}——仅当条件为真tabIndex 小于 4时才执行该事件在ACTION OPTIONS中Action选择Set current tabId参数填写{{variables.tabIndex}}——把当前标签页切换到tabIndex变量中存储的 id 对应的标签页。事件系统在真正执行动作前会先解析Run only if条件只有条件成立才继续分发动作见 frontend/src/AppBuilder/_stores/slices/eventsSlice.js 中executeAction对runOnlyIf的判断逻辑。Set current tab对应 Tabs 组件注册的setTab动作其参数id就是要切换到的标签页 id见 frontend/src/AppBuilder/WidgetManager/widgets/tabs.js。事件 2收集当前标签页 HTML第二个事件同样是Query Success事件Action选择Run QueryRun Only If参数填写{{parseInt(variables.tabIndex) 4}}——仅在循环未结束时执行Query选择getTabsHTML为该事件处理添加100 毫秒的Debounce防抖。注意getTabsHTML查询将在下文创建需先创建查询再回填此事件。防抖参数由事件执行器统一支持——executeAction本身就被debounce包裹见 frontend/src/AppBuilder/_stores/slices/eventsSlice.js此处为事件级叠加的 100ms 防抖用于等待标签页切换后的渲染完成避免取到未更新的 DOM。事件 3触发最终打印第三个事件同样为Query Success事件Action选择Run QueryRun Only If参数填写{{parseInt(variables.tabIndex) 4}}——仅当tabIndex等于 4循环的最后一次迭代时执行此时所有标签页的 HTML 都已收集完毕Query选择printPDF。注意printPDF查询将在下文创建需先创建查询再回填此事件。三条事件共同构成完整的循环链条事件 1 切页 → 事件 2 收集 HTML → getTabsHTML 成功后又回跑 viewTabs如此往复直到tabIndex达到 4 时由事件 3 触发打印。getTabsHTML 查询收集当前标签页 HTMLgetTabsHTML是一条 JavaScript 查询负责读取当前标签页的 HTML 内容并追加保存到tabsHtml数组变量中最终累积全部标签页的 HTML。actions.setVariable( // 设置 tabsHtml 变量 tabsHtml, [...(variables?.tabsHtml ?? [])].concat([ // 将当前标签页的 html 追加到 tabsHtml 变量中 ((variables?.tabIndex ?? -1) 0 ? div styletop: ${ // 为当前标签页的 html 添加高度为 100vh 的 div variables?.tabIndex ?? -1 }00vh; position: absolute; // 便于将所有标签页的数据一次性打印出来 : ) document.getElementsByClassName(widget- components.tabs1.id)[0] // 获取当前标签页的 html .innerHTML /div, // 将当前标签页的 html 追加到 tabsHtml 变量 ]) );代码要点tabsHtml以数组形式累积各标签页的 HTML[...(variables?.tabsHtml ?? [])]保证在变量未初始化时也能正常工作通过 DOM APIdocument.getElementsByClassName(widget- components.tabs1.id)[0].innerHTML抓取 Tabs 组件tabs1当前激活标签页的实际渲染内容当tabIndex 0时会在 HTML 前包裹一个position: absolute的div其top为${tabIndex}00vh——利用每个标签页高度约 100vh 的错位排版把多个标签页的内容纵向堆叠到同一张纸上从而实现「多页内容一次打印」。该查询需要配置 1 个事件事件 1回跑循环事件类型为Query SuccessAction选择Run QueryQuery参数选择viewTabs——即getTabsHTML成功执行后立即再次运行viewTabs驱动循环进入下一轮。注意创建完getTabsHTML后需回到viewTabs查询的事件 2把getTabsHTML填入事件处理器的 Query 参数中。printPDF 查询生成可打印文档printPDF是一条 JavaScript 查询它把tabsHtml变量中累积的全部 HTML 写入一个新建的浏览器窗口从而允许用户将该窗口打印/另存为包含所有标签页内容的 PDF 文档。var printContents variables.tabsHtml; // 获取所有标签页的 html来自 tabsHtml 变量 var winPrint window.open(, , width900,height650); // 打开一个新的打印窗口 var styles document.querySelectorAll(link, style); var stylesHtml ; for (var i 0; i styles.length; i) { stylesHtml styles[i].outerHTML; } // 收集当前页面的样式 stylesHtml stylepage { size: landscape; }/style; // 为打印页面添加横向landscape方向 winPrint.document.write( htmlhead stylesHtml /headbody ); // 将样式写入打印页面 for (var j 0; j printContents.length; j) { winPrint.document.write(printContents[j]); } // 将所有标签页的 html 写入打印页面 winPrint.document.write(/body/html); // 完成文档并打印 winPrint.document.close(); winPrint.focus(); winPrint.print(); winPrint.close();代码要点遍历当前页面的link与style标签document.querySelectorAll(link, style)将其outerHTML拼接进打印窗口确保打印出的内容保留应用的主题样式额外注入page { size: landscape; }将打印页面方向设置为横向更适合多列表格类报告使用window.open(, , width900,height650)打开新窗口依次write全部标签页 HTML最后依次调用close()、focus()、print()、close()触发浏览器原生打印对话框。该查询需要配置 3 个事件均为Query Success事件 1清理 tabIndex事件类型选择Query SuccessAction选择Unset variable在ACTION OPTIONS中将Key设置为tabIndex——打印成功后清除循环变量避免下次点击时状态残留。事件 2清理 tabsHtml事件类型选择Query SuccessAction选择Unset variable在ACTION OPTIONS中将Key设置为tabsHtml——打印成功后清除累积的 HTML 数据确保下一次点击重新收集。事件 3恢复原标签页事件类型选择Query SuccessAction选择Control componentComponent参数选择tabs1Action选择Set current tabId参数填写{{variables.lastSelectedTab}}——把当前标签页恢复为点击Download PDF之前用户所在的那个标签页。这组「清理 恢复」动作保证了打印流程结束后应用状态回到初始状态用户可以重复点击按钮而不会出现变量残留或标签页错位。Unset variable动作对应事件系统里的unset-custom-variable分支底层调用unsetVariable(key, moduleId)从应用变量中移除指定键见 frontend/src/AppBuilder/_stores/slices/eventsSlice.js而Set variable动作对应set-custom-variable分支调用setVariable(key, value, moduleId)写入变量见 frontend/src/AppBuilder/_stores/slices/eventsSlice.js。注意创建完printPDF后需回到viewTabs查询的事件 3把printPDF填入Query Success事件处理器的 Query 参数中。运行与验证所有查询创建并回填事件后点击Download PDF按钮即可测试浏览器会打开一个新标签页/窗口其中包含按顺序纵向排布的所有标签页内容每个标签页约占 100vh 高度触发浏览器打印对话框选择「另存为 PDF」即可下载包含全部标签页数据的 PDF 文档打印窗口关闭后应用内的标签页会自动恢复到点击按钮前用户所在的标签页lastSelectedTab。小结本方案的核心设计可以归纳为三点循环控制viewTabs用tabIndex变量 Run only if条件实现循环配合 Tabs 组件的Set current tab动作驱动逐页切换内容收集getTabsHTML通过 DOM 读取当前激活标签页的innerHTML并以 100vh 错位 div 实现多页纵向堆叠输出打印printPDF将收集到的样式与 HTML 写入新窗口以横向页面输出并在完成后清理tabIndex、tabsHtml变量、恢复原标签页。你可以据此模式扩展把循环上限从4改为任意标签页数量、为每个标签页定制打印样式或将window.print()替换为其他导出逻辑从而将「多标签页一键打印」复用到发票、报表、工单等多种业务场景。【免费下载链接】ToolJetOpen-source foundation of ToolJet AI - the enterprise app generation platform for internal tools, dashboards, business applications, workflows and AI agents. Build visually, from a prompt, or from Claude Code, Codex and Cursor over MCP 项目地址: https://gitcode.com/GitHub_Trending/to/ToolJet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表