【摸鱼笔记】python 提取和采集 finereport 未绑定目录的报表模板

devtools/2024/10/21 3:15:49/

背景

在企业应用过程中,报表一般会按照数据分析的主题、项目将多个报表放在一处,一些图表类报表会有通过超链接等方式,跳转到对应的明细报表中。

并且在正式的使用中,这些报表不会绑定到目录。

在梳理数据分析项目使用情况时这些报表会难以辨认所属的项目,因为即使按照很标准的方式【将同一项目的报表放在同一目录】也会有数据分析项目相互包含的问题影响梳理的工作量。

同时在fine logDB 的访问记录中 displayName 也不会记录访问时的目录名称,所以需要通过报表模板和报表模板之间的调用关系,将没有绑定目录的报表与已经绑定目录的报表关联到一起。

从而完成梳理过程。

抓取

范围

报表模板中可以配置跳转的目标报表,一般会以以下方式配置结果

  • 超链接 网络报表
  • 插入子报表
  • 超链接 url
  • 公式定义器
  • 报表块JS事件

方式

finereport 报表模板是xml格式文本文件,使用vscode打开可以确认,

xml格式文本文件可以通过 xpath 语法解析出想要的内容,以下是解析配置结果对应的xpath表达式

超链接 网络报表

//*/JavaScript[@class='com.fr.js.ReportletHyperlink']/ReportletName

插入子报表

//*/O[@t='SubReport']/packee/Path

超链接 url

//*/JavaScript[@class='com.fr.js.WebHyperlink']/URL

公式定义器

//*/O[@class='com.fr.base.Formula']/Attributes

报表块JS事件

//*/JavaScript[@class='com.fr.js.JavaScriptImpl']/Content")

如下图,在任意单元格中插入超链接,这里使用网络报表为例:

在这里插入图片描述

此报表模板路径为

D:\FineReport_11\webapps\webroot\WEB-INF\reportlets\01_dev\clip\url_test.cpt

配置结果中网络报表 url 为

D:\FineReport_11\webapps\webroot\WEB-INF\reportlets\01_dev\clip\home_page.frm

使用 vscode 打开 url_test.cpt

在这里插入图片描述

可以看到 xml 中<JavaScript class="com.fr.js.ReportletHyperlink"> 元素

它的子元素 <ReportletName showPI="true"> 包含着我们想要的结果<![CDATA[/01_dev/clip/home_page.frm]]>

所以使用 XPath 能够将 ReportletName 匹配到,并且提取到网络报表中配置的报表路径。

这里的报表路径是相对于 {fine_report_path}\webapps\webroot\WEB-INF\reportlets 的相对路径。

也是预览链接中 viewlet 参数指向的路径。http://localhost:8075/webroot/decision/view/report?viewlet=01_dev/clip/home_page.cpt

完整代码

python">import itertools
import pathlibimport pandas as pd
import yarl
from lxml import etreereportlets = "D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets\\"top = "D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets\\demo"
path_top = pathlib.Path(reportlets)result_lst = []for reportlet in itertools.chain(path_top.rglob("*.cpt"), path_top.rglob("*.frm")):with open(reportlet, mode="rb") as fr:xml_string = fr.read()if xml_string is None or xml_string.__len__() <= 0:continueroot = etree.XML(xml_string)tree = etree.ElementTree(root)# xpath提取 超链接 网络报表elements_reportlet = root.xpath("//*/JavaScript[@class='com.fr.js.ReportletHyperlink']/ReportletName")# xpath提取 插入子报表elements_sub_report = root.xpath("//*/O[@t='SubReport']/packee/Path")# xpath提取 超链接 urlelements_url = root.xpath("//*/JavaScript[@class='com.fr.js.WebHyperlink']/URL")# xpath提取 公式定义器# element_formula = root.xpath("//*/O[@class='com.fr.base.Formula']/Attributes")# xpath提取 报表块JS事件# element_js_content = root.xpath("//*/JavaScript[@class='com.fr.js.JavaScriptImpl']/Content")extract_lst = []# 处理 xpath 提取到的结果for e in itertools.chain(elements_reportlet,elements_sub_report):text_element = e.textif text_element is None:continuecontent_text = str(text_element).strip()if ".cpt" not in content_text and ".frm" not in content_text:continueif content_text not in extract_lst:extract_lst.append(content_text)for e in itertools.chain(elements_url):text_element = e.textif text_element is None:continueurl_obj = yarl.URL(text_element)# 提取URL的各个部分# print("# url ")# print(url_obj.human_repr())# print("## scheme ")# print(url_obj.scheme)# print("## host ")# print(url_obj.host)# print("## path ")# print(url_obj.path)# print("## query ")# for k in url_obj.query.keys():#     print("- ", k, url_obj.query.get(k))# print("## fragment ", url_obj.fragment)if not url_obj.host == "localhost":continueif not "/webroot/ReportServer" == url_obj.path:continueif url_obj.query is None or url_obj.query.get("reportlet") is None:continuecontent_query = url_obj.query.get("reportlet")# print("## reportlet ")# print(reportlet)if content_query not in extract_lst:extract_lst.append(content_query)if extract_lst is None or len(extract_lst) <= 0:continuefor extract in extract_lst:result_item = {"reportlet": reportlet.relative_to(path_top).as_posix().__str__(),"extract": extract}# 打印示例提取结果 {'reportlet': 'url_test.cpt', 'extract': '/01_dev/clip/home_page.frm'}print(result_item)result_lst.append(result_item)# 用 pandas 存入 Excel
# 也可进行其他处理 比如存入数据库
df = pd.DataFrame(result_lst)df.to_excel("./report_let.xlsx", engine="openpyxl", index=False)

http://www.ppmy.cn/devtools/105313.html

相关文章

DELTATAU泰道602428-100

DELTATAU泰道602428-100是一款由DELTATAU&#xff08;泰道&#xff09;品牌生产的具体型号产品&#xff0c;但由于不同领域的产品种类繁多&#xff0c;且具体产品信息可能随时间更新&#xff0c;以下是根据现有信息进行的综合介绍&#xff1a; 基本信息 产品型号&#xff1a;…

政治哲学(Political Philosophy)

GPT-4o (OpenAI) 政治哲学是研究政治、政府、法律、权利和义务等基本问题的哲学分支。下面是一些政治哲学中涉及的关键概念和层面&#xff1a; 1. 国家和政府的性质&#xff1a; - 国家的定义和目的&#xff1a;探讨什么是国家&#xff0c;以及国家存在的目的和正当性&…

2024前端面试题分享

前言 最近忙着面试很久没有更新文章了&#xff0c;分享一下我收集的前端面经&#xff0c;当然题目仅供参考&#xff08;乞求秋招offer&#xff09; 面试题 响应式布局 ---根据用户的的窗口变化而变化的布局方式 react 的hooks ---官方提供的钩子和自定义的钩子&#xf…

Linux下Docker基础命令(使用腾讯云镜像源)

Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Linux 或 Windows 操作系统的机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不会有任何接口&…

Flask中的g的作用

Flask中的g对象是一个非常重要的概念&#xff0c;它在Flask应用程序的上下文中扮演着关键角色。下面我将详细阐述g对象的作用&#xff0c;但由于篇幅限制&#xff0c;无法达到5000字&#xff0c;但会尽量全面而精炼地介绍其关键特性和用途。 Flask中的g是什么&#xff1f; 在…

信息打点-系统篇端口扫描CDN服务负载均衡WAF防火墙

知识点&#xff1a; 1、获取网络信息-服务厂商&网络架构 2、获取服务信息-应用协议&内网资产 3、获取阻碍信息-CDN&WAF&负载均衡&防火墙 演示案例&#xff1a; 1、网络信息获取-服务厂商&网络架构 访问外网80端口&#xff0c;转发到内网80端口 2…

顺序结构存储的线性表操作【作业代码 1】

顺序结构存储的线性表操作 顺序结构存储的线性表是一种使用连续内存空间来存储元素的数据结构。在这种结构中&#xff0c;元素之间的相对位置通过物理存储位置直接反映出来&#xff0c;即元素在内存中的地址是连续的。下面&#xff0c;我们将基于您提供的代码片段&#xff0c;…

Sentinel-1 Level 1数据处理的详细算法定义(九)

《Sentinel-1 Level 1数据处理的详细算法定义》文档定义和描述了Sentinel-1实现的Level 1处理算法和方程&#xff0c;以便生成Level 1产品。这些算法适用于Sentinel-1的Stripmap、Interferometric Wide-swath (IW)、Extra-wide-swath (EW)和Wave模式。 今天介绍的内容如下&…