最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Python解析FineReport模板數(shù)據(jù)集

 更新時間:2023年12月29日 15:06:03   作者:The_Singing_Towers  
這篇文章主要為大家詳細(xì)介紹了如何使用Python解析FineReport模板數(shù)據(jù)集,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解下

背景

在使用 FineReport 作為報表平臺過程中,

當(dāng)報表項目過多,或者報表項目需要遷移,又或者報表數(shù)據(jù)源需要遷移時,

我們通常需要知道報表用到的表有哪些,或者需要修改的SQL語句有哪些。

這時我們在 FineReport 設(shè)計器中需要將模板的數(shù)據(jù)集提取出來。

但目前設(shè)計器中沒有 數(shù)據(jù)集導(dǎo)出 的功能。

所以我們使用Python 開發(fā)程式以解析報表模板文件獲取 數(shù)據(jù)集 和 SQL語句,并保存為Excel,

以提供給后續(xù)解析SQL獲取調(diào)用內(nèi)容的項目使用。

應(yīng)用場景

  • 查找調(diào)用內(nèi)容
  • FineReport 模板遷移
  • 元數(shù)據(jù)
  • 數(shù)據(jù)血緣

操作對象

本示例中使用 本地工作目錄 中的 報表模板,F(xiàn)ineReport 平臺版本為 11

本地工作目錄路徑

D:\FineReport_11\webapps\webroot\WEB-INF\reportlets

示例報表模板路徑

01_dev\record_monitor\record_scheduler.cpt

示例報表模板數(shù)據(jù)集名稱

log_record_execute

示例報表模板數(shù)據(jù)鏈接名稱

LogDB

示例報表模板截圖

解析過程

查找目標(biāo)模板文件

為保證數(shù)據(jù)和模板安全,請先下載 正式環(huán)境reports文件夾,在本地進行匹配

工作過程中,平臺的報表目錄不一定之后報表模板文件,故需要用代碼先查找匹配,再打開;

代碼

import pathlib

# 請先下載 正式環(huán)境reports文件夾,在本地進行匹配

work_directory = pathlib.Path("D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets")

top = pathlib.Path("D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets\\01_dev\\record_monitor")

# 遞歸獲取 工作目錄 本路徑和子路徑所有擴展名為 .cpt 的 文件
for f in top.rglob("*.cpt"):
    # 模板文件的絕對路徑
    abs_path = f.absolute()
    # 為保證對象準(zhǔn)確,使用絕對路徑
    print(abs_path.__str__())

運行結(jié)果

D:\FineReport_11\webapps\webroot\WEB-INF\reportlets\01_dev\record_monitor\record_scheduler.cpt

獲取 數(shù)據(jù)集

FineReport 報表模板 .cpt .frm 本身是 xml 文件,故可直接使用解析XML的方式解析;

解析方式是XPATH語法定位目標(biāo)元素

代碼

import pathlib

from lxml import etree

# 請先下載 正式環(huán)境reports文件夾,在本地進行匹配

work_directory = pathlib.Path("D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets")
top = pathlib.Path("D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets\\01_dev\\record_monitor")

# 解析結(jié)果 收集
result_list = []

# 遞歸獲取 工作目錄 本路徑和子路徑所有擴展名為 .cpt 的 文件
for f in top.rglob("*.cpt"):
    # 模板文件的絕對路徑
    abs_path = f.absolute()

    with open(abs_path, mode="rb") as fr:
        xslt_content = fr.read()
    # 開始解析 模板文件 XML
    xml_root = etree.XML(xslt_content)
    # 使用 XPATH 定位 XML 中 數(shù)據(jù)集內(nèi)容
    tabel_data_el = xml_root.xpath("http://*/TableDataMap//TableData[@class='com.fr.data.impl.DBTableData']")

    for db_data in tabel_data_el:
        # 數(shù)據(jù)集名稱
        date_source_name = db_data.get("name")
        print(date_source_name)

運行結(jié)果

log_record_execute

我們可以用 Vs Code 或者其他文本編輯器從資源管理器打開這個模板文件,

可以看到 數(shù)據(jù)集 在模板XML中的樣子,

數(shù)據(jù)集都在 標(biāo)簽名為 TableDataMap 的 xml 元素下,

數(shù)據(jù)集本身就是 標(biāo)簽名為 TableData 的 xml 元素,所以使用 XPATH 能夠根據(jù)這種結(jié)構(gòu)定位到。

同時數(shù)據(jù)集的內(nèi)容也能以相同方式定位到。

部分 XML

<?xml version="1.0" encoding="UTF-8"?>
<WorkBook xmlVersion="20211223" releaseVersion="11.0.0">
    <TableDataMap>
        <TableData name="log_record_execute" class="com.fr.data.impl.DBTableData">
            <Parameters>
                <Parameter>
                    <Attributes name="start_date"/>
                    <O>
                        <![CDATA[2023-07-01 00:00:00]]></O>
                </Parameter>
                <Parameter>
                    <Attributes name="end_date"/>
                    <O>
                        <![CDATA[2023-09-07 00:00:00]]></O>
                </Parameter>
            </Parameters>
            <Attributes maxMemRowCount="-1"/>
            <Connection class="com.fr.data.impl.NameDatabaseConnection">
                <DatabaseName>
                    <![CDATA[LogDB]]></DatabaseName>
            </Connection>
            <Query>
                <![CDATA[select * from fine_record_execute where todate(time) >= '${start_date}'  and todate(time) <= '${end_date}']]></Query>
            <PageQuery>
                <![CDATA[]]></PageQuery>
        </TableData>
    </TableDataMap>
    ...
</WorkBook>

獲取數(shù)據(jù)集下的內(nèi)容

獲取到數(shù)據(jù)集的XML之后,變不需要從整個模板文件定位了,因為數(shù)據(jù)集的各種內(nèi)容都在這串XML里了,

所以直接解析 數(shù)據(jù)集XML 的 字符串就行;

代碼

import json
import pathlib

from lxml import etree

# 請先下載 正式環(huán)境reports文件夾,在本地進行匹配

work_directory = pathlib.Path("D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets")
top = pathlib.Path("D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets\\01_dev\\record_monitor")

# 遞歸獲取 工作目錄 本路徑和子路徑所有擴展名為 .cpt 的 文件
for f in top.rglob("*.cpt"):
    # 模板文件的絕對路徑
    abs_path = f.absolute()

    with open(abs_path, mode="rb") as fr:
        xslt_content = fr.read()
    # 開始解析 模板文件 XML
    xml_root = etree.XML(xslt_content)
    # 使用 XPATH 定位 XML 中 數(shù)據(jù)集內(nèi)容
    tabel_data_el = xml_root.xpath("http://*/TableDataMap//TableData[@class='com.fr.data.impl.DBTableData']")

    for db_data in tabel_data_el:

        # 數(shù)據(jù)集名稱
        date_source_name = db_data.get("name")

        # 轉(zhuǎn) string 取巧,重新定位數(shù)據(jù)集內(nèi)容
        string = etree.tostring(db_data, encoding='utf-8').decode('utf-8')

        data_source = etree.XML(string)
        # 即使 XPATH 定位到的是單個對象,但是返回值是一個list,需要將 list 里的對象 重新拼成 string
        conn = data_source.xpath("/TableData/Connection/DatabaseName/text()")

        conn_collect = []

        for j in conn:
            # 數(shù)據(jù)鏈接名字
            conn_collect.append(str(j).strip())

        conn_string = "".join(conn_collect)

        query = data_source.xpath("/TableData/Query/text()")

        query_collect = []

        for j in query:
            # 數(shù)據(jù)集SQL
            query_collect.append(str(j).strip())

        query_string = "".join(query_collect)

        # 將 解析結(jié)果 拼接到 dict
        data_source_json = {
            "report": pathlib.Path.relative_to(abs_path, work_directory).__str__(),
            "data_source": date_source_name,
            "conn": conn_string,
            "query": query_string
        }

        print(json.dumps(data_source_json, ensure_ascii=False))

運行結(jié)果

{
    "report": "01_dev\\record_monitor\\record_scheduler.cpt",
    "data_source": "log_record_execute",
    "conn": "LogDB",
    "query": "select * from fine_record_execute where todate(time) >= '${start_date}'  and todate(time) <= '${end_date}'"
}

可以看到,報表模板路徑,數(shù)據(jù)集名稱,數(shù)據(jù)鏈接名稱,SQL語句都完整獲取到了。

完整代碼

最后將獲取到的內(nèi)容轉(zhuǎn)成 pandas 的 DataFrame,然后輸出到Excel

import pathlib

import pandas as pd
from lxml import etree

# 請先下載 正式環(huán)境reports文件夾,在本地進行匹配

work_directory = pathlib.Path("D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets")
top = pathlib.Path("D:\\FineReport_11\\webapps\\webroot\\WEB-INF\\reportlets\\01_dev\\record_monitor")

# 解析結(jié)果 收集
result_list = []
# fineReport .cpt .frm 本身是xml文件,故可直接按行匹配字符查找是否與對象有關(guān)
# 遞歸獲取 工作目錄 本路徑和子路徑所有擴展名為 .cpt 的 文件
for f in top.rglob("*.cpt"):
    # 模板文件的絕對路徑
    abs_path = f.absolute()

    with open(abs_path, mode="rb") as fr:
        xslt_content = fr.read()
    # 開始解析 模板文件 XML
    xml_root = etree.XML(xslt_content)
    # 使用 XPATH 定位 XML 中 數(shù)據(jù)集內(nèi)容
    tabel_data_el = xml_root.xpath("http://*/TableDataMap//TableData[@class='com.fr.data.impl.DBTableData']")

    for db_data in tabel_data_el:

        # 數(shù)據(jù)集名稱
        date_source_name = db_data.get("name")

        # 轉(zhuǎn) string 取巧,重新定位數(shù)據(jù)集內(nèi)容
        string = etree.tostring(db_data, encoding='utf-8').decode('utf-8')

        data_source = etree.XML(string)
        # 即使 XPATH 定位到的是單個對象,但是返回值是一個list,需要將 list 里的對象 重新拼成 string

        conn = data_source.xpath("/TableData/Connection/DatabaseName/text()")

        conn_collect = []

        for j in conn:
            # 數(shù)據(jù)鏈接名字
            conn_collect.append(str(j).strip())

        conn_string = "".join(conn_collect)

        query = data_source.xpath("/TableData/Query/text()")

        query_collect = []

        for j in query:
            # 數(shù)據(jù)集SQL
            query_collect.append(str(j).strip())

        query_string = "".join(query_collect)

        # 將 解析結(jié)果 拼接到 dict
        data_source_json = {
            "report": pathlib.Path.relative_to(abs_path, work_directory).__str__(),
            "data_source": date_source_name,
            "conn": conn_string,
            "query": query_string
        }

        result_list.append(data_source_json)

df = pd.DataFrame(result_list)

df.to_excel("./data_source.xlsx", engine="openpyxl", index=False)

運行結(jié)果

到此這篇關(guān)于使用Python解析FineReport模板數(shù)據(jù)集的文章就介紹到這了,更多相關(guān)Python解析FineReport數(shù)據(jù)集內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Django微信小程序后臺開發(fā)教程的實現(xiàn)

    Django微信小程序后臺開發(fā)教程的實現(xiàn)

    這篇文章主要介紹了Django微信小程序后臺開發(fā)教程的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 基于python-opencv3實現(xiàn)圖像顯示和保存操作

    基于python-opencv3實現(xiàn)圖像顯示和保存操作

    這篇文章主要介紹了基于python opencv3的圖像顯示和保存操作方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-06-06
  • python如何將圖片批量保存至word文檔中

    python如何將圖片批量保存至word文檔中

    這篇文章主要介紹了python如何將圖片批量保存至word文檔中問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 淺談PyQt5中異步刷新UI和Python多線程總結(jié)

    淺談PyQt5中異步刷新UI和Python多線程總結(jié)

    今天小編就為大家分享一篇淺談PyQt5中異步刷新UI和Python多線程總結(jié),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • pandas讀取文件夾下所有excel文件的實現(xiàn)

    pandas讀取文件夾下所有excel文件的實現(xiàn)

    最近需要做一個需求,要求匯總一個文件夾所有的excel文件,所以本文就來介紹一下pandas讀取文件夾下所有excel文件的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • 一文詳解Python中的日期計算和自動化運行腳本

    一文詳解Python中的日期計算和自動化運行腳本

    這篇文章主要為大家詳細(xì)介紹了Python中的日期計算和自動化運行腳本的相關(guān)知識,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,有需要的小伙伴可以了解下
    2026-03-03
  • python3 gunicorn配置文件的用法解讀

    python3 gunicorn配置文件的用法解讀

    這篇文章主要介紹了python3 gunicorn配置文件的使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Python數(shù)據(jù)類型之Tuple元組實例詳解

    Python數(shù)據(jù)類型之Tuple元組實例詳解

    這篇文章主要介紹了Python數(shù)據(jù)類型之Tuple元組,結(jié)合實例形式分析了Python元組類型的概念、定義、讀取、連接、判斷等常見操作技巧與相關(guān)注意事項,需要的朋友可以參考下
    2019-05-05
  • python計算方程式根的方法

    python計算方程式根的方法

    這篇文章主要介紹了python計算方程式根的方法,涉及Python數(shù)學(xué)運算的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • Python中使用md5sum檢查目錄中相同文件代碼分享

    Python中使用md5sum檢查目錄中相同文件代碼分享

    這篇文章主要介紹了Python中使用md5sum檢查目錄中相同文件代碼分享,本文直接給出實現(xiàn)代碼,需要的朋友可以參考下
    2015-02-02

最新評論

晋城| 新密市| 寿光市| 南平市| 大理市| 临漳县| 包头市| 樟树市| 保山市| 鄂温| 沙洋县| 定安县| 息烽县| 荔波县| 阿瓦提县| 南投市| 肃宁县| 莎车县| 富平县| 罗定市| 滨海县| 怀安县| 定日县| 汝州市| 林口县| 泾川县| 甘泉县| 嵊州市| 温泉县| 乌鲁木齐市| 塔城市| 沐川县| 正蓝旗| 松潘县| 宁晋县| 黄石市| 明星| 武功县| 穆棱市| 三穗县| 曲沃县|