请上传宽度大于 1200px,高度大于 164px 的封面图片
    调整图片尺寸与位置
    滚轮可以放大缩小图片尺寸,按住图片拖动可调整位置,多余的会自动被裁剪掉
取消
迈达斯之手(uid:55902)
职业资格认证:尚未取得认证
纯前端图表快速集成【支持自适应、联动、导出、打印】
本方案为通过纯前端手段,快速在FR中集成Echarts,达到快速开发各种异化图表,每一个异化图表用的地方很少,但是有很多种异化图表(大屏中比较常见),每一个异化图表都开发插件成本太大,也不合适,毕竟也许只有一个地方需要用。 如果你不满足以下条件,请直接关闭页面,这个方案基本上你用不上。 1.熟练使用JS,熟悉前端开发 2.熟练使用Echarts,有丰富的Echarts开发经验 以上两点至关重要!任意一点不具备基本上这个方案你都用不上! 106901 demo效果 106902 特别说明:改方案开始会比较多JS代码量,随着构造器(现在你先不管构造器是啥,后面会介绍)的封装越多,使用就越简单,越方便。 1.需要安装插件:超级API插件【目前内置在里面的】 2.开发你需要的构造器。 构造器就是生成setOptions的配置的方法。 核心难点1:数据处理部分的构造器 ;(function() { var group = function( data, def ){ var xs = ; var ss = ; var vs = ; var len = data.length; for( var i=0; i
超级API计划
当前版本的FR插件开发过程中~让开发者头疼的往往是与FR的耦合问题~很多插件都会大面积的使用到FR的内部代码,这样使得插件跟FR耦合过深,很容易在产品升级,JAR包更新时发生各种不兼容的问题。所以我大胆的想了一个方法~就是开发一个超级API插件~尽可能的把我们需要的FR的代码以功能API的形式封装到插件里面~以后其他插件与FR的耦合~都尽可能通过这个插件~这样开发者就没必要去纠结FR的内部实现了~兼容问题也都由这个插件来维护~ 现面向全网番薯和爱好者征集,你觉得需要用到的目前却没有的API~ 现面向全网番薯和爱好者征集,你觉得需要用到的目前却没有的API~ 现面向全网番薯和爱好者征集,你觉得需要用到的目前却没有的API~ 插件上传不上来(总是说我没安装flash,都安装N次了)~我放到我的技术交流群里面了( 367705354)需要的加群下载(加群请带上论坛昵称)~ 目前也么得啥API,倒是提供了几个小方法 修改sheet名(可导出) 前端调用: FR.SPAPI.setSheetName(tag,name); tag 就是要修改的sheet原名或者sheet编号(从0开始) name 就是新名字 比如:把sheet2 改名为AAA 调用为 FR.SPAPI.setSheetName( ‘sheet2’, 'AAA'); 把第1个sheet(从0开始)改名为AAA调用为 FR.SPAPI.setSheetName( 1, 'AAA'); 后端调用: com.midas.api.API.setSheetName( Object sheetTag,String newName, String sessionID ); param sheetTag 要修改的sheet名或索引 param newName 新名字 param sessionID 报表sessionID return 执行结果 JSONObject 适用于分页预览填报预览,不支持跨sheet取数【要连跨sheet取数一起改的话性能太低了】 分页预览修改单元格的值(支持打印导出) 限制:联动单元格运算不会执行(原因是分页预览后台结果里面只有值没有保留联动需要的相关依赖和公式),所有修改哪一个单元格,只会改变那个单元格的值,相关联动单元格的值不会变 调用方法: FR.SPAPI.setPageCellValue( cell, value ) FR.SPAPI.setPageCellValue( cell, value, pn) cell 要修改的当前页面上的单元格 比如A2 B5这样的~ value 新值 pn 页码,不传表示修改当前页 报表块CPT滚动 支持以下情况: 无冻结cpt,分页填报预览 冻结行cpt,分页填报预览 表单报表块 冻结行表单报表块 自定义滚动条插件 调用方法: var spd = 3.5;//滚动的速度,自己调节,不传默认就是3.5 表单中,在对应的报表块控件的初始化事件里面写 FR.SPAPI.autoScroll(this,spd); cpt模板中在分页预览或填报预览的加载结束事件写 FR.SPAPI.autoScroll(null,spd); 这两个是缺省的调用方法,还可以传递一个滚动到最下面之后的回调函数比如: var cbk = function(stimer,$tag){ 自定义操作,参数1是定时器序号,参数2是滚动的对象,当一次滚动到最下面时会执行这个方法,如果不传这个方法,默认的就是停止滚动并,回到最上面。 } 补充:回调返回true则滚动会继续执行,返回false则终止滚动 调用方法为: FR.SPAPI.autoScroll( this, spd, cbk ); FR.SPAPI.autoScroll( null, spd, cbk ); 另外值得注意的就是,鼠标悬浮在滚动对象上,将停止滚动,离开将恢复滚动,双击将终止滚动,再次双击将开启滚动(否则不论鼠标悬浮还是离开都不会滚动) 导出防sessiontimeout 该API为纯前端API,调用方法 1.以默认excel的导出形式导出当前报表 FR.SPAPI.exportEx(); 2.以xxx的形式导出当前报表 都是excel FR.SPAPI.exportEx("xxx"); 3.自定义文件名 FR.SPAPI.exportEx("xxx","文件名"); 4.导出指定结果报表,用于某些特殊场景(比如子表触发主表导出) FR.SPAPI.exportEx("xxx","文件名",sessionID); 扩展:获取当前sessionID_g().currentSessionID; 编辑于 2018-6-6 14:27
插件开发技巧之暴力重写
在FR的插件开发中,我们有时候可能会遇到这样一个问题 我们在实现一个接口方法时 public C Func( A a, B b ); 接口方法里面操作后需要修改A的私有成员D d,为其修改或增加一些方法,以改变D类的一些FR的没有接口处理的功能。 为了更容易理解我抽象了一个场景 首先是我们的执行过程 public class App { public static void main(Stringargs){ A a = new A("张三"); IA e = new E(); D d = new D(a); d.run(); //其他操作 e.run( d ); //其他操作 d.run(); } } public class A { private String name = null; public A(){ } public A(String name){ this.name = name; } public void run() { System.out.println("A is "+name+" running."); } public void run2(){ System.out.println("A.run2 is "+name+" running."); } } public class D{ private A a = null; public D( A a ){ this.a = a; } public void run() { a.run(); } } public class E implements IA { @Override public void run( D d ) { System.out.println("E.run"); } } public interface IA { public void run(D d); } 我们运行显示结果为: A is 张三 running. E.run A is 张三 running. 假设我们又一个需求是需要改变执行逻辑里面的第二次D.run时A的run逻辑。而类A和APP以及D是FR产品JAR包里面的业务逻辑,我们没办法重写。 我们能写的就是接口IA的实现E,怎么做呢?通过反射的方式实现,我封装了一个代理类。 public class Proxy { public static T getv( Object val, String key ){ return Reflect.on(val).get(key); } public static void setv( Object val, String key, Object v ){ Reflect.on(val).set(key,v); } public static void reset( Object val, String key, Object v ){ Reflect ref = Reflect.on(val); copy(v,ref.get(key)); ref.set(key, v); } public static T copy( T target, Object old ){ Reflect ref = Reflect.on(target); Reflect oref = Reflect.on(old); Set kset = oref.fields().keySet(); for(String fieldName : kset ){ ref.set( fieldName, oref.get(fieldName) ); } return target; } } 我们先开发一个类B继承A,在B方法里面我们重新定义A的run逻辑 public class B extends A { //修改方法 public void run() { String name = Proxy.getv(this, "name"); System.out.println("B is "+name+" running."); Proxy.setv(this,"name", "李四"); run2(); } //新增方法 }然后我们在E中实现 public class E implements IA { @Override public void run( D d ) { System.out.println("E.run"); B b = new B(); Proxy.reset(d, "a", b); } } 运行结果如下 A is 张三 running. E.run B is 张三 running. A.run2 is 李四 running. 第二次A的run逻辑就已经改成B的了~ 这种方式虽然一定程度上能解决很多没有接口的插件问题,但是因为这种方式对FR类的封装破坏性很强,而且由于本身不是接口功能,FR自身在升级的时候可能不会被考虑到,而发生改变。所以不到万不得已最好别随便用~ 编辑于 2018-5-17 22:31
巧借PDF输出实现cpt的PDF预览
先上效果图 101389 测试了 IE11 chrome firefox 都阔以 上核心代码 public class Server extends NoSessionIDService { @Override public String actionOP() { return "pdf"; } @Override public void process(HttpServletRequest req, HttpServletResponse res, String op) throws Exception { String sid = WebUtils.getHTTPRequestParameter(req, "sid"); HttpSession session = req.getSession(true); //将同一个前端的预览请求任务缓存在一起 Map vtsk = (Map) session.getAttribute("PDFSID"); if( null == vtsk ){ vtsk = new HashMap(); session.setAttribute("PDFSID",vtsk); } if( StringUtils.isEmpty(sid) ){ //获取要预览的模板 String cpt = getCptPath(req); //生成计算模板用的参数表 Map parameters = getParameters(req); //注册任务,生成sid sid = registerTask( vtsk, cpt,parameters); //得到最终预览的URL String url = getURL(sid); //得到网页的标题 String title = getWebTitle(cpt,parameters); //转换成网页输出 String html = "" + title + "" + "