【教程】帆软报表实现批量图片下载

11 11~14 分钟

前言

实际生产中,由于业务产生了一个小的需求,需要查询数据库中的url并批量打包下载。这个需求确实也不复杂,但是无论如何还是需要开发的,尤其是与用户交互的方面。突然想到生产中有一套帆软报表,可以实现自定义sql查询数据,那么能不能把查询结果的url交给浏览器去下载呢,经过一番探究答案是肯定的!这样简化流程后,每次只需要根据这个报表模板去修改业务sql即可满足业务要求,让只会sql的业务人员也可以实现自定义下载。

实现

然后在你的报表设计器中添加一个按钮,用来下载,添加一个点击事件,引用JavaScript脚本中添加刚才下好的两个js脚本,把我给你准备的js代码粘贴进去,就可以实现下载全部图片打包了!

image-ze4f.png

    var _obj = $(".x-table tr");
    var _length = _obj.length;
    var urls = [];
    for(var i = 0; i < _length; i++) {
        var _td = _obj.eq(i).find("td");
        for(var j = 0; j < _td.length; j++) {
            var _val = _td.eq(j).text();
            var _tval = $.trim(_val);
            // 可以加校验:比如只收集http/https开头的内容
            if(_tval !== "" && /^https?:\/\//.test(_tval)){
                urls.push(_tval);
            }
        }
    }
    if(urls.length === 0){
        alert("未找到任何图片URL!");
        return;
    }

    var zip = new JSZip();
    // 用IIFE+async方式支持await
    (async function(){
        for(let i=0; i<urls.length; i++){
            try{
                let response = await fetch(urls[i], {mode: 'cors'});
                let blob = await response.blob();
                let ext = blob.type.split('/')[1] || 'jpg';
                zip.file('image_' + (i+1) + '.' + ext, blob);
            }catch(e){
                // 可选:console.warn(`图片下载失败: ${urls[i]}`);
            }
        }
        zip.generateAsync({type:"blob"}).then(function(content){
            saveAs(content, "images.zip");
        });
    })();

  • 虽然已经初步实现了下载,但是实际中还是遇到了两个问题:1.报表默认是分页的,只能下载当前页面的内容。2.由于使用浏览器去下载,实际上会发生跨域的问题需要解决,这个在浏览器控制台可以看到报错。

分页问题:只需要在报表的查看地址后面拼写 &__bypagesize__=false ,就可以关闭默认的分页,可以存成收藏夹给业务侧使用。

跨域问题:这个需要服务端解决,一般需要一层代理或者修改服务端跨域策略。我这边环境是nginx代理的图片地址,因为是内网地址我直接改成*了,实际可以改成具体的地址。

add_header 'Access-Control-Allow-Origin' '*' always;