报表数据存储结构说明,适用于二次开发或学习
金蝶云社区-duo_qian
duo_qian
5人赞赏了该文章 6379次浏览 未经作者许可,禁止转载编辑于2015年07月22日 10:14:52

报表数据存储结构说明,使用二次开发或学习
一、数据存储逻辑
1、 报表保存:
1) 只要是合并报表模块的报表(个别报表、汇总报表、工作底稿、合并报表)都保存在T_CSL_CSLREPORT表中,表中包含公司、币别、报表类型、期间类型、年、期、二进制BOOK文件等信息。
2) 报表系统编制的报表如是用于集团上报的报表,将自动保存一份数据到合并报表系统中的表T_CSL_CSLREPORT中,两条记录几乎是一样的,包括审批、上报等状态,如报表系统进行删除那么两边的数据都将删除掉,报表系统与合并报表系统的唯一差别是,合并报表系统的报表会进行项目数据保存(用于数据合并),而报表系统则不进行项目数据保存,因为是2份相同的数据,无需在保存一份,报表系统保存的报表物理表:T_RPT_REPORT,该表的字段FCSLREPORTID指向合并报表系统的报表。
3)
2、 报表项目数据保存(目前按表页类型进行分类存储到不同的后台表):
1) 存储项目数据条件:单元格中必须存在项目公式,对于填充类报表存在基准点的保存是依据基准点所在行的项目公式为维度进行保存,保存范围为基准点的填充行、列范围。
2) 报表表页类型分类(固定表):
a) 普通报表(存储比较复杂,下面给出例子),涉及后台表:t_csl_cslreport,T_CSL_RPTReceived,t_csl_itemdata,t_csl_itemdataentry,t_csl_itemdataEntry001,itemdataEntryXXX(根据报表项目多少映射到不同的entry表),t_csl_rptitem,t_csl_DataElement。
b) 往来抵销报表,涉及后台表:T_CSL_InterItemData,该表字段Freport与t_csl_cslreport进行关联,该表存在本方公司、对方公司、年、期等信息,主要是往来核对的数据来源。
c) 交易抵销报表,涉及后台表:T_CSL_ExchItemData,该表字段Freport与t_csl_cslreport进行关联,该表存在本方公司、对方公司、年、期等信息,主要是交易核对的数据来源。
d) 权益抵销报表、权益抵销报表(新),涉及后台表:T_CSL_InvestItemData,该表字段Freport与t_csl_cslreport进行关联,该表存在本方公司、对方公司、年、期等信息,主要是权益的数据来源。
3) 动态罗列报表:
a) 根据罗列区域行列范围进行保存项目数据。
b) 涉及后台表:T_CSL_DynaItemData,该表字段Freport与t_csl_cslreport进行关联,该表存在本方公司、对方公司、年、期等信息。
3、 表间关系:
a) 报表系统与合并报表:表T_CSL_Report -->字段FcslReportID –>关联表T_CSL_CSLReport
b) 合并报表与报表接收记录及合并范围:表T_CSL_RPTReceived-->字段FreportID-->关联表T_CSL_CSLReport。(报表接收记录T_CSL_RPTReceived在保存上报报表时根据该报表的模板分配记录而生成,如果是一表多报的情况,该记录就存在多个记录);
表T_CSL_RPTReceived-->字段FORGTreeID-->关联T_ORG_Tree(合并范围)字段FID。(T_CSL_RPTReceived中字段FreportID、FORGTreeID确认唯一性)
c) 表T_CSL_ItemData-->字段Frportid-->关联表T_CSL_CSLReport字段FID,表T_CSL_ItemData保存信息与T_CSL_CSLReport相似,形成一对一关系。
d) 表T_CSL_ItemDataEntry-->字段FItemDataID -->关联表T_CSL_ItemData字段ID,T_CSL_ItemDataEntry该表以年、期、取数类型、值类型为维度,将映射到不同的T_CSL_ItemDataEntryXXX表中的具体数据中
e) 表T_CSL_ItemDataEntryXXX(XXX代表具体的001开始的数值,如T_CSL_ItemDataEntry001)-->字段FID关联表T_CSL_ItemDataEntry字段FID,T_CSL_ItemDataEntryXXX中保存具体的报表的项目数据。
f) 表T_CSL_ItemFieldMapped-->字段FitemID-->关联表T_CSL_RPTItem(报表项目),新增报表项目时将映射该报表项目所涉及的数据保存的对应后台表及字段。
g) 表T_CSL_ItemDataEntry-->字段FdataElement-->关联表T_CSL_DataElement(取数类型)。
4、 获取某个单元格的项目数据举例(通过该举例了解报表存储结构):
1、项目公式
=Item("2001",0,0,"AMOUNT","MONEY")
2、获取报表项目的id
select fid from t_csl_rptitem where fnumber='2001' --c0746c51-00fd-1000-e000-29c1c0a8100d237A9505
3、获取取数类型内码
select finterseq from t_csl_dataelement where fnumber='AMOUNT' --2
4、通过报表项目id获取该报表项目的存储映射关系,存储表名,字段名
select Ftablename,FFieldName from t_csl_itemfieldmapped where fitemid='c0746c51-00fd-1000-e000-29c1c0a8100d237A9505'
5、通过报表id(注意是t_csl_cslreport下的报表id,如果是报表系统做的,需找到合并报表系统报表id)获取关联itemdata子表的外键即FID,该表里面包含币别、公司等信息
select * from t_csl_itemdata where freportid='FfIaegEYEADgEbRLCqgE+rcS6iw=' --15f21a7a-0118-1000-e011-b44e0aa804fa
6、通过上表查询FID获取该报表所对应的项目数据关系横表,该表以取数类型、值类型、年和期为维度,确认该单元格的唯一的一个FID值
select * from t_csl_itemdataentry where fitemdataid='15f21a7a-0118-1000-e011-b44e0aa804fa' and fvaluetype=1 and fdataelement = 2 and fyear = 2008 --15f21a7a-0118-1000-e011-b44f0aa804fa
7、通过步骤4获取的映射表名、字段名加上步骤6获取的ID值最终取得存储值。
select F68 from t_csl_itemdataentry001 where fid='15f21a7a-0118-1000-e011-b44f0aa804fa'
二、后台取数接口说明
 系统已有获取项目数据的接口类ItemDataProviderControllerBean,获取固定表项目数据方法,批量获取项目数据,不按照表来取数,protected Map _getAcctItems(Context ctx, ItemDataCondition condition) throws BOSException, EASBizException,参数
ItemDataCondition 定义获取的公司、年、期等信息设置,具体看类说明,或检索具体调用处定义。
 如果非集团下发模板做的报表(普通报表)或无项目公式ITEM,Ditem的单元格上面的数据都不会单独存储,这需要遍历单元格处理或
用一下方式批量或者报表中的单元格数据,代码示例如下:

byte[] data = reportInfo.getData(); //--通过ReportInfo对象获取字节流
//--通过Map构造KEY,KEY为表页名+感叹号+单元格名,最后调用框架接口BookIOUtil.loadSomeCellValues(data, map);一次性获取单元格数据,
//--数据都是key-value对应方式,拿到构造的Map即可进行数据加工。
HashMap map = new HashMap();
for (int i = 0; group != null && i < group.size(); i++) {
Ref ref = (Ref)group.get(i);
String cellRefName = ref.sheetName + "!" + ref.cellName;
map.put(cellRefName.toUpperCase(), null);//构造Map对象的KEY,
}
try {
BookIOUtil.loadSomeCellValues(data, map);//调用关键接口
} catch (Exception e) {
for (int i = 0; i < group.size(); i++) {
Ref ref = (Ref)group.get(i);
ref.formulaValue.setException(e);
}
continue;
}

 非存在项目公式的单元格获取方法:
1、获取报表对象,
1)如果是报表系统下的报表则通过:
ReportInfo reportInfo = ReportFactory.getRemoteInstance().getReportInfo(pk);//对应后台表t_rpt_report
2) 如果是合并报表下的报表(个别报表、合并报表、汇总表、工作底稿)则通过以下获取:
CslReportInfo cslReportInfo = CslReportFactory.getRemoteInstance().getCslReportInfo(pk);//对应表t_csl_cslreport
3)说明报表系统做的报表如果用于集团上报的,那么表t_rpt_report与表t_csl_cslreport存在一个外键关系,
即表t_rpt_report的FcslReportId与t_csl_cslreport的表FID对应。
2、获取单元格值
byte[] data = reportInfo.getData(); //--通过ReportInfo对象获取字节流
//--通过Map构造KEY,KEY为表页名+感叹号+单元格名,最后调用框架接口BookIOUtil.loadSomeCellValues(data, map);一次性获取单元格数据,
//--数据都是key-value对应方式,拿到构造的Map即可进行数据加工,该方法主要是离散单元格的数据获取比较方便。如果是一块区域的,可直接通过
//单元格迭代器获取整块数据进行处理。
//可以迭代报表的单元格构造KEY,或者已明确了表页名称和范围的,也可以直接构造KEY。
HashMap map = new HashMap();
Book book = reportInfo.getBook();
Sheet sheet = book.getSheet(sheetName);
//左上角单元格坐标与右下角单元格坐标,
ICellsIterator iterator = sheet.getCellsIterator(int row,int col, int row2, int col2,boolean bDescend,boolean forContentCell);
Cell cell;
while(iterator.hasNext()){
cell = iterator.next();
BigDecimal val = new BigDecimal(cell.getValue().toString());//这里假设是数值,开发时做下判断。
.....
}
//后续按需要处理