Finereport在导出excel时,通过筛选框动态选择导出的sheet页

前言

由于业务需求,翻了很多文档和帆软评论区,都没有找到一个关于在导出excel时,动态选择sheet页的教程。虽然帆软评论区有大佬提及,可以写JS自定义导出按钮,但是对于没有JS基础的人来说,还是一头雾水。作为小白的我研究了好几天,终于通过JS实现了。因此,我决定把详细教程写下来。

一、需求说明

现要求制作:业务员各月&汇总业绩数据报表,具体的需求如下:

  1. 汇总sheet页,分别汇总各月份的数据
  2. 明细sheet页,明细按月份拆分到各月份的sheet页中,且每个sheet页最后一行是金额汇总
    在这里插入图片描述
    简单来说,就是要在一个excel中将业务员的汇总sheet页和各月明细sheet同时导出。。
    举例:假设当前是2025-10-15,excel只需要导出“汇总”+“1-9月的明细数据”,而10-12月的sheet页不要

二、分析

  1. 现帆软文档资料中有JS实现分Sheet导出Excel,但只能按照规则将数据集拆分到重复性的sheet页中,且不支持存在非重复性的sheet。比如额外增加汇总sheet页,导出的结果中汇总sheet页会重复n遍。这个效果不满足我当前的需求。
    举例:假设当前是2025-4-15,excel实际需要导出“汇总”+“1-3月的明细数据”,共4个sheet页。
    但按照资料的方式,导出的excel中:汇总sheet页有3个,以及1-3月各月份明细,共6个sheet页。这显然不对劲,我不需要汇总sheet页重复啊

  2. 现在想到的只有自定义按钮+URL的方式导出了,那么问题就在于:
    如何将筛选框的参数和sheet页映射上?
    如何将筛选框的参数通过URL传递过去?

三、实现思路

JS自定义导出按钮 +URL拼接导出。根据筛选框参数映射为第i个sheet页,然后JS拿这几个sheet的序号,直接写死导出,从而实现动态选择sheet页。

文档资料:多 Sheet 报表导出指定 Sheet 时,参数值为 :&sheets=[sheet序号],Sheet 序号从 0开始,导出多个 sheet 时序号以逗号分隔。如导出 sheet1:&format=excel&sheets=[0],导出 sheet1 和sheet2:&format=excel&sheets=[0,1]。

四、实现具体步骤

1. 自定义好sheet页内容和过滤条件

在finereport的cpt文件中,创建多个sheet页,sheet页分别是汇总,1-12月份的数据,各Sheet页的筛选条件自己过滤好。
在这里插入图片描述

2. 参数筛选框制作

月份:我这里给的是年-月,对应2025-01等。这块看个人,但要注意这块要和数据集过滤条件搭配上,以及和JS代码中的sheet页序号映射上。

-- 明细数据集过滤条件
WHERE DATE_FORMAT(t.data_date,'%Y-%m')  in ('${月份}')
-- 生成当前年份的 12 个月数据,如2025-01
SELECT DATE_FORMAT(
        MAKEDATE(YEAR(CURDATE()), 1) + INTERVAL (t.month_num - 1) MONTH, 
        '%Y-%m') AS "年月"
FROM (
    SELECT 1 AS month_num UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
    UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8
    UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12
) t
ORDER BY t.month_num;
-- JS将月份参数和sheet页序号映射,形如2025-01:1;2025-02:2。我这里sheet页序号0放的是汇总页
var year = new Date().getFullYear();
var sheetMap = {};
for (var i = 1; i <= 12; i++) {
    sheetMap[year + "-" + i.toString().padStart(2, '0')] = i;
}

在这里插入图片描述在这里插入图片描述

3. 自定义导出按钮

将按钮拖到表头位置,点击按钮进入编辑状态。添加点击事件后,即可编辑JS脚本内容
在这里插入图片描述

4. 自定义按钮中的JS代码

官网文档参考:JS获取决策报表参数界面控件值URL直接导出报表批量导出多个文件
完整代码如下:

//✅变量定义,这里的参数获取参考官网文档,部分JS的获取参数规则可能不适用
var selectedValue = _g().getParameterContainer().getWidgetByName("月份").getValue();
var name = _g().getParameterContainer().getWidgetByName("业务员").getValue();
var namearr = name.split("','");

// 清洗不同格式的输入(字符串、数组等)
var selectedValues;
if (typeof selectedValue === 'string') {
    selectedValues = selectedValue
        .split(',')
        .map(function(v) {
            return v.trim().replace(/^'|'$/g, '');
        })
        .filter(function(v) {
            return v !== '';
        });
} else if (Array.isArray(selectedValue)) {
    selectedValues = selectedValue.map(function(v) {
        return typeof v === 'string' ? v.trim() : v;
    });
} else {
    selectedValues = [selectedValue.toString().trim()];
}

//构造参数与sheet页序号的映射关系。汇总页序号为0,因此映射的sheet页序号从1开始
var year = new Date().getFullYear();
var sheetMap = {};
for (var i = 1; i <= 12; i++) {
    sheetMap[year + "-" + i.toString().padStart(2, '0')] = i;
}

//将筛选的sheet页序号放进数组中
var indices = [];
var unmatched = [];
indices.push(0)
for (var i = 0; i < selectedValues.length; i++) {
    var value = selectedValues[i].toString().trim().toUpperCase();
    if (sheetMap[value] !== undefined) {
        indices.push(sheetMap[value]);
    } else {
        unmatched.push("'" + value + "'");
    }
}

// ✅ 构建导出 URL,关键:把当前选择的“月份”参数也传过去
var url = '业务员业绩提成核算.cpt';
url += '&sheets=[' + indices.join(',') + ']';  //限制导出的sheet页序号
url += '&format=excel';
url += '&月份=' + selectedValue;

//用于获取当前日期,让导出的文件名自带导出日期
var now = new Date();
var yyyy = now.getFullYear();
var mm = String(now.getMonth() + 1).padStart(2, '0');
var dd = String(now.getDate()).padStart(2, '0');
var now_date = yyyy + mm + dd; // 如:20250401

//打开新的URL进行导出。这里的循环是用于批量导出业务员的。如果没有这个需求,这里可去掉循环
for (var i = 0; i < namearr.length; i++) {
	var pars = '&__filename__=' + namearr[i] + '核算提成表_'+now_date;
	window.open("${servletURL}?viewlet=" + encodeURI(url + pars) + "&业务员=" + encodeURI(namearr[i]), "_blank");
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值