#
摘要: NET系统集成有自己独立的登录验证方式。比如,跟报表集成时,不需要再使用报表内置的登录界面,只需要将报表默认的参数用户名fr_username和密码fr_password发送给报表系统,触发一下报表验证方式就可以实现单点登录了,以下用FineReport的.NET跨域单点登录案例简单介绍一下。
系统本身有独立的登录验证方式如下图:
1.触发报表验证方法
报表集成时不需要再一次...
阅读全文
对于报表开发,很多情况下,自带的函数就能满足大部分用户的报表制作需求,FineReport也不例外。但是在一些特殊领域,可能需要一些特殊的函数,在这种情况下,FineReport提供了自定义函数机制,可以由用户根据业务需要自己来定义一些函数,但这些函数必须满足函数定义规则。
先来了解一下FineReport的函数定义规则:Functionname(Para,Para,...),其中Functionname为函数名,Para为参数。
每一个函数都被定义成一个类,这个类必须要实现Function这个接口,在运算的时候首先通过函数名反射取得这个类,然后调用它的run(Object[] agrs)方法。下面以SUM这个函数为例。
SUM函数原理
由程序可以看到,SUM类用来运算SUM函数,他继承了AbstractFunction类,而AbstractFunction实现了Function这个接口。
当函数运算的时候,先根据函数名取得运算该函数的类,如SUM(2,4,true)这个函数先根据函数名取得SUM这个类,然后调用SUM类的run(Object[] args)方法,args中存放的是SUM函数的参数,运算的时候可以从args中取得参数进行运算。如执行结果为SUM(2,4,true)=2+4+1=7。
SUM函数所使用代码:
package com.fr.report.script;
import java.lang.reflect.Array;
import com.fr.report.script.core.FArray;
import com.fr.report.script.core.FunctionHelper;
public class SUM extends AbstractFunction {
public Object run(Object[] args) {
double result = 0;
for (int i = 0; i < args.length; i++) {
if (args[i] == null) {
continue;
}
result += parseObject(args[i]);
}
return FunctionHelper.parsePrimitiveDouble(result);
}
private double parseObject(Object obj) {
if (obj instanceof Number) {
return ((Number) obj).doubleValue();
} else if (obj instanceof Boolean) {
return ((Boolean) obj).booleanValue() ? 1 : 0;
} else if (obj instanceof FArray) {
FArray array = (FArray) obj;
double sum = 0;
for (int i = 0; i < array.length(); i++) {
sum += parseObject(array.elementAt(i));
}
return sum;
} else if (obj != null) {
try {
return Double.parseDouble(obj.toString());
} catch (NumberFormatException exp) {
return 0;
}
}
return 0;
}
}
实现步骤
编写自定义函数
下面以一个简单的自定义函数例子来说明使用自定义函数。我们定义一个函数StringCat,他的作用是把所有的参数以字符串的形式连接起来。
StringCat函数使用规则为StringCat(Para,Para,Para…….);
其中Para为该函数的参数,个数不限。
由概述可知AbstractFunction实现了Function这个接口,因此StringCat可以直接继承AbstractFunction类,完整代码如下:
package com.fr.function;
import com.fr.script.AbstractFunction;
public class StringCat extends AbstractFunction {
public Object run(Object[] args) {
String result = "";
Object para;
for (int i = 0; i < args.length; i++) {
para = args[i];
result += para.toString();
}
return result;
}
}
这里要注意,使用函数StringCat(Para,Para,Para…..)时,根据函数名取得运算该函数的类StringCat,并将参数传入类中的args对象数组中,执行该类的run函数。
而在run函数中即实现了将传入的参数以字符串的形式连接起来。并返回最终形成的字符串。
编译自定义函数
将编译后的StringCat.class放到FineReport的安装目录WEB-INF下面的classes目录下,因为StringCat.java属于包com.fr.function,所以StringCat.class需要放到classes\com\fr\function目录下。
注册自定义函数
生成该函数的类后需要在设计器中进行注册,才可以使用该函数。打开服务器|函数管理器,选择刚刚定义好了StringCat类,如下图
函数名称可以自定义,如这边定义为StringCat;
同时可以添加该函数的使用说明,如上图所示的描述
使用自定义函数
注册好自定义函数后,制作报表时便可直接使用了,使用方法与内置的函数是相同的。
新建报表,定义两个报表参数para1、para2,类型分别为字符串型与整形,默认值分别为空字符串与0
在空白报表的任意单元格里写入公式:=StringCat($para1,$para2)(注意:写入公式的时候在参数名前加$,表明这是使用的参数)
点击分页预览在参数控件中,写入参数值如para1为:FineReport,para2为:123。
点击查询可以看到结果
说明StringCat公式可以正常使用啦。
对于一款软件或产品,尤其是一些企业级应用的IT软件,是不可能满足所有需求的。尤其是针对业务化的产品需求,某些个性化的需求就要进行二次开发。二次开发需要API接口,无论是什么样的开发,开发人员都需要对开发的产品大内部结构有所了解。在应用广泛的企业报表领域,开发在所难免,下图展示了我在工作中开发的FineReport的内核示意图。
这款类似于Excel的报表软件,成为设计器。在设计器中新建一个工作薄就是建了一个WorkBook,WorkBook相当于一个容器,里面可以放任意个WorkSheet,就相当于在设计器的一个工作薄中新建了多个sheet。每个WorkSheet是由任意个单元格CellElement组成,因此CellElement是一个模板的最小元素。获得WorkBook后,必须取得其中的某个WorkSheet才能对这个报表中的CellElement进行操作,这对于模板还是结果都是一样的,如果以模板为例,最基本的内核结构就是如下面这张图
由于每个部分各自包含了很多属性,比如可以设置单元格的前景、背景、边框、字体、字号等;又比如每个WorkSheet中可以添加,删除单元格、可以设置每个sheet的页面属性、可以给每个sheet中添加图表悬浮元素等;再比如可以对WorkBook进行执行获得结果并导出成各种格式、可以进行打印、添加工具栏等等。
正是基于这样,再开发时会有丰富的API接口可供调用。以下是FineReport包含的所有开放的API。
由图可有看出,对于这样的开发可以从以下几个功能点进行开发。
报表数据源
设计器本身已经提供了数据库数据源、文本数据源、xml数据源等多种数据来源方式,同时还可以通过java程序自行生成数据来源,只需要实现TableData接口便可以了。
输入输出报表
在程序中新建一个报表对象同时也可以直接读取一个cpt模板来生成,经过处理的报表最终可以导出成多种形式,可以保存为程序网络报表在web端直接访问,也可以导出为excel、pdf、word、cpt等多种格式文件。
设置单元格属性及报表属性编辑
可以对报表对象的单元格属性、web属性、参数、页面设置等多个属性进行控制,可以自由控制单元格的显示样式、工具栏的按钮、参数面板的展示、参数的赋值等等。
自定义填报
开放的填报api接口能够根据自己的需要来定义填报入库方式,通过填报接口,可以往数据库中保存用户操作日志、在填报成功与失败时进行各种处理等等。
开发的工作虽枯燥也有意思,闲来无事时也会开发一些有趣的应用,比如下图把天气集成到报表页面。
关于这个问题,制作数据地图的方法已不新奇,总体来说有这么几类方案:
一类方案:直接在excel里制作
优势:个人小数据量应用较为方便简单
缺点:需要熟悉VBA,且更强大的功能对VBA水平要求较高
1、绘制地图图形 + VBA宏语言
思路:用插入图形"任意多边形"绘制地图;每一个"任意多边形"赋予正确名称;对"任意多边形"赋值;利用VBA对"任意多边形"的值进行操作, 例如上色。
先准备一张所需要的地图图片,网上都有,可以下载
然后利用插入绘制多边形图片将地图中的区域描边
选定好的区域可以在左上角修改名称
将数据表中的数据和地图中的地区做关联,这里就要用到VBA了。
代码:
Sub ProvRefill()
ActiveSheet.Shapes.Range(Array("shandong")).Select
With Selection.ShapeRange.Fill
.Visible = msoTrue
.ForeColor.ObjectThemeColor = msoThemeColorAccent1
.ForeColor.TintAndShade = 0
.ForeColor.Brightness = -0.5
.Transparency = 0
.Solid
End With
End Sub
这段代码是修改地图所选区域的颜色的,其他功能类似,懂VBA的会觉得简单,不懂的可以自行百度。
2、EXCEL插件集成
这类插件有很多,推荐Power Map for Excel 2013,安装好之后,选择数据区域,启动就行
二类方案:其他软件
优势:地图已集成在内,可连接数据库,已有功能强大大数据量处理具有优势
缺点:自定义开发对人员水平要求较高,较困难
这一类软件一般是数据可视化的软件,能用到EXCEL数据源的,现在比较普遍的是报表工具和所谓商业智能大数据工具。
不多说,大家可能觉得陌生,那就直接上实例。
这里介绍FineReport(功能强大最实际的报表工具)
展示数据地图不在话下,关键有地图钻取功能。
所谓钻取就是:比如你点击山东省,进入山东省省地图,显示山东省各市的数据,数据的展示方式可以使用其他图表,比如条形图、气泡图等等。
详细步骤:
1、 准备数据源
将excel的数据导入到这个报表设计器里,如果你的excel数据是取自于数据库的话,可以直接从设计器里读取数据库的数据。
2、 合并一片单元格,点击菜单栏中的插入>单元格元素>插入图表,选择地图,然后点击确定,如下图:(这里申明一下,这个软件类似于EXCEL,所以一些操作术语何以类比于EXCEL)
1、 选择地图类型,国家地图、省级地图还是其他云云,或者你有自定义的SVG地图也行。这里注意,地图的区域名要和区域数据字段的名字对应。
个人觉得钻取才是其亮点,所以这里一定要介绍一下。
钻取:
定义好地图的类型之后,就可以为地图定义数据来源了,选中地图,点击图表属性表-数据,进入数据设置面板,地图展现方式选择多层钻取,如下图:
从上图可以看到,钻取层级下有个中国的文件夹,双击即可打开查看中国下面的省份,选中中国文件夹,右击,则会跳出层级设置对话框,如下图:
要实现点击山东省能出现一张柱状图,这个其实是两张图表关联的,所谓“联动”。
联动:
合并一片单元格,点击插入>单元格元素>插入图表,选择柱形图,点击确定即可添加一张柱形图。
柱形图的数据来源:(这里我都是直接用数据库的数据源)
在此,地图和柱形图都已经设置好了,如果要实现联动,需要在设置交互属性。
选中地图,在图表属性表中选择特效,点击交互属性,添加一个超级链接,即点击,添加一个图表超链-联动单元格,设置如下图:
到这里基本就完成了,感觉自己做得图有些low,别毁了人家名声,其实人家功能很强大,可视化很炫的。
另附几张图:
其他软件的话,还有商业智能可视化类的tableau, FineBI,可能对大家比较陌生,就不做教程介绍了。
总之,利用excel中的数据源制作地图图表方法多多,不当之处还请指正。
很多人会遇到这种情况,在浏览页面时,发现鼠标右键不启用了。咦?刷新刷新再刷新,并无卵用,然后怒敲鼠标(没错,我就是这么暴力),更换浏览器,无用,最后弃之。其实,这是因为设计人员对页面启用了“禁用右键”功能,目的是为了防止内容被抄。
曾经也是受害者的我,如今作为一名小小的IT开发人员,就来告诉你如何“禁用右键”!
这里列举一个我在利用FineReport开发报表时遇到的案例。
启用“禁止右键”
报表大家都懂吧,启用“禁用右键”功能,往往是出于展示过程中的数据安全和操作上的失误考虑(想想银行动辄几千几百万的金额,分分钟要长个心眼啊)。
首先在页面中调用模板,一般是将url放在iframe中,然后通过点击相应的树节点查看报表,一般报表都会设置权限,如果设置权限,登录系统后可能有些用户通过点击右键中的属性查看url然后访问,这样对系统来说其实是很不安全的,因此禁止用户通过右键查看url,此时可以使用禁用菜单右键功能。
2. 实现步骤
点击模板>模板web属性>(填报,数据分析,分页预览设置),选择为该模板单独设置,在下面的事件设置里面添加一个加载结束事件,完整js代码如下:
1.//点击右键 无动作
document.oncontextmenu=new Function("return false");
2.//点击右键 弹出提示
document.oncontextmenu=function(e) {
alert("提示内容");
return false;
}
这段代码的基本原理是让用户的页面右键点击事件返回false,禁止弹出菜单。
如果模板中有参数面板,希望一调用模板就禁用右键,而不是查询之后禁用,则需要在参数面板的查询按钮中添加初始化事件,写入上述js代码。
查询之前就做提示和禁用
破解“禁用右键”
找到浏览器顶部菜单中的【工具】按钮,在下拉菜单中,选择【Internet选项】
打开Internet选项后,再切换到【安全】选项卡,然后再点击底部的【自定义级别】
然后在打开的【安全设置-Internet区域】对话框中,找到【活动脚本】设置选项,然后将默认的“启用”更改为【禁用】,最后再一路点击底部的【确定】。
然后关闭再重启浏览器,再打开刚刚的网页,你就会发现“残疾”的鼠标右键能正常点击了。
以上就是我的方法,不足之处还请多多指点。
摘要: 今天我们来聊聊Java防盗链,多说无用,直接上应用案例。
这里所用的工具是报表软件FineReport,搭配有决策系统(一个web前端展示系统,主要用于权限控制),可以采用java防盗链的方式来实现页面权限。
浏览器中直接输入报表URL的时候,它的头文件是空的,因此,可以在访问的时候做两个判断:头文件是否为空以及以什么页面进行跳转,如果不符合跳到错误页面即可。
什么是Referer?
这里...
阅读全文
1. 环境搭建
1.1 环境准备
首先确认HANA Studio的环境是否允许工程进行NewFile的操作,不行的话要考虑更新Studio的版本。
HANAStudio需要依赖Java jdk1.6或者1.7的版本
1.2 操作步骤
需要获取到SYSTEM账号的权限,在SYSTEM权限下进行操作
Adda System
填写正确的主机名(如IP地址)和HANA的instance number(询问管理员获得)
填写账号名和密码,点击finish
Create repository
点击Repositories页签,Create repository Workspace
新建一个Package或者选择一个原有的Package
如下图,右键->New->Repository Package 新建Package,再弹出的页面输入包名即可创建
New file XMLASrvDef.xsxmla
在新建的包下新建文件XMLASrvDef.xsxmla
编辑文件,输入service{*},点击激活按钮,如下图:
激活后的文件状态发生改变
Newfile .xsapp
同理,新建文件.xsapp,不需要输入内容,点击激活按钮
Newfile . xsprivileges
代码:
{"privileges":
[{"name":"SYSTEM","description":"Administrationprivilege"}]
}
同理,新建文件. xsprivileges,编辑文件,输入代码如下:点击激活按钮
New file .xsaccess
同理,新建文件. xsaccess,编辑文件,输入代码如下:
{
"exposed" : true,
"authorization" :["test::SYSTEM"]
}
点击激活按钮
Newfile test.html
用于测试环境是否新建成功,同理编辑文件,点击激活按钮
配置必要的权限
Analytic Privileges中添加_SYS_BI_CP_ALL
Application Privileges中添加test::SYSTEM
1.3 测试连接
确保HANA 环境中至少存在一个Analytic view,假如没有,需要自己新建用于测试
打开浏览器,输入地址,测试连接
地址的格式:http://hostname:80[instance number]/test/XMLASrvDef.xsxmla
输入用户名和密码结果返回404,说明服务器接到了请求,给出了响应
保险起见,可以输入http://hostname:80[instance number]/test/test.html
如果看到上图,说明服务已经开启
2.新建XMLA数据连接
点击服务器>定义数据连接,新建一个XMLA数据连接,数据库类型选择SAP HANA,填写url与账号密码,选择Catalog,测试连接,连接成功即可
3. FAQ
3.1
假如以上权限配置好后仍旧出现问题,尝试配置如下权限Granted Roles中添加
sap.hana.uis.db::SITE_DESIGNER: to designapplication sites
sap.hana.uis.db::SITE_USER: to useapplication sites
sap.hana.xs.lm.roles::Administrator
sap.hana.xs.ide.roles::EditorDeveloper
Object privileges中添加
GRANT_ACTIVATED_ROLE
3.2 环境搭建中遇到的问题
1.Serverreturned HTTP response code: 403 for URL
可能是(1)用户名密码错误 (2)用户权限没有配置好 (3)新建的文件如privileges没有激活,需要检查
2.Serverreturned HTTP response code: Connection refused: connect
可能是设计器中填写的url有问题,检查ip地址,检查端口号,检查xsxmla文件所在的路径是否输入正确
3.新建的文件激活时遇到问题
请联系SAP管理员
3.3 jdbc连接hana的注意点
图中的SQL验证查询是必填的选项,这个sql的获取,可以通过以下途径
打开HANAStudio,随便预览一个数据源,点击右上角的show log可以查看历史查询的SQL语句,把语句拿过来复制粘贴到此处即可
摘要: 文件输出的多样性,准确性和稳定性对于我们常用的报表软件来说很重要。报表的输入是指从报表的模板文件(XML格式的)创建WorkBook对象,输出则指将报表保存为各种格式文件,比如Pdf、Excel、Word这种常见的文件格式,比如FineReport还支持cpt、Svg、Csv、Image(包含png、 jpg、gif、 bmp、wbmp)等多种文件格式。
...
阅读全文
摘要: 数据库保存的是阳历日期,有时候会遇到把阳历换成阴历的需求,在报表开发过程中,可以首先定义一个可以将阳历转为阴历的类,然后自定义FineReport函数,在run方法中获取年月日参数并调用之前的类将阳历转为阴历,最终返回给报表。
阅读全文
摘要: 很多人在开发报表的时候会遇到将多张表样相同的excel导入到模板,然后提交至数据库中。但问题是很多情况,在线导入不支持一次性选择多个excel,一次只能选择一个excel,也不能将多个excel中的数据在不提交入库的前提下导入到模板中,即如果在导入excel之前,web页面里面有数据,导入excel之后会覆盖之前的数据.这样的问题可以利用FineReport自定义一个excel导入按钮来解决
阅读全文