# 数据报表开发步骤

以数据加工为例，（该方式可以覆盖所有场景）

其余类似自行去开发者社区等处搜索资料进行研究

## 1 语义模型设计

位置: 动态建模平台 -> 报表平台 -> 语义模型 -> 语义模型-XX

## 2 自由报表设计

位置: 动态建模平台 -> 报表平台 -> 自由报表 -> 自由报表-XX

## 3 数据加工类开发

## 4 数据加工设计器中填写模板代码



# 报表数据加工类demo代码

数据加工接口

```java
import com.ufida.dataset.IContext;
import nc.pub.smart.data.DataSet;
import nc.vo.pub.BusinessException;

/**
 * 数据加工 培训接口
 * 这里常用得两种形式，采用一种即可
 * 1 返回数据sql的形式，常用作不太复杂的业务，计算较少，通过sql的连接求和等就能完成业务模型
 * 2 返回数据集的形式，常用做复杂业务的情况。跟语义模型中的【语义提供者->也叫做业务数据】类似
 */
public interface IDataProcessDemoReport {

    /**
     * 数据sql
     * @param context
     * @return
     * @throws BusinessException
     */
    String query(IContext context) throws BusinessException;

    /**
     * 返回数据集
     * @param context
     * @return
     * @throws BusinessException
     */
    DataSet queryData(IContext context) throws BusinessException;
}
```

数据加工实现类

```java

import com.ufida.dataset.IContext;
import com.ufida.report.anareport.FreeReportContextKey;
import com.ufida.report.anareport.base.BaseQueryCondition;
import nc.pub.smart.data.DataSet;
import nc.pub.smart.metadata.Field;
import nc.pub.smart.metadata.MetaData;
import nc.vo.pub.BusinessException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;

/**
 * 数据加工 服务实现
 */
public class DataProcessDemoReportImpl implements IDataProcessDemoReport {

    //数据模型字段，这里示例写了两个，自己可以按照自己的设计来
    String[] fields = new String[] {"code", "name"};

    /**
     *  返回DataSet 的模型
     *  我们需要代码构建一个元数据MetaData , 处理自己的业务数据返回一个二维数组
     *  然后将 MetaData和二维数组装到DataSet模型中，返回给前端进行渲染
     */
    @Override
    public DataSet queryData(IContext context) throws BusinessException {

        DataSet ds = null;
        //获取查询条件
        BaseQueryCondition basecon = (BaseQueryCondition) context
                .getAttribute(FreeReportContextKey.KEY_IQUERYCONDITION);
        //初始化元数据
        MetaData metadata = this.initMetaData();
        //条件判断,basecon中是前端传来的查询条件，需要从其中解析出查询条件，转为自己的查询VO，方便后续使用，这一步大家可以根据自己的想法进行设计实现
        //...todo

        //获取业务数据，根据自己的业务，自己设计结构，拿到一个二维数组。在这仅写了简单的构建二维数组数据。
        Object[][] businessData = getBusinessData();

        return new DataSet(metadata,businessData);

    }

    private Object[][] getBusinessData() {
        Collection<Object[]> dataSetList = new ArrayList(100);
        for(int i = 0 ; i < 100 ; i++){
            Object[] rowdata = new Object[fields.length]; //构造列
            //行数据
            for(int j = 0 ; j < fields.length ; j++){
                rowdata[j] = "测试数据" +fields[j]+ i;
            }
            dataSetList.add(rowdata);
        }

        return dataSetList.toArray(new Object[dataSetList.size() == 0 ? 1 : dataSetList.size()][]);
    }

    private MetaData initMetaData() {
        MetaData md = new MetaData();
        for(int i = 0 ; i < fields.length ; i++){
            md.addField(initStringMetaData(fields[i]));
        }
        return md;
    }

    private Field initStringMetaData(String fieldName) {
        Field filed = new Field();
        filed.setCaption("默认caption");
        filed.setDbColumnType(Types.VARCHAR);
        filed.setFldname(fieldName);
        filed.setPrecision(250);
        return filed;
    }
  

    @Override
    public String query(IContext context) throws BusinessException {

        StringBuffer buffer = new StringBuffer();

        buffer.append(" select code,name,itemcount,disproperty from bd_userdefrule left join bd_userdefitem bd_userdefitem on ");
        buffer.append(" bd_userdefitem.pk_userdefrule = bd_userdefrule.pk_userdefrule ");

        return buffer.toString();

    }

}
```



# 报表数据加工设计器demo代码

## 1 sql形式调用示例（放在语义模型设计器中）

```java
nc.pub.smart.context.SmartContext context = getContext();
String sql = nc.bs.framework.common.NCLocator.getInstance().lookup(你的数据加工接口全路径.class)
.query(context);
setResultSQL(sql);
```

## 2 数据集调用示例（放在语义模型设计器中）

```java
nc.pub.smart.context.SmartContext context = getContext();
DataSet ds = nc.bs.framework.common.NCLocator.getInstance().lookup(你的数据加工接口全路径.class)
.queryData(context);
setDataSet(ds);
```



# 报表前端界面扩展

## 报表前端扩展demo代码

```js
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { createPage, ajax } from 'nc-lightapp-front';
import { SimpleReport } from 'nc-report';
/**
 * 报表前端扩展demo
 */
class ReportExtendDemo extends Component {
    constructor(props) {
        super(props);
        this.state = {
          report: {
            showHighSearchBtn: true,
            setDefaultVal: this.setDefaultVal,
            clickAdvBtnEve: this.clickAdvBtnEve,
            onAfterEvent: this.onAfterEvent
          }
        }
    }
    //点击高级查询 回调事件
    clickAdvBtnEve = (props, searchId) => {
    }
    //tempedata 环境变量信息
    setDefaultVal = (searchId, props, islinkuse, tempedata) => {
    }
    //编辑后事件
    onAfterEvent = (props, searchId, field, val) => {
    }
    render() {
        return (
          <div className="table">
            <SimpleReport {...this.state.report}/>
          </div>
          
        );
    }
}
ReportTest = createPage({})(ReportTest);
ReactDOM.render(<ReportTest />, document.getElementById('app'));
```

## 配置文件 config.json

```js
{
	"report": true
}
```

## 扩展位置

在你的脚手架下面新建报表前端扩展demo代码，确保脚手架的src下面有lappreportrt的包，如果没有需要去home下去进行拷贝到脚手架下

lappreportrt的home 路径为:   home\hotwebs\nccloud\resources 下

## 页面路径位置

你的代码路径需要配置到应用注册处的页面路径处，可以参考已有节点的路径进行配置
