GDIM自动报告 (Report App)

本章说明如何为 GDIM 「自动报告」应用 编写 Pipeline:读取项目数据,计算或生成文字, 按 Word 模板渲染成 .docx 报告(或报告中的一个章节)。

应用类型的整体划分见 GDIM应用类型 (App Types),共用构建步骤见 工作流构建 (Pipeline Build)。 入门教程见 新手入门 (Getting Started) 中「生成报告」一节。

平台如何运行

  1. 在数字模型中添加「自动报告」应用,上传 .pipe 并配置报告章节和 Word 模板。

  2. GDIM 运行 Pipeline 时通过 template 属性把模板文件描述传给 DocPrinter。

  3. DocPrinter 渲染报告并上传到 GDIM 文件服务器,return_results_config 指定的 OutputFile 返回给前端下载。

配置细节见 GDIM 视频教程 中「自动报告应用」部分。

推荐拓扑

报告通常由若干段内容组成,每段内容各用一个 DocDataWriter 转为 DocData,再合并后打印:

GdimTableReader / GdimAppProjectInfoReader
     │
     ▼
NullValueChecker(可选:空值时给出可读的错误或警告)
     │
     ├──► 计算 / 分析模块 ──────────► DocDataWriter (章节 A) ─┐
     ├──► PromptTemplate ─► LLMNode ─► DocDataWriter (章节 B) ─┤
     └──► 绘图模块 (图片文件) ───────► DocDataWriter (章节 C) ─┤
                                                                ▼
                                               MergeDocData (动态输入端口)
                                                                │
                                                                ▼
                                               DocPrinter (save_to_gdim=True)
                                                                │ OutputFile ← return_results_config

只有一段内容时可以省略 MergeDocData,DocDataWriter.OutputDocData 直接接 DocPrinter.InputDocData。

规则

  • ``DocPrinter.save_to_gdim = True``。 否则报告只留在服务器本地,GDIM 拿不到 GdimFile。

  • 模板通过 template 属性提供。 pipeline.add_attribute(attr_name="template", module_name="PrintDoc", param_name="template", attr_title="报告模板")。 脚本里的本地模板路径只用于本地测试;上传后以前端传入的文件描述为准。

  • ``return_results_config = {“PrintDoc”: “OutputFile”}``。 只返回报告文件。

  • ``output_name`` 设为稳定、可识别的文件名,例如 "Doc2场地工程地质条件2.docx"。

  • **MergeDocData 默认要求所有输入端口都有数据**(all_ports_required=True)。任一分支输出 None,整份报告就不会生成。 对可能为空的数据源:用 empty_error_type = "create_empty_table" 读空表(DocDataWriter 对空表输出空 DocData), 或用 NullValueChecker 提前报出可读的错误;确实允许缺章节时才设 all_ports_required = False。

  • 报告里的图片或子文档 经 DocDataWriter.files_path 写入;由前端提供时用属性传入 GDIM 文件描述(list[dict]),不要写死本机路径。

  • LLM 生成的文字 用 PromptTemplate + LLMNode,输出接 DocDataWriter。提示词写在脚本里,不依赖外部文件。

两阶段开发:先导出模板变量,再配置模板

Word 模板里的 {{key}} 必须和 DocData 的 key 一致,因此按两步做:

  1. 先不接 DocPrinter 。 运行到 MergeDocData``(或唯一的 ``DocDataWriter),导出变量结构:

    merged = result.get_result("MergeDoc", "OutputDocData")
    merged.export_keys_to_json(str(WORKSPACE_DIR / "doc_keys.json"))   # 模板变量结构
    merged.export_data_to_json(str(WORKSPACE_DIR / "doc_data.json"))   # 可选:检查实际数据
    
  2. 按 doc_keys.json 编辑 Word 模板,把变量放进 {{ }},表格用循环语法。然后接上 DocPrinter 运行,检查生成的报告。

doc_keys.json、doc_data.json 属于运行产物,放在 workspace/;Word 模板是提交到仓库的输入文件,放在 Pipeline 根目录。

完整示例

读取产状表和勘探孔参数表:产状由 PythonCoder 生成描述文字,抗震设计参数由钻孔凸包中心查询,两段内容合并后打印。

from pathlib import Path

from gdisdk.connectors import log_in
from gdisdk.modules import PythonCoder
from gdisdk.modules.filters import TableSelector
from gdisdk.modules.geoSurvey import SeismicDesignParameters
from gdisdk.modules.gisOperators import ConvexHullCenter
from gdisdk.modules.readers import GdimTableReader
from gdisdk.modules.writers import DocDataWriter, DocPrinter, MergeDocData
from gdisdk.pipeline import PipeLine

_SCRIPT_DIR = Path(__file__).resolve().parent
WORKSPACE_DIR = _SCRIPT_DIR / "workspace"
TEMPLATE = _SCRIPT_DIR / "Doc2场地工程地质条件2-模板.docx"   # 仅本地测试用


def build_pipeline() -> PipeLine:
    pipeline = PipeLine(
        app_name="Doc2GeologicalCondition2",
        app_title="Doc2场地工程地质条件2",
        workspace=WORKSPACE_DIR,
    )
    pipeline.update_gdim_state(token=log_in(), proj_id="你的GDIM项目ID")
    pipeline.local_functions_path = str(_SCRIPT_DIR / "localFunction.py")

    read_tables = GdimTableReader("ReadTables")
    read_tables.table_fields = ["产状表", "勘探孔参数表"]
    read_tables.empty_error_type = "create_empty_table"

    select_attitude = TableSelector("SelectAttitudeTable")
    select_attitude.table_name = "产状表"

    attitude_description = PythonCoder("AttitudeDescription")
    attitude_description.local_function_name = "process_attitude_table"
    attitude_description.add_dynamic_ports_in("InputTable")
    attitude_description.add_dynamic_ports_out("OutputResult")

    select_bores = TableSelector("SelectBoreTable")
    select_bores.table_name = "勘探孔参数表"

    hull_center = ConvexHullCenter("ConvexHullCenter")
    hull_center.by_xy = False   # 用经纬度

    seismic_params = SeismicDesignParameters("SeismicDesignParams")

    attitude_doc = DocDataWriter("AttitudeDoc")
    seismic_doc = DocDataWriter("SeismicDoc")

    merge_doc = MergeDocData("MergeDoc")
    merge_doc.add_dynamic_ports_in("InputAttitude")
    merge_doc.add_dynamic_ports_in("InputSeismic")

    print_doc = DocPrinter("PrintDoc")
    print_doc.template = str(TEMPLATE)
    print_doc.output_name = "Doc2场地工程地质条件2.docx"
    print_doc.save_to_gdim = True

    pipeline.add_links(
        read_tables.OutputTables >> select_attitude.InputTables
        | select_attitude.OutputTable >> attitude_description.InputTable
        | read_tables.OutputTables >> select_bores.InputTables
        | select_bores.OutputTable >> hull_center.InputTable
        | hull_center.OutputCenter >> seismic_params.InputPoint
        | attitude_description.OutputResult >> attitude_doc.InputData
        | seismic_params.OutputResult >> seismic_doc.InputData
        | attitude_doc.OutputDocData >> merge_doc.InputAttitude
        | seismic_doc.OutputDocData >> merge_doc.InputSeismic
        | merge_doc.OutputDocData >> print_doc.InputDocData
    )

    pipeline.add_attribute(
        attr_name="template",
        module_name="PrintDoc",
        param_name="template",
        attr_title="报告模板",
    )

    pipeline.return_results_config = {"PrintDoc": "OutputFile"}
    pipeline.save_pipeline(f"{pipeline.workspace}/{pipeline.app_name}.pipe")
    return pipeline


if __name__ == "__main__":
    pipeline = build_pipeline()
    result = pipeline.run(
        verbose=True,
        run_trace_file="run_trace.json",
        return_results={"MergeDoc": "OutputDocData", "PrintDoc": "OutputFile"},
    )
    result.get_result("MergeDoc", "OutputDocData").export_keys_to_json(str(WORKSPACE_DIR / "doc_keys.json"))
    print(result.get_result("PrintDoc", "OutputFile"))

常见错误

  • 没设 save_to_gdim=True 。 本地能生成 .docx,上传后拿不到 GdimFile。

  • 模板只写了本机路径,没有暴露 template 属性。 GDIM 无法传入章节模板。

  • 某个分支为空导致整份报告不输出。 MergeDocData 默认要求所有端口有数据;处理空表或用 NullValueChecker 给出明确提示。

  • 模板变量和 DocData key 对不上。 先导出 doc_keys.json 再编辑模板;改了 DocDataWriter 的输入或表名后要重新导出。

  • 合并时 key 重复。 MergeDocData 会给重复 key 追加 _1、_2 后缀,模板里的变量随之失配;给各段数据起不同的表名或结果名。

  • ``return_results_config`` 返回了中间数据。 自动报告应用只需返回 PrintDoc.OutputFile。

与其它文档的关系