简介:这份Smartbi报表设置文档面向使用Smartbi进行报表开发的数据分析与报表人员,聚焦从模板引用到预览发布的完整设置流程,帮助读者解决报表样式设计、参数校验与排版等实际问题。资源包内含1个docx文档,大小约1.05MB,以图文步骤与代码片段结合的方式组织内容。文档覆盖引用模板、页面设置、隔行不同颜色、列宽自适应、参数设置、参数排版与预览发布等环节,其中列宽自适应给出可全局或单列调用的通用脚本,参数设置部分提供结束日期不早于开始日期且间隔不超过90天的宏校验示例,参数排版则说明筛选项居左、每行不超过6个等布局经验。目前已有1302人学习,适合需要快速上手Smartbi报表配置、对照实操查漏补缺的初中级报表开发者参考。
1. 从一份被反复翻烂的配置文档说起:Smartbi 报表到底该怎么落地
很多做企业报表的同行都有个习惯:拿到一个能跑通的模板,先存下来,下次直接改。我手里这份 Smartbi 报表设置文档就是这么来的——它不是官方手册,而是一线做报表时把「引用模板、页面设置、隔行变色、列宽自适应、参数校验、参数排版、预览发布」这七步串起来的实操记录。Smartbi 本身是挂在 Excel 里的插件式报表工具,设计态就在 Excel 页签里完成,所以它天然带着 Excel 的灵活,也天然带着 Excel 的坑。这份文档解决的核心问题是:让一张报表从「能看」变成「能交付」——列宽不挤、隔行不花、参数不乱填、发布不翻车。适合谁?适合已经会用 Smartbi 拖字段、但每次交付前都要手动调半天的报表开发;也适合刚接手别人模板、面对一堆宏和参数不知道从哪下手的接手者。下面按我实际复现的顺序拆一遍,代码和参数都来自文档原文,能直接抄。
2. 模板引用与页面设置:冻结行数为什么是 1 到 5
2.1 引用模板不是复制粘贴,是继承结构
在 Excel 里打开 Smartbi 页签,登录后点「模板」,再打开目标模板——这一步很多人以为只是加载一个样式文件,其实它继承的是整个报表的结构定义:数据集绑定、参数定义、单元格扩展方向、甚至宏的挂载点。所以文档里强调「在模板上设计新报表样式」,意思是别新建空白工作簿从零画,那样参数和数据集都得重绑,纯属给自己找活。常见做法是:先打开一个最接近需求的已有模板,另存为新的报表名,再在它基础上改字段和样式。这样参数、宏、页面设置都是现成的,改起来只动业务部分。
2.2 页面设置里那个「第一行是空白行」的细节
文档里有一句容易被忽略的注:「第一行是空白行,所以上面报表冻结的是 1-5 行」。这句话背后是 Excel 冻结窗格的逻辑——冻结的是行号,不是视觉上的表头。如果你的报表第一行是空白占位行,表头实际从第二行开始,那冻结 1-5 行意味着前五行(含空白行)都被锁住。参数怎么设?在 Smartbi 的页面设置里找到冻结行数配置,填 5。但要注意:如果模板改动了表头行数,这个 5 必须同步改,否则要么冻少了滚动时表头跑掉,要么冻多了占屏幕。我一般会在模板里用批注标一行「冻结行数=表头结束行号」,交接时不用猜。
2.3 隔行不同颜色:条件格式比手刷靠谱
隔行变色文档归到「设置」里,没给代码,因为 Smartbi 里这步通常走 Excel 的条件格式。做法是选中数据区域,新建规则,用公式=MOD(ROW(),2)=0判断偶数行,设一个浅底色。为什么不用手动填色?因为报表数据行数是动态的,今天 20 行明天 200 行,手刷的颜色不会跟着扩展。用条件格式,行增删颜色自动跟随。这里有个坑:条件格式的应用范围要选到足够大的行,比如选到第 1000 行,否则数据一多后半段就没颜色了。参数上,ROW()不带参数取当前行号,MOD(...,2)=0命中偶数行,想改奇数行就把 0 改成 1。
3. 列宽自适应:那段通用宏到底改哪个参数
3.1 宏的挂载位置和触发时机
列宽自适应文档给了一段function main(spreadsheetReport),这是 Smartbi 电子表格报表的宏入口。挂载位置在 Excel 的 Smartbi 页签下「宏管理」里新建宏。触发时机是报表刷新或加载完成后,spreadsheetReport是框架传进来的报表对象,workbook是底层电子表格工作簿。很多人第一次写会疑惑为什么不用window或document——因为这段代码跑在报表引擎的沙箱里,只能通过spreadsheetReport拿上下文。
function main(spreadsheetReport) { var sheet = spreadsheetReport.workbook.worksheets.get(0); if (sheet === "" || sheet === null) { return; } var counts = sheet.cells.maxDisplayRange.columnCount; // 获取电子表格列数 sheet.autoFitColumns(0, counts); // 从 0 开始,到 counts 列结束 // sheet.autoFitColumn(3); // 只对某列自适应,第一列为 0 }逻辑说明:先取第 0 个工作表,判空防止报表还没渲染完就执行导致报错。maxDisplayRange.columnCount拿的是当前显示范围的最大列数,注意是「显示范围」不是「数据范围」,如果报表有隐藏列,这里可能偏大。autoFitColumns(0, counts)从第 0 列自适应到 counts 列。参数说明:两个入参是起止列索引,左闭右开还是左闭右闭取决于版本,文档注释写「到 counts 列结束」,实测多数版本是包含 counts 的,如果发现最后一列没自适应,把 counts 加 1 再试。单独调某列用autoFitColumn(3),索引从 0 起,第 4 列就是 3。
3.2 全局自适应和单列自适应的取舍
文档提到「下面列宽自适应可以全局设置,但是调试的时候可以单独设置」。全局设置是在报表属性里勾选自适应,好处是省事,坏处是它按所有列一起算,遇到某列内容特别长会把整表撑开。调试阶段我一般先注释掉全局,用autoFitColumn逐列试,确认哪列该宽哪列该窄,再决定要不要放开全局。常见误用是全局自适应加上固定列宽混用——固定列宽会被自适应覆盖,等于白设。如果某列必须固定,就在自适应之后单独sheet.setColumnWidth(index, width)再压回去。
4. 参数校验宏:90 天限制和日期比较的写法
4.1 为什么要劫持 doRefresh
文档里参数校验那段宏,核心是先把原来的doRefresh存到_jhy_doRefresh,再用新函数覆盖它。这是典型的「装饰器」思路——不修改原方法,而是在它前面插一段校验,校验不过就return不往下走。为什么不用 Smartbi 自带的参数校验?因为自带校验通常只能做单参数的非空、范围,跨参数的逻辑(结束不早于开始、间隔不超 90 天)它管不了,只能靠宏。挂载位置同样是宏管理里新建宏。
function main(spreadsheetReport) { if (!spreadsheetReport._jhy_doRefresh) { spreadsheetReport._jhy_doRefresh = spreadsheetReport.doRefresh; } spreadsheetReport.doRefresh = function(fromButton, delayMask) { // 根据参数名称获取参数值 var endtime = new Date(spreadsheetReport.getParameterValue("结束日期 2").replace(/\-/g, "/")); var starttime = new Date(spreadsheetReport.getParameterValue("开始日期 2").replace(/\-/g, "/")); if (endtime < starttime) { setTimeout(function() { alert("结束时间不能早于起始时间"); }, 100); return; } // 结束日期不大于开始日期 90 天 if (endtime.getTime() - starttime.getTime() > 1000 * 3600 * 24 * 90) { setTimeout(function() { alert("两个参数的差不能超过 90 天"); }, 100); return; } this._jhy_doRefresh(fromButton, delayMask); }; }逻辑说明:getParameterValue按参数名取值,文档里参数名带「2」后缀,说明模板里可能有多组同名参数,取值时必须写全名,少个后缀就取到 undefined。日期字符串先replace(/\-/g, "/")把2024-01-01转成2024/01/01,因为部分浏览器对带横杠的日期解析有兼容问题,转斜杠更稳。比较用Date对象直接比大小,间隔用getTime()毫秒差和1000*3600*24*90比。setTimeout包alert是为了让提示在刷新动作之后弹出,不包的话 alert 会阻塞刷新流程,体验很差。参数说明:90 这个数字改天数就改90,改小时就调系数;参数名「结束日期 2」「开始日期 2」必须和模板里定义的完全一致,大小写和空格都算。
4.2 校验宏的三个边界
第一,_jhy_doRefresh这个标记变量是防止宏被重复挂载导致doRefresh被套多层,如果发现刷新一次弹三次提示,就是这层没判好。第二,getParameterValue在参数还没渲染完时可能返回空字符串,new Date("")是 Invalid Date,比较结果全是 false,校验会静默失效——所以严格场景要加空值判断。第三,90 天限制是「可选」的,文档明确说「跟进报表参数决定是否需要」,没有日期参数的报表别硬加,加了反而多一次无意义刷新。
5. 参数排版与预览发布:一行不超过 6 个的排布逻辑
5.1 参数排版的平均分配原则
文档对参数排版给了很具体的约束:筛选项居左,每行尽可能美观的基础上平均分配,一行不超过 6 个,如果是 2 行第二行至少保留 2 个。这套规则不是审美偏好,是可用性底线。一行超过 6 个,参数标签加输入框在 1366 宽的屏幕上就会挤成两行,反而更乱;两行时第二行只剩 1 个,视觉上像被遗弃的孤儿控件。实操做法:先数参数总数,除以 6 向上取整得行数,再平均分。比如 8 个参数,分 2 行每行 4 个;7 个参数,分 2 行一行 4 个一行 3 个。居左是指整块参数区靠左对齐,不是每个参数靠左,别理解偏。
5.2 预览发布前必须走的检查项
预览发布是最后一步,但翻车往往在这。我一般按这个顺序过一遍:先点预览,看数据行是否正常扩展、隔行色是否跟随、列宽是否自适应到位;再改参数值触发校验宏,确认提示能弹出且刷新被拦住;然后检查冻结行在滚动时是否锁住表头;最后看参数区在最小分辨率下有没有换行错位。发布时注意报表的权限和参数默认值——默认值设成空可能导致首次打开就报校验错误,设成当天则多数场景可用。文档没展开发布配置,但这一步的坑基本都在默认值和权限上,和样式无关。
6. 避坑与排查:那些让我返工三次的细节
6.1 列宽自适应后最后一列还是被截断
现象:宏跑了,前面几列都自适应了,最后一列内容还是显示不全。原因:maxDisplayRange.columnCount取的是显示范围列数,如果最后一列是后来扩展出来的,显示范围可能没算进去,或者autoFitColumns的结束索引是开区间。解决:把autoFitColumns(0, counts)改成autoFitColumns(0, counts + 1),或者直接用sheet.autoFitColumns(0, sheet.cells.maxDisplayRange.columnCount - 1)试边界,两个方向都试一次就知道当前版本的区间习惯了。
6.2 日期校验宏完全不生效
现象:结束日期早于开始日期,点刷新照样出数,没有任何提示。原因:参数名对不上。文档里是「结束日期 2」「开始日期 2」,但实际模板里可能叫「结束日期」或「endDate」,getParameterValue取不到就返回空,new Date("")是 Invalid Date,两个 Invalid Date 比较永远 false,校验被绕过。解决:在宏里先alert(spreadsheetReport.getParameterValue("结束日期 2"))把值打出来,确认参数名和取值都正确,再写比较逻辑。
6.3 隔行变色在数据刷新后消失
现象:第一次打开有隔行色,改参数刷新后颜色没了。原因:条件格式的应用范围是固定区域,刷新后数据行数变了,超出原范围的行没有格式。解决:把条件格式的应用范围选到远大于预期数据量的行,比如选到第 2000 行;或者改用宏在刷新后重设格式,但那样每次刷新都跑一遍,性能不如条件格式。
6.4 冻结行数设了但滚动时表头还是跑
现象:页面设置里冻结了 5 行,实际滚动时第 3 行就跟着滚了。原因:冻结的是 Excel 的行,但 Smartbi 报表可能有自己的表头渲染层,两者没对齐;或者模板第一行空白行导致实际表头行号和冻结行号错位。解决:确认表头实际占用的行号区间,把冻结行数改成表头结束行号;如果 Smartbi 有独立的表头冻结配置,优先用它而不是 Excel 冻结。
6.5 参数排版在宽屏正常窄屏错位
现象:开发机 1920 宽看着一行 6 个正好,用户 1366 宽打开变成一行 4 个加两个换行。原因:参数区用了固定宽度或百分比宽度,没做响应式。解决:参数区容器用自适应宽度,单个参数控件设最小宽度而不是固定宽度,让它在窄屏时自然换行且保持每行数量可控。文档说「具体问题具体分析」,指的就是这种要按实际分辨率调的情况。
7. 把校验宏改成可配置:一个让交接少吵三次架的技巧
文档里的 90 天是硬编码在宏里的,交接时如果业务方说「我们改成 60 天」,接手的人得翻宏代码找那个数字。我的习惯是把这类阈值提到报表参数或一个配置对象里,改的时候不用动逻辑。具体做法:在宏顶部定义一个var CONFIG = { maxDayGap: 90, dateParamEnd: "结束日期 2", dateParamStart: "开始日期 2" };,下面所有用到的地方引用CONFIG.maxDayGap。这样业务改规则只动一行,也顺便把参数名集中管理了,避免 6.2 那种参数名对不上的问题。
function main(spreadsheetReport) { var CONFIG = { maxDayGap: 90, // 最大间隔天数,改这里 dateParamEnd: "结束日期 2", // 结束日期参数名 dateParamStart: "开始日期 2" // 开始日期参数名 }; if (!spreadsheetReport._jhy_doRefresh) { spreadsheetReport._jhy_doRefresh = spreadsheetReport.doRefresh; } spreadsheetReport.doRefresh = function(fromButton, delayMask) { var endRaw = spreadsheetReport.getParameterValue(CONFIG.dateParamEnd); var startRaw = spreadsheetReport.getParameterValue(CONFIG.dateParamStart); if (!endRaw || !startRaw) { // 空值直接放行,避免误拦 this._jhy_doRefresh(fromButton, delayMask); return; } var endtime = new Date(endRaw.replace(/\-/g, "/")); var starttime = new Date(startRaw.replace(/\-/g, "/")); if (endtime < starttime) { setTimeout(function() { alert("结束时间不能早于起始时间"); }, 100); return; } if (endtime.getTime() - starttime.getTime() > 1000 * 3600 * 24 * CONFIG.maxDayGap) { setTimeout(function() { alert("两个参数的差不能超过 " + CONFIG.maxDayGap + " 天"); }, 100); return; } this._jhy_doRefresh(fromButton, delayMask); }; }逻辑说明:相比原版,多了空值放行分支——参数没填时不拦,让用户先填再校验,否则首次打开空参数直接弹错很烦。阈值和参数名收进CONFIG,提示语里的天数也用变量拼,改一处全生效。参数说明:maxDayGap单位是天,想改成按小时就把1000*3600*24换成1000*3600并同步改提示语。验证方法:改完宏后,分别用「结束早于开始」「间隔 91 天」「间隔 89 天」「参数留空」四种输入各刷一次,看提示和放行是否符合预期,四种都过才算稳。
从那以后我每次交付带参数的 Smartbi 报表,都强制走一遍「空值、边界、超限、正常」四组输入,不靠肉眼扫代码。这套习惯帮我省下的返工时间,比写宏本身多得多。希望帮到你。
本文还有配套的精品资源,点击获取