JsReport报表
Steedos 与 jsreport 集成,开发人员可以使用Html和Javascript编写复杂样式的报表。
报表查看界面
业务人员在报表模块中选中对应的报表,即可进入报表查看界面。
数据权限
Steedos中的报表数据均通过统一的OData接口传递给报表服务器,自动加上权限过滤的功能,报表中只会显示当前用户被授权访问的数据。
数据筛选
如果需要进行明细统计,业务人员还可以借助Steedos的筛选器功能,对统计数据进行进一步筛选,并查看筛选之后的统计报表。
报表设计工具
开发人员可以使用报表设计工具,编辑模拟数据,调整报表样式,并实时预览报表的显示效果。
报表参数
报表名称 name
报表的显示名称
name: 合同年度统计表
报表数据源 data_source
目前只能使用OData作为报表数据源。
data_source: odata
对象名 object_name
定义报表需要查询的主对象名。
object_name: contracts
字段 fields
定义报表需要查询的字段。
fields:
- name
- amount
- contract_type
查询条件 filters
定义使用OData查询报表数据的过滤条件。
filters: ["contract_type", "=", "技术合同"]
报表显示模版
使用Html文件,编写报表的排版样式。模版对应的后缀名为 .report.html
报表脚本
使用Javascript定义报表中用到的帮助函数。帮助脚本对应的后缀名为 .helper.js
//定义一个加法函数,以解决金额相加精度问题
function add(){
var args = arguments,//获取所有的参数
lens = args.length,//获取参数的长度
d = 0,//定义小数位的初始长度,默认为整数,即小数位为0
sum = 0;//定义sum来接收所有数据的和
//循环所有的参数
for(var key in args){//遍历所有的参数
//把数字转为字符串
var str = ""+args[key];
if(str.indexOf(".")!=-1){//判断数字是否为小数
//获取小数位的长度
var temp = str.split(".")[1].length;
//比较此数的小数位与原小数位的长度,取小数位较长的存储到d中
d = d < temp ? temp : d;
}
}
//计算需要乘的数值
var m = Math.pow(10,d);
//遍历所有参数并相加
for(var key1 in args){
sum += args[key1]*m;
}
//返回结果
return sum/m;
}
function deci(num, v) {
/*
十进制浮点数转换,
num表示要四舍五入的数,
v表示要保留的小数位数。
*/
var vv = Math.pow(10, v);
return Math.round(num * vv) / vv;
}
// getContractTypes中排它性的id值,该分类指其他分类以外的所有分类
var otherContractTypeId = "--other--";
function getContractTypes() {
return [{
"_id": "7CbxwqzjkkHrtFNeH",
"name": "租赁合同"
},{
"_id": "c3mTcfHGZ3nCRmyzq",
"name": "承揽合同"
},{
"_id": "GrKZCAPHYm5v5gLqh",
"name": "建设工程合同"
},{
"_id": "ntpWE3a27Mm64YApM",
"name": "技术合同"
},{
"_id": "z32TeRg5ZpkSNzdyc",
"name": "买卖合同"
},{
"_id": "EFgyJM52j5MLgY3pt",
"name": "劳务合同"
},{
"_id": "ngLXGLJAKsxHGbKNo",
"name": "港口作业合同"
},{
"_id": otherContractTypeId,
"name": "其他合同"
}]
}
function getContractTags() {
return [{
"name": "已履行的合同",
"key": "finished",
"property": "contract_state",
"value": "完毕"
},{
"name": "尚在履行的合同",
"key": "pending",
"property": "contract_state",
"value": "进行中"
},{
"name": "违约但继续履行的合同",
"key": "continue",
"property": "contract_state",
"value": "违约但继续履行"
},{
"name": "解除的合同",
"key": "cancel",
"property": "contract_state",
"value": "解除"
},{
"name": "关联交易合同",
"key": "connected",
"property": "is_connected_transaction",
"value": "是"
}]
}
function geTotalTags() {
return [{
"name": "重大合同",
"key": "important",
"property": "is_important",
"value": "是"
},{
"name": "招标合同",
"key": "bidding",
"property": "is_bidding",
"value": "是"
},{
"name": "固定资产合同",
"key": "solid_investment",
"property": "is_solid_investment",
"value": "是"
}]
}
function beforeRender(req, res, done) {
var contractTypes = getContractTypes();
var contracts = req.data.contracts;
let result = {};
var contractTags = getContractTags();
result.contractTypes = {};
contractTypes.forEach(function(item){
result.contractTypes[item._id] = {
name: item.name
}
result.contractTypes[item._id].tags = {};
contractTags.forEach(function(tagItem){
result.contractTypes[item._id].tags[tagItem.key] = {
name: tagItem.name,
count: 0,
sum: 0
}
});
});
var totalTags = geTotalTags();
result.tags = {};
totalTags.forEach(function(tagItem){
result.tags[tagItem.key] = {
name: tagItem.name,
count: 0,
sum: 0
}
});
result.total = {
name: "总合同",
count: 0,
sum: 0
}
contracts.forEach(function(record){
result.total.count++;
result.total.sum = add(result.total.sum, record.amount);
totalTags.forEach(function(tagItem){
if(record[tagItem.property] === tagItem.value){
result.tags[tagItem.key].count++;
result.tags[tagItem.key].sum = add(result.tags[tagItem.key].sum, record.amount);
}
});
var recordContractType = record.contract_type;
if(recordContractType){
var resultContractType = result.contractTypes[recordContractType._id];
if(!resultContractType){
resultContractType = result.contractTypes[otherContractTypeId];
}
contractTags.forEach(function(tagItem){
if(record[tagItem.property] === tagItem.value){
resultContractType.tags[tagItem.key].count++;
resultContractType.tags[tagItem.key].sum = add(resultContractType.tags[tagItem.key].sum, record.amount);
}
});
}
});
req.data = Object.assign({}, req.data, {
report_name: "测试合同",
contractTypes: contractTypes,
result: result
});
delete req.data.contracts;
done();
}