WPF+springMVC实现动态SQL报表

4 篇文章 0 订阅

背景:项目运行过程中,时不时要加一些查询报表供用户使用,但是每次开发一个新报表,客户端页面和后端功能就要重写一套,90%的工作都是重复的,所以想着做一套基于sql配置的动态查询报表,新增新报表的时候只需要在后台加一条配置,前端就可以动态解析相关字段,执行sql查询并展示给用户。

报表配置模块

服务端就是一个普通的springMVC程序,新增一个报表配置模块

  1. 报表配置模块实体类
public class ReportConfigDto implements Serializable{
    /**
     * 报表编号
     */
    private String code;
    /**
     * 报表名称
     */
    private String name;
    /**
     * 表头字段
     */
    private String header;
    /**
     * 报表业务分类(相当于分组)
     */
    private String businessType;
    /**
     * 报表说明和介绍
     */
    private String remark;
    /**
     * 表头字典
     */
    private String headerCategory;
    /**
     * 表头展示名称
     */
    private String displayName;
    /**
     * 查询条件
     */
    private String queryCondition;
    /**
     * 查询条件类型
     */
    private String queryType;
    /**
     * 查询时该条件是否必须不为空
     */
    private String queryRequired;
    /**
     * 查询模式 (=、<=、>=、allLike、leftLike、rightLike等)
     */
    private String queryPattern;
    /**
     * 查询sql,如果多表联查,可以在查询语句外面套一层select语句来对应表头别名
     */
    private String querySql;
  1. 报表配置模块表
CREATE TABLE `report_config` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `code` varchar(50) NOT NULL COMMENT '报表编码',
  `name` varchar(100) NOT NULL COMMENT '报表名称',
  `header` varchar(255) NOT NULL COMMENT '表头',
  `header_category` varchar(1000) DEFAULT NULL COMMENT '表头字典(字段名1{key1:value1,key2:value2};字段名2{key1:value1,key2:value2})',
  `display_name` varchar(255) NOT NULL COMMENT '表头名称',
  `query_condition` varchar(1000) DEFAULT NULL COMMENT '查询条件(地图@SelectMapControl;文本框@TextBox;下拉框@ComboBox;日期@Date)',
  `query_required` varchar(1000) DEFAULT NULL COMMENT '查询条件是否必填验证(字段名1@true;字段名2@false)',
  `query_type` varchar(1000) DEFAULT NULL COMMENT '查询条件字段类型(字段名1@number;@字段名2@string)',
  `query_pattern` varchar(1000) DEFAULT NULL COMMENT '查询模式(字段名1@=;字段名2@>=;字段名3@allLike;字段名4@leftLike;字段名5@rightLike)',
  `query_sql` varchar(5000) DEFAULT NULL COMMENT '查询sql(开头不带select)',
  `is_delete` tinyint(1) NOT NULL DEFAULT '0' COMMENT '删除标记',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  `update_time` datetime NOT NULL COMMENT '更新时间',
  `create_user` varchar(50) NOT NULL COMMENT '创建人',
  `update_user` varchar(50) NOT NULL COMMENT '更新人',
  `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '时间戳',
  `load_search` tinyint(1) NOT NULL COMMENT '打开报表时是否立即查询(0:否,1:是)',
  `remark` varchar(500) NOT NULL COMMENT '报表说明',
  `business_type` varchar(100) NOT NULL COMMENT '业务分类',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_updateTime` (`update_time`) USING BTREE,
  KEY `idx_code` (`code`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='自定义报表配置';

-- 参考示例
INSERT INTO ws_report_config (code, name, header, header_category, display_name, query_condition, query_required, query_type, query_pattern, query_sql, area_no, is_delete, create_time, update_time, create_user, update_user, ts, load_search, remark, business_type) VALUES('workTotalNum', '近30天生产量统计', 'dates;tp;totalqty', 'tp{Pick:出库,Putaway:入库,Review:盘点}', '日期;业务类型;数量', 'tp@ComboBox', NULL, 'tp@string', 'tp@=', 'date_format(t.create_time ,''%Y-%m-%d'' ) dates,t.tp,sum(t.real_qty) totalqty
from (select r.create_time,m.milestone_type tp,r.real_qty 
from ws_job_r r left join ws_job_m m
on r.milestone_no = m.milestone_no
where m.milestone_type in(''Pick'',''Review'',''Putaway'',''Tally'')
and r.create_time >= DATE_SUB(NOW(), INTERVAL 30 DAY)) t
where 1 = 1 <conditions>
group by dates,t.tp order by dates desc',  0, '2021-11-17 00:00:00.0', '2021-11-17 00:00:00.0', 'admin', 'admin', '2021-11-18 11:50:07.0', 1, '', '工作量统计');
  1. 前端界面(每个报表配置,操作列提供一个按钮,点击按钮即执行报表查询,渲染新的报表页面)
    在这里插入图片描述

动态报表查询模块

  1. 检索按钮点击事件,根据报表配置id查询到报表配置对象,跳转到动态报表界面
  2. 动态报表界面主要代码如下
public partial class SqlReport : UserControl {
        private int loadNum = 0; //防止重复加载
        public ReportConfigDto reportConfig; //报表配置信息,前个页面传入
        public Dictionary<string, string> headerDic = new Dictionary<string, string>(); //字段名和显示名称的字典
        public Dictionary<string, string> queryConditionDic = new Dictionary<string, string>(); //查询条件的字典
        public Dictionary<string, string> queryTypeDic = new Dictionary<string, string>(); //查询条件字段类型字典
        public Dictionary<string, string> queryPatternDic = new Dictionary<string, string>(); //查询条件模式字典(全等、左等、右等...)
        public Dictionary<string, bool> queryRequiedDic = new Dictionary<string, bool>(); //查询条件是否必填校验字典

        public Dictionary<string, Dictionary<string, string>> headerCategoryDic =
            new Dictionary<string, Dictionary<string, string>>(); //枚举值的字典

        public Dictionary<string, SqlReportMeta> metaDic = new Dictionary<string, SqlReportMeta>(); //全部查询条件集合
        public DataTable tableData = new DataTable();


        private List<PageColumns> pcs = new List<PageColumns>();

        private BackgroundWorker queryMonitorWorker;

        /// <summary>
        /// 查询条件
        /// </summary>
        public static string queryCondition = "";

        public SqlReport() {
            InitializeComponent();
            AddHandler(PageControl.PageRoutedEvent, new RoutedEventHandler(PageRoutedHandler));

            queryMonitorWorker = new BackgroundWorker();
            queryMonitorWorker.WorkerSupportsCancellation =
                true; // 表示BackgroundWorker是否支持异步取消。当该属性设置为true时,可以调用异步方法CancelAsync来取消异步操作
            queryMonitorWorker.DoWork += QueryMonitor_AsyDoWork;
            queryMonitorWorker.RunWorkerCompleted += QueryMonitor_Completed;
            this.Loaded += (o, e) => {
                if (loadNum == 0) {
                    SqlReport_Load(o, e);
                }
            };
        }

        /// <summary>
        /// 页面加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SqlReport_Load(object sender, RoutedEventArgs e) {
            loadNum = 1;
            try {
                if (User.CurrentUser == null) {
                    throw new UserMessage("当前用户不能为空!请重新登录");
                }

                //查询所有的日期选择框,设置默认值
                foreach (var datePicker in this.queryConditionsPanel.FindChildren<DatePicker>()) {
                    string date = datePicker.Text.Trim();
                    if (string.Equals(date, Constant.INITTIME)) {
                        datePicker.Text = DateTime.Now.ToString("yyyy-MM-dd");
                    }
                }

                initReportMeta(); //构建查询条件
                initColumn(); //初始化表头
                this.pcCon.SetColumnHeader(pcs);
                this.pcCon.IsShowLoading = true; //加载
                this.pcCon.LoadingMsg = "加载中……"; //加载信息  默认:正在加载…
                this.pcCon.SelectionUnitType(DataGridSelectionUnit.Cell);
                if (reportConfig.loadSearch == 1) {
                    btnSearch_Click(null, null);
                }
            } catch (UserMessage um) {
                MsgHelper.ShowMessage(this.txtMsg, um.Message, 0);
            }
        }

        private void initColumn() {
            // foreach (var colNo in headerDic.Keys)
            // {
            //     DataColumn column = new DataColumn(colNo, typeof(string));
            //     tableData.Columns.Add(column);
            // }

            foreach (var header in headerDic) {
                pcs.Add(new PageColumns(header.Value, header.Key));
                DataColumn column = new DataColumn(header.Key, typeof(string));
                tableData.Columns.Add(column);
            }
        }


        /// <summary>
        /// 初始化报表元数据
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void initReportMeta() {
            if (string.IsNullOrEmpty(reportConfig.header) || string.IsNullOrEmpty(reportConfig.displayName)) {
                throw new UserMessage("报表表头信息配置有误,请联系研发处理!");
            }

            String[] headers = reportConfig.header.Split(';');
            String[] headerCategorys =
                reportConfig.headerCategory != null ? reportConfig.headerCategory.Split(';') : null;
            String[] displayNames = reportConfig.displayName != null ? reportConfig.displayName.Split(';') : null;
            String[] queryConditions =
                reportConfig.queryCondition != null ? reportConfig.queryCondition.Split(';') : null;
            String[] queryTypes = reportConfig.queryType != null ? reportConfig.queryType.Split(';') : null;
            String[] queryPatterns = reportConfig.queryPattern != null ? reportConfig.queryPattern.Split(';') : null;
            String[] queryRequireds = reportConfig.queryRequired != null ? reportConfig.queryRequired.Split(';') : null;

            if (headers.Length != displayNames.Length) {
                throw new UserMessage("报表配置有误,请联系研发处理!");
            }

            for (int i = 0; i < headers.Length; i++) {
                headerDic.Add(headers[i], displayNames[i]);
            }

            if (queryConditions != null && queryConditions.Length > 0) {
                foreach (var condition in queryConditions) {
                    if (!string.IsNullOrEmpty(condition)) {
                        string[] conditionKV = condition.Split('@');
                        if (string.IsNullOrEmpty(conditionKV[0]) || string.IsNullOrEmpty(conditionKV[1])) {
                            throw new UserMessage("queryCondition字段键值对配置有误");
                        }

                        queryConditionDic.Add(conditionKV[0], conditionKV[1]);
                    }
                }
            }

            //展示元素类型
            if (queryTypes != null && queryTypes.Length > 0) {
                foreach (var type in queryTypes) {
                    if (!string.IsNullOrEmpty(type)) {
                        string[] typeKV = type.Split('@');
                        if (string.IsNullOrEmpty(typeKV[0]) || string.IsNullOrEmpty(typeKV[1])) {
                            throw new UserMessage("queryType字段键值对配置有误");
                        }

                        queryTypeDic.Add(typeKV[0], typeKV[1]);
                    }
                }
            }

            //必填项
            if (queryRequireds != null && queryRequireds.Length > 0) {
                foreach (var req in queryRequireds) {
                    if (!string.IsNullOrEmpty(req)) {
                        string[] reqKV = req.Split('@');
                        if (string.IsNullOrEmpty(reqKV[0]) || string.IsNullOrEmpty(reqKV[1])) {
                            throw new UserMessage("queryRequired字段键值对配置有误");
                        }

                        queryRequiedDic.Add(reqKV[0], string.Equals(reqKV[1], "true"));
                    }
                }
            }

            //查询模式
            if (queryPatterns != null && queryPatterns.Length > 0) {
                foreach (var pattern in queryPatterns) {
                    if (!string.IsNullOrEmpty(pattern)) {
                        string[] patternKV = pattern.Split('@');
                        if (string.IsNullOrEmpty(patternKV[0]) || string.IsNullOrEmpty(patternKV[1])) {
                            throw new UserMessage("queryPattern字段键值对配置有误");
                        }

                        queryPatternDic.Add(patternKV[0], patternKV[1]);
                    }
                }
            }

            if (headerCategorys != null && headerCategorys.Length > 0) {
                foreach (var category in headerCategorys) {
                    if (!string.IsNullOrEmpty(category)) {
                        string key = category.Substring(0, category.IndexOf('{'));
                        int startIndex = category.IndexOf('{') + 1;
                        int endIndex = category.IndexOf('}');
                        string categoryString = category.Substring(startIndex, endIndex - startIndex);
                        string[] cateMap = categoryString.Split(',');
                        Dictionary<string, string> cateKVDic = new Dictionary<string, string>();
                        foreach (var cate in cateMap) {
                            string[] cateDetail = cate.Split(':');
                            cateKVDic.Add(cateDetail[0], cateDetail[1]);
                        }

                        headerCategoryDic.Add(key, cateKVDic);
                    }
                }
            }

            //创建查询条件
            if (queryConditionDic != null && queryConditionDic.Count > 0) {
                foreach (var query in queryConditionDic.Keys) {
                    //string code, string name, string type,string filedType,string pattern,bool? required, Dictionary<string, string> category
                    SqlReportMeta meta = new SqlReportMeta(query,
                        headerDic.ContainsKey(query) ? headerDic[query] : null,
                        queryConditionDic.ContainsKey(query) ? queryConditionDic[query] : null,
                        queryTypeDic.ContainsKey(query) ? queryTypeDic[query] : null,
                        queryPatternDic.ContainsKey(query) ? queryPatternDic[query] : null,
                        queryRequiedDic.ContainsKey(query) && queryRequiedDic[query],
                        headerCategoryDic.ContainsKey(query) ? headerCategoryDic[query] : null);
                    metaDic.Add(query, meta);
                    buildReportQueryConditions(meta);
                }
            }
        }

        /// <summary>
        /// 构建报表查询条件
        /// </summary>
        /// <param name="meta"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void buildReportQueryConditions(SqlReportMeta meta) {
            if (string.Equals(meta.type, SqlReportMetaType.TextBox)) {
                buildLabel(meta);
                TextBox textBox = new TextBox();
                textBox.Name = meta.code;
                textBox.Margin = new Thickness(0, 8, 0, 8);
                textBox.Style = this.FindResource("PageTBStyle") as Style;
                this.queryConditionsPanel.Children.Add(textBox);
            } else if (string.Equals(meta.type, SqlReportMetaType.ComboBox)) {
                buildLabel(meta);

                List<ComboBoxKVItem> items = new List<ComboBoxKVItem>();
                foreach (var cate in meta.category) {
                    items.Add(new ComboBoxKVItem(cate.Value, cate.Key));
                }

                ComboBox comboBox = new ComboBox();
                comboBox.ItemsSource = items;
                comboBox.Name = meta.code;
                comboBox.Margin = new Thickness(0, 10, 0, 10);
                comboBox.Width = 150;
                this.queryConditionsPanel.Children.Add(comboBox);
            } else if (string.Equals(meta.type, SqlReportMetaType.SelectMapControl)) {
                SelectMapControl mapControl = new SelectMapControl();
                mapControl.Name = meta.code;
                this.queryConditionsPanel.Children.Add(mapControl);
            } else if (string.Equals(meta.type, SqlReportMetaType.DatePicker)) {
                buildLabel(meta);
                //<DatePicker Style="{StaticResource PageDpStyle}"  SelectedDateFormat="Short"  x:Name="dpStartTime"/>
                DatePicker datePicker = new DatePicker();
                datePicker.Name = meta.code;
                datePicker.Style = this.FindResource("PageDpStyle") as Style;
                datePicker.SelectedDateFormat = DatePickerFormat.Short;
                this.queryConditionsPanel.Children.Add(datePicker);
            }
        }

        private void buildLabel(SqlReportMeta meta) {
            Label label = new Label();
            label.Content = meta.name + ":";
            label.Style = this.FindResource("PageLbStyle") as Style;
            label.Margin = new Thickness(8, 8, 0, 8);
            this.queryConditionsPanel.Children.Add(label);
        }

        /// <summary>
        /// 查询异步worker执行
        /// </summary>
        /// <param name="user"></param>
        private void QueryMonitor_AsyDoWork(object sender, DoWorkEventArgs e) {
            e.Result = SmartReportAssemble.querySqlReportCommonResult((ReportCommonQuery) e.Argument);
        }

        /// <summary>
        /// 报表数据返回
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void QueryMonitor_Completed(object sender, RunWorkerCompletedEventArgs e) {
            if (e.Error != null) {
                MsgHelper.ShowMessage(this.txtMsg, e.Error.Message, 0);
            } else if (e.Cancelled) {
                MsgHelper.ShowMessage(this.txtMsg, "请求操作已取消", 0);
            } else {
                PageInfo<dynamic> result = (PageInfo<dynamic>) e.Result;
                if (result != null) {
                    if (result.list == null || result.list.Count == 0) {
                        MsgHelper.ShowMessage(this.txtMsg, "查询结果为空", 1);
                    }

                    //清空数据表
                    clearTableData();

                    List<ReportCommonDto> resultList =
                        JsonConvert.DeserializeObject<List<ReportCommonDto>>(JSON.ToJSON(result.list));

                    foreach (var dto in resultList) {
                        DataRow row = tableData.NewRow();
                        foreach (var colNo in headerDic.Keys) {
                            object value = dto.ContainsKey(colNo) ? dto[colNo] : null;
                            if (headerCategoryDic.ContainsKey(colNo) && value != null) {
                                Dictionary<String, String> curCateDic = headerCategoryDic[colNo];
                                value = curCateDic.ContainsKey(value.ToString())
                                    ? curCateDic[value.ToString()]
                                    : value;
                            }

                            row[colNo] = value;
                        }

                        tableData.Rows.Add(row);
                    }

                    PageData page = new PageData();
                    page.Totals = result.total;
                    page.tableDatas = tableData;
                    this.pcCon.SetTableDatas(page);
                }
            }
        }

        private void clearTableData() {
            tableData.Clear();
            PageData page = new PageData();
            page.Totals = 0;
            page.tableDatas = null;
            this.pcCon.SetTableDatas(page);
        }

        /// <summary>
        /// 搜索
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSearch_Click(object sender, RoutedEventArgs e) {
            try {
                MsgHelper.HideMessage(this.txtMsg);
                QueryDone(1, this.pcCon.PageNum);
            } catch (UserMessage um) {
                MsgHelper.ShowMessage(this.txtMsg, um.Message, 0);
            } catch (Exception ex) {
                MsgHelper.ShowMessage(this.txtMsg, ex.Message, 0);
            }
        }

        /// <summary>
        /// 查询按钮触发操作
        /// </summary>
        /// <param name="pageNo"></param>
        /// <param name="pageNum"></param>
        private void QueryDone(int pageNo, int pageNum) {
            try {
                ReportCommonQuery query = new ReportCommonQuery();
                query.orgNo = User.CurrentUser.orgNo;
                query.distributeNo = User.CurrentUser.distributeNo;
                query.warehouseNo = User.CurrentUser.warehouseNo;
                query.mapAreaId = GetMapAreaNo();

                query.reportCode = reportConfig.code; //报表编号
                query.pageSize = pageNum;
                query.pageNum = pageNo;
                buildQueryParams(query);
                if (!queryMonitorWorker.IsBusy) {
                    queryMonitorWorker.RunWorkerAsync(query);
                }
            } catch (UserMessage um) {
                throw um;
            } catch (Exception ex) {
                throw ex;
            }
        }

        /// <summary>
        ///构建查询参数
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        private void buildQueryParams(ReportCommonQuery query) {
            foreach (var element in this.queryConditionsPanel.Children) {
                if (string.Equals(element.GetType().Name, SqlReportMetaType.TextBox)) {
                    TextBox t = element as TextBox;

                    if (queryConditionDic.ContainsKey(t.Name)) {
                        if (t.Text.Contains(";")) {
                            throw new UserMessage("查询条件中不允许包含特殊字符");
                        }

                        string param = t.Name;
                        if (queryRequiedDic.ContainsKey(t.Name) &&
                            queryRequiedDic[t.Name] &&
                            (string.IsNullOrEmpty(t.Text) || string.IsNullOrWhiteSpace(t.Text))) {
                            throw new UserMessage("[" + headerDic[t.Name] + "]不能为空");
                        }

                        //字符串查询条件
                        if (queryTypeDic.ContainsKey(t.Name) &&
                            string.Equals(queryTypeDic[t.Name], SqlReportMetaType.META_TYPE_STRING)) {
                            if (queryPatternDic.ContainsKey(t.Name)) {
                                switch (queryPatternDic[t.Name]) {
                                    case SqlReportMetaType.PATTERN_ALL_LIKE:
                                        param += " like '%" + t.Text.Trim() + "%'";
                                        break;
                                    case SqlReportMetaType.PATTERN_LEFT_LIKE:
                                        param += " like '%" + t.Text.Trim() + "'";
                                        break;
                                    case SqlReportMetaType.PATTERN_RIGHT_LIKE:
                                        param += " like '" + t.Text.Trim() + "%'";
                                        break;
                                    default:
                                        param += " = '" + t.Text.Trim() + "'";
                                        break;
                                }
                            } else {
                                param += " = '" + t.Text.Trim() + "'";
                            }
                        } else {
                            param += " " + queryPatternDic[t.Name] + t.Text + " ";
                        }

                        if (!string.IsNullOrEmpty(t.Text) && !string.IsNullOrWhiteSpace(t.Text)) {
                            query.queryParams += param + ";";
                        }
                    }
                } else if (string.Equals(element.GetType().Name, SqlReportMetaType.ComboBox)) {
                    ComboBox c = element as ComboBox;

                    if (queryConditionDic.ContainsKey(c.Name)) {
                        //字典查询条件只支持全等查询
                        ComboBoxKVItem item = c.SelectionBoxItem as ComboBoxKVItem;
                        if (item != null) {
                            string param = c.Name + " = '" + item.Value + "';";
                            query.queryParams += param;
                        }
                    }
                } else if (string.Equals(element.GetType().Name, SqlReportMetaType.SelectMapControl)) {
                    SelectMapControl m = element as SelectMapControl;
                    long? mapAreaNo = m.GetMapAreaNo();
                    if (mapAreaNo != null) {
                        string param = m.Name + " = " + mapAreaNo + ";";
                        query.queryParams += param;
                    }
                } else if (string.Equals(element.GetType().Name, SqlReportMetaType.DatePicker)) {
                    DatePicker d = element as DatePicker;

                    string param = d.Name;
                    if (queryRequiedDic.ContainsKey(d.Name) &&
                        queryRequiedDic[d.Name] &&
                        (string.IsNullOrEmpty(d.Text) || string.IsNullOrWhiteSpace(d.Text))) {
                        throw new UserMessage("[" + headerDic[d.Name] + "]不能为空");
                    }

                    if (queryPatternDic.ContainsKey(d.Name)) {
                        param += " " + queryPatternDic[d.Name] + " ";
                    } else {
                        param += " = ";
                    }

                    param += "'" + d.Text.Trim() + "'";
                    query.queryParams += param;
                }
            }
        }

        /// <summary>
        /// 分页回调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PageRoutedHandler(object sender, RoutedEventArgs e) {
            try {
                PageRouteEventArgs args = e as PageRouteEventArgs;
                if (args.EventType == PageRouteEventArgs.EventEnum.manager) {
                    QueryDone(args.PageNo, args.PageNum);
                }
            } catch (UserMessage um) {
                MsgHelper.ShowMessage(this.txtMsg, um.Message, 0);
            } catch (Exception ex) {
                MsgHelper.ShowMessage(this.txtMsg, ex.Message, 0);
            }
        }

    }
  1. 报表查询后台主要代码如下:
public BaseResponse querySqlReportCommonResult(ReportCommonRequest query) {
    String executeSql = null;
    try {
        AssertHelper.notNull(query);
        AssertHelper.notNull(query.reportCode);

        ReportConfigRequest configRequest = new ReportConfigRequest();
        BeanHelper.copyProperties(query,configRequest);
        configRequest.setCode(query.reportCode);
        List<ReportConfigDto> configDtos = reportConfigManager.listReportConfig(configRequest);
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        PageInfo<ReportCommonDto> pageInfo = new PageInfo<>();
        if (CollectionUtils.isNotEmpty(configDtos)) {
            String querySql = configDtos.get(0).getQuerySql();
            //如果前台传入的查询条件不为空,就开始构建查询条件拼接到sql后面
            if (StringUtils.isNotBlank(query.queryParams)) {
                String appendConditions = "";
                String[] params = query.queryParams.split(";");
                for (String paramExp : params) {
                    if (StringUtils.isNotBlank(paramExp)) {
                        appendConditions += " and " + paramExp;
                    }
                }
                querySql = StringUtils.replace(querySql,"<conditions>",appendConditions);
            } else {
                querySql = StringUtils.replace(querySql,"<conditions>","");
            }
            executeSql = querySql;
            query.setQuerySql(executeSql);
            List<ReportCommonDto> result = reportConfigManager.querySqlReportCommonResult(query);
            pageInfo = new PageInfo<>(result);
        } else if (CollectionUtils.size(configDtos) > 1) {
            return RpServiceAssist.fail(BaseResponse.class, MessageConst.SERVICE_ERROR_CODE, "查询到编号为" + query.reportCode + "的多个报表,请联系管理员处理");
        }
        return RpServiceAssist.ok(BaseResponse.class, pageInfo);
    } catch (Exception ex) {
        logger.error("查询sql报表配置:{}异常,执行SQL为:{},详细错误信息:{}" , JsonHelper.toJson(query),executeSql,ex);
        return RpServiceAssist.fail(BaseResponse.class, MessageConst.SERVICE_ERROR_CODE, "报表查询异常,请联系管理员处理");
    }
}
  1. 枚举类(界面元素渲染支持文本框,下拉框,日期选择框)
public class SqlReportMetaType
{
	// 元素渲染类型
    public const string TextBox = "TextBox";
    public const string ComboBox = "ComboBox";
    public const string DatePicker = "DatePicker";

	//元数据类型
    public const string META_TYPE_STRING = "string";
    public const string META_TYPE_NUMBER = "number";
	
	//模糊查询匹配模式
    public const string PATTERN_ALL_LIKE = "allLike";
    public const string PATTERN_LEFT_LIKE = "leftLike";
    public const string PATTERN_RIGHT_LIKE = "rightLike";
}
  1. 查询效果如下
    在这里插入图片描述

总结

以上代码不是完整代码,但是核心代码已经全部贴出来了,主要关键点在于点检索按钮时对报表的配置项的解析,以及查询结果表格的动态列生成。以上仅供参考。
注:这个SQL报表没有过多考虑针对SQL注入的防护问题,因为前端触发sql查询的时候是从后台取的SQL语句,如果对安全规范要求很高的话,需要针对最终执行的SQL做一些关键词的过滤。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值