润乾自助报表 Copilot 实践
在报表项目中,业务开展过程中会不断产生新的查询统计需求,或者原有需求发生变化,导致报表不断增加或需要修改,这就造成了没完没了的报表。如果一直由技术人员来负责报表开发,会导致项目周期过长、成本难以控制,同时来回的业务沟通也会让报表的时效性变差,影响业务正常开展。为此,润乾推出了自助报表的 Copilot,业务人员可以通过汉语命令完成一系列报表开发操作。这样一来,一部分工作就可以由业务人员通过自助报表工具自己完成,技术人员只需负责数据处理和复杂报表的制作即可。在《AI 加持下的自助报表还能这么做!》一文中介绍了自助报表能够实现的效果,本文主要介绍如何在自己的应用集成它。
产品安装
产品下载与安装
产品直接在润乾官网下载就行,注意,这里要下载报表设计器与开源BI zip 安装包两个产品:

润乾报表核心程序及配置文件在设计器安装后产生的WEB 应用中,报表设计器根据操作系统不同分为多个版本,根据实际需要下载对应版本即可,这里以 windows 为例,下载 windows 版。自助报表相关文件在开源 BI zip 安装包中,也需要下载下来。
报表设计器解压缩后根据向导直接安装就行,设计器自带试用版授权,如需其他版本授权,可以在官网申请。【设计器安装根目录】\report\web\webapps 下的 demo 目录就是报表的 WEB 应用。
自助报表集成:将下载的开源BI zip 安装包(名字为 reportBI- 发布日期)解压缩,将解压缩后的 report\web\webapps 下的 demo 目录同级复制到设计器自带的 demo 目录中,粘贴时会提示 web.xml 文件重复,直接覆盖就可以,这时润乾报表应用集成完成。
集成部署
应用集成
润乾报表应用是标准的JAVA WEB 应用,可以独立部署也可以和用户自己的应用做无缝集成,如需无缝集成按照 JAVA 应用的标准集成方式操作就行,主要有两点:一,将除了应用根目录 /WEB-INF 下的 web.xml 外的其他文件,同目录合并(基本没有同名文件,注意下 WEB-INF/lib 下的 jar 包的版本号,一般保留高版本的就行)。二:将两个应用的 web.xml 中的内容合并,注意 listener、filter、servlet 等顺序要严格按照相关 WEB 服务器规定。
润乾自助报表所需文件目录结构如下:

如仅需集成本文中的自助报表,则只需要从设计器自带的demo 应用中获取上述文件集成,如项目中还有技术人员提前做好的复杂报表需求,那么集成 demo 自带的所有文件就行。
注:在帮助文档《程序员参考》的web 应用章节中介绍了 demo 应用发布目录中的所有文件目录结构及用途,如有需要可做进一步查阅。
应用部署
本文以报表单独部署方式为例,介绍下自助报表应用在Tomcat 下部署操作。在 Tomcat\webapps 下新建目录 report,然后将【设计器安装根目录】\report\web\webapps\demo 下的文件,复制到 Tomcat\webapps\report 目录中。
数据源配置
本文以Mysql 数据库为例,将 Mysql 的 jdbc 驱动复制到 Tomcat\lib 中(【设计器安装根目录】\common\jdbc 目录中自带了 Mysql 的驱动,也可以根据实际 Mysql 版本自行下载)。
用文本编辑器打开Tomcat\webapps\demo\WEB-INF 下的 raqsoftConfig.xml 文件,在 DBList 节点中增加连接 Mysql 数据库的配置信息,如:

这里可以同时配置多个数据源,按照格式添加就行(文件中自带了多个数据源的配置,可以在基础上直接修改,不需要的可以删除),name 的值为数据源名称,应用中会根据这个名称读取相关数据库连接配置。
raqsoftConfig.xml 的 Report 节点的 license 处可以设置授权文件,默认空表示使用试用授权,根据实际需要配置就行。
到此,应用部署完毕,可以执行Tomcat/bin 下的 startup.bat 启动应用了。
数据准备
在Mysql 数据库中,有订单表,数据结构如下:

现在要使用这些数据做订单统计报表,可以由技术人员提前设置好数据来源,业务人员直接使用准备好的数据做报表就可以了。自助报表的数据来源可以直接来自SQL 语句。更改自助报表页面(应用根目录 \raqsoft\guide\jsp\olap.jsp),用文本编辑器打开,找到并修改此处:
String sqlId = request.getParameter("sqlId");
if (sqlId == null) sqlId = "sqlId1";
String dataSource = request.getParameter("dataSource");
if (dataSource == null) dataSource = "mysql";
String ql = request.getParameter("ql");
if (ql == null) ql = "select * from 订单表 where ${SQL_CONTROL_WHERE_"+sqlId+"}";
session.setAttribute("SQL_CONTROL_WHERE_"+sqlId,"雇员 ID=1");
sqlId 是 sql 的编号,可以从 url 上获取,该值不能为空,可以在这里设置默认值。
dataSource 是数据源名称,这里设置默认值 mysql,就是在 raqsoftConfig.xml 里配置的数据源名称,报表支持多数据源,可以通过该参数进行切换。
ql 是传入报表的 SQL 语句,可以获取 URL 上传入的 SQL 实现动态取数,这里先用一个固定的,注意 SQL 语句后边带了 where 条件,SQL_CONTROL_WHERE_+sqlId 这里是条件替换的关键字,可以通过这个关键字进行条件值的替换,主要用于数据权限控制。
session.setAttribute,是通过 where 条件的关键字,将具体条件值替换到 SQL 语句中,这里设置表示取雇员 ID=1 的数据,实际应用中,这里根据实际需求做条件拼接,然后放到 session 里就行。这样不同人访问页面,看到的数据不同,实现了数据权限控制的功能,如果取全量数据,这里设置个 1=1 就行。
在olap.jsp 的下半部分:

这块是控制将SQL 语句传入自助报表,sqlDatasets 变量声明这块默认是注释状态,这里要按照截图中更改下就行,这样自助报表的数据来源就变成了前边传入的 SQL 语句。
字典配置
订单表中的运货商字段存储的是代码值形式,展示时需要转换成相应的中文,要进行码表设置,这个可以在SQL 语句中通过 join 取字典表中的中文字段,也可以在 dimData.json(应用根目录\WEB-INF\files\data\temp)中增加对应配置,如数据库中有字典表运货商,数据结构如下:

实际项目中码表可能只是个list 数组,并不在数据库中,所以这里主要说明下 dimData.json 中的设置,在 dimData.json 中增加如下数据:

其中运货商是订单表中需要转换成中文的字段名,数据行中的name 是显示值,real 是代码值,这是标准的 json 格式串,可以自己写程序生成,也可以借助润乾的 SPL 工具,通过一句代码就可以,如:=db.query("select 公司名称, 运货商 ID from 运货商").("{\"id\":"+string(1000000+#)+",\"pId\":0,\"name\":\""+ 公司名称 +"\",\"real\":"+string(运货商 ID)+",\"dim\":\" 运货商 \"}").concat(",")
自助报表使用
数据准备工作完成后,就可以启动应用,浏览器端访问http://localhost:8080/report/raqsoft/guide/jsp/olap.jsp 进入自助报表页面:

进入页面后,默认会以网格式报表展示数据,业务人员可以在此页面拖拽字段或者使用自然语言命令生成自己的报表,具体操作参考之前提到的:《AI 加持下的自助报表还能这么做!》。
实际使用中一些较为复杂的报表可以由技术人员提前做好,业务人员基于已有的报表查看数据,或者在已有的报表基础上修改,形成自己的报表,这样一些报表的开发工作就可以由业务人员自己处理,技术人员就不用面对没完没了的报表工作了。
比如技术人员可以先做好一个订单分组报表:

做好的报表可以保存下来,点击工具栏中的保存按钮,在弹出的保存窗口中设置名称:

文件会保存在默认目录中(应用的WEB-INF\files\olap 下),文件格式是 olap 后缀,默认存放目录可以在 WEB-INF 下的 guideConf.properties 中进行修改。业务人员打开报表只需将保存的文件名做为参数传入就行,访问链接:http://localhost:8080/report/raqsoft/guide/jsp/olap.jsp?olap= 订单分组.olap,就能查看到之前做好的报表结果。此时可以根据需求在结果上通过汉语言指令进行修改,比如在原有基础上增加环比增长,只需要点击“汉语”图标,执行命令:“计算 订单金额 比例环比 命名为 环比增长”,这样就增加环比增长列:


页面右侧为报表拖拽区域,可以通过鼠标拖拽生成报表结果,如果不希望右侧出现拖拽面板,可以更改olap.jsp 中的 guideConf.canEditReport,将值设成 no,避免用户的一些误操作,当然这个看实际需求情况而定。在 olap.jsp 里也可以做更多的客户化定制操作,文件内有详细的说明。
权限控制
权限控制主要分两种,数据权限和访问权限:
数据权限
在olap.jsp 中设置了数据来源为 SQL 语句,该 SQL 语句可以通过外部程序传入,在 SQL 语句中可以拼接不同的 where 条件达到数据权限控制的效果,本例中根据雇员 ID 字段做数据过滤,参数值可以在 session 中获取或者通过 request 获取,拼接好条件后替换 where 中的关键字即可,这样保证不同的人访问页面后看到的数据是不同的,或者整个 SQL 语句都可以通过参数传递过来,在传递前拼好相应的参数也行。
访问权限
在自助报表页面可以将制作好的报表结果保存到应用目录内,默认都是保存到同一目录,那么不同的人修改报表可能会出现同名覆盖问题,并且所有都放同一目录里也不便于管理,无法区分权限。在自助报表保存时可以在对话框内设置保存目录,在保存时:

服务器目录这里可以手动输入目录名,但是这个手动输入实用性不强,可以改由程序自动获取当前用户名自动生成,在olap.jsp 中增加: guideConf.serverSavePath="zhangsan",具体值同样可以在 jsp 中获取 session 信息或者在 request 中获取,这样,点击保存时,会自动填入对应信息,如:
使用时也可以设置这个对话框直接隐藏掉,避免信息外露,在olap.jsp 中增加:guideConf.saveDisp="1110"; ,这样,不同人保存时结果会放到各自目录内,访问报表时在 URL 上或者在 jsp 里在获取用户信息拼接到目录里就能有效控制访问权限。
LLM 使用及配置
开启LLM
默认情况下自助报表的汉语言指令要符合规范,不能识别灵活的口语命令,当用自然语言描述生成报表指令时,规则引擎无法理解就会报错。这时候可以借助AI 的能力,通过 LLM 将口语化的命令转化为规范语句,从而被识别处理。要启用LLM,需要修改【应用根目录】\raqsoft\guide\js 下的 funcs.js。

url:所选大模型的API 接口地址。
keyFile:指定存储 API 密钥的本地文本文件名(如 deepseek.txt),该文件在应用的 WEB-INF 下,将对应服务的 APIKey 写入该文件。
requestJSON:配置 LLM 的调用参数,如模型名称等。
promptMain:LLM 提示词文件设置,根据 isMulti 的值控制使用哪个提示词文件:nlr-prompt-main-multi.md(LLM 规划)或nlr-prompt-main.md(LLM 规范)。
注:本文中使用的是deepseek,换用其他模型可以按照例子更改下。
配置完成后,重启应用,就可以利用LLM 将口语化指令转化为规范语句。
LLM 提示词
提示词是用户给LLM 的输入,用于引导和指定模型按什么样的规则输出,精准的提示词设置有助于 LLM 更好理解用户需求并做更精准的输出。我们可以在提示词文件中设置好LLM 本次任务的所属角色、要做什么、怎么做以及提供一些示例说明,这样就可以借助 LLM 将自然语言指令转换成自助报表能执行的规范化命令。自助报表中根据用户执行的的操作(LLM 规范或LLM 规划)调用不同的提示词文件。
注:自助报表的提示词文件均放在:【应用根目录】/WEB-INF/classes 下,命名为 ***.md。
LLM 规范提示词
LLM 规范使用提示词文件 nlr-prompt-main.md,该提示词起到功能识别器作用,用户通过 LLM 规范对自然语言转换时,LLM 先根据 nlr-prompt-main.md 文件中的关键字设置,理解用户真实意图,识别自然语言命令所对应的功能模块,如字段删除、数据过滤操作、外观格式与样式设置等,在 classes 目录下会有不同的功能性的提示词文件与之相对应,提示词文件名为功能名.md,LLM 识别出用户自然语言中的具体功能后,再使用对应的提示词文件(功能名.md)对自然语言指令进行转换。如指令“去掉发货日期”,识别用户需求为做字段删除操作,使用提示词文件“字段删除.md”,LLM 根据该提示词文件信息,最终将用户输入的自然语言指令转换成自助报表能够识别的规范化命令:删除字段 发货日期。
LLM 规划提示词
LLM 规划支持转换包含多条指令的自然语言,做规划时LLM 使用提示词文件 nlr-prompt-main-multi.md,给 LLM 定位的角色是自助报表系统专属的多步骤自然语言指令规划器,主要做命令拆分规划,提示词文件中定义了多步骤的命令的拆分规则,LLM 依照提示词信息将自然语言拆分成多条指令并识别指令中的功能名称,用于后续执行,返回格式如下:
拆分步骤总数:X
步骤 1:功能名称 | 纯自然语言指令
步骤 2:功能名称 | 纯自然语言指令
字段专属字典表
字段专属字典表文件:nlr-prompt-dict.md,指令中有时会用到字段数据,比如数据过滤指令“取城市为北京的数据”,转换后的规范命令为“过滤 货主城市 等于 北京”,此时北京是个字符串,它是否需要用引号会影响命令执行的正确性,在提示词文件中设置了字典表引用格式规则:字符类型字段数据在字典表内,返回时不需要引号,如不在则必须加英文引号。可根据实际需要在字段专属字典表中添加对应字段值。
注:LLM 规范和 LLM 规划具体使用见《AI 加持下的自助报表还能这么做!》
LLM 切换及提示词更改
自助报表默认使用的LLM 是 deepseek,如果需要切换其他大模型在前文提到的 funcs.js 中按说明修改就行,注意要申请对应 LLM 的 API Key 写入到 keyfile 中。
不同的LLM 提示词细节可能略有不同,如发现转换结果不符合预期,可以修改上述提到的提示词文件进行调试。或者业务人员可能会有一些业务术语不在当前提示词文件中,如输入的命令可能会掺杂一些英文简语形式:做删除字段时自然语言写为“del 货主地区”,那么可以更改 nlr-prompt-main.md,在功能清单的字段删除节点中增加“del 某字段”:

这样用户就可以按照自己熟悉的语言风格实现对报表的设置。也可以在nlr-prompt-main.md 功能清单中按照原来样式新增功能,然后要有对应功能名.md 文件与之匹配,在功能名.md 中写入提示词设置命令的转换规则。
总结
润乾报表的一个典型特征是易集成,本文介绍了自助报表部署集成以及使用的一些相关配置,可以将自助报表嵌入到用户自己的业务系统中,接入用户的权限体系,打造统一的报表平台。
借助自助报表的汉语言报表功能,技术人员只需要做好数据准备工作,一些报表开发工作可以交由业务人员在WEB 通过自然语言生成,避免了技术人员无休止的报表开发工作,也使得业务需求能够及时得到响应。在通过自然语言生成报表时,汉语指令接入了 LLM,能够帮助业务人员更准确地生成润乾可执行的规范化语句,进一步提升了业务人员制作报表的可行性。
