如何通过Puppeteer动态调整Grafana固定高度表格实现完整导出?
解决Grafana 7.5.8表格面板固定高度导致导出内容不全的问题
核心思路
通过Puppeteer在页面加载完成后,修改表格滚动容器的高度为内容实际高度,让所有行无需滚动即可显示,再执行导出操作。
具体实现步骤及代码
启动Puppeteer并加载仪表盘页面
确保页面完全加载(包括表格数据渲染),若需登录需先模拟登录流程。定位表格滚动容器并调整高度
针对Grafana 7.5.8的DOM结构,找到表格的滚动容器,计算内容实际高度后覆盖固定高度样式。执行导出操作
等待样式生效后,导出为PDF或截图。
完整代码示例
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: 'new' }); // 使用新版无头模式 const page = await browser.newPage(); // 1. 访问仪表盘(替换为你的实际URL) await page.goto('http://your-grafana-instance/d/your-dashboard-uuid/your-dashboard-name', { waitUntil: 'networkidle2', // 等待网络请求完成 timeout: 60000 // 延长超时时间避免加载缓慢导致失败 }); // 2. 等待表格面板渲染完成(选择器根据实际DOM结构调整) await page.waitForSelector('.table-panel .scrollbar-container', { timeout: 30000 }); // 3. 动态调整表格高度以显示所有行 await page.evaluate(() => { // 处理所有表格面板 const tableScrollContainers = document.querySelectorAll('.table-panel .scrollbar-container'); tableScrollContainers.forEach(container => { // 获取内容实际高度 const contentHeight = container.scrollHeight; // 覆盖固定高度样式 container.style.height = `${contentHeight}px`; container.style.maxHeight = `${contentHeight}px`; container.style.overflow = 'visible'; // 确保滚动条隐藏,内容完全显示 // 调整外层面板容器高度(避免面板本身被裁剪) const panelContainer = container.closest('.panel-container'); if (panelContainer) { // 额外增加40px避免标题、边框等元素挤压内容 panelContainer.style.height = `${contentHeight + 40}px`; panelContainer.style.maxHeight = `${contentHeight + 40}px`; } }); }); // 等待样式生效(可根据实际情况调整等待时间) await page.waitForTimeout(1500); // 4. 导出为PDF(或替换为截图) await page.pdf({ path: 'grafana-dashboard-export.pdf', format: 'A4', printBackground: true, // 保留背景样式 margin: { top: '20px', right: '20px', bottom: '20px', left: '20px' } // 设置边距避免内容被裁剪 }); // 若需截图: // await page.screenshot({ path: 'dashboard-screenshot.png', fullPage: true }); await browser.close(); })();
关键注意事项
- 选择器适配:使用浏览器开发者工具查看Grafana页面的DOM结构,确认表格滚动容器的准确选择器(若
.table-panel .scrollbar-container不生效,可替换为div[style*="height: 197px"]定位固定高度元素)。 - 登录处理:若仪表盘需要认证,需在
page.goto前模拟登录,例如:await page.goto('http://your-grafana-instance/login'); await page.type('input[name="user"]', 'your-username'); await page.type('input[name="password"]', 'your-password'); await page.click('button[type="submit"]'); await page.waitForNavigation({ waitUntil: 'networkidle2' }); - 异步数据加载:若表格数据是异步加载的,需等待数据渲染完成,可通过
page.waitForFunction判断行数稳定:await page.waitForFunction(() => { const rowCount = document.querySelectorAll('.table-panel table tbody tr').length; // 根据业务场景设置合理的最小行数 return rowCount >= 1; }, { timeout: 30000 }); - 多表格处理:代码中使用
querySelectorAll遍历所有表格面板,确保所有表格都被调整高度。
内容的提问来源于stack exchange,提问作者Some Guy
相关产品推荐
相关产品推荐

