首页/文章/ 详情

没有 Word 也能自动写有限元报告:ANSYS 用 Python 自己实现 MD文档生成器

1天前浏览4

图片

没有 Word 也能自动写有限元报告:ANSYS Mechanical 用 Python 自己实现 Markdown 文档生成器

需求描述:从 Word 依赖切换到 Markdown

大家好,我是小郭老师,中科院硕士,长期从事 ANSYS 二次开发与仿真流程自动化。

之前的文章里,我们介绍过使用 Word 来组织仿真结果图片和报告内容。后来有学员反馈,他的电脑没有安装 Word,日常环境主要使用 WPS,原来的代码因此出现了问题。

这类问题的关键,不在于 WPS 能不能打开某个文档,而在于脚本是否把报告生成过程绑定到了 Word 的应用对象模型。如果代码需要启动 Word、创建文档对象、插入图片,再设置段落和表格格式,那么运行环境里少了对应的 Office 组件,或者对象接口不完全一致,就可能在脚本执行阶段出现兼容性问题。

对于 ANSYS Mechanical 的有限元和数值计算任务,报告首先需要保存的是一组结构化信息:分析类型、材料参数、载荷条件、结果对象、结果数值、图片文件和复核说明。这些内容可以先用纯文本保存,再由 Markdown 阅读器负责渲染。

Markdown 的优势在于语法轻量,标题、表格、列表、链接和图片都可以直接写成文本。生成 .md 文件不要求电脑安装 Word,也不要求脚本调用 WPS 的自动化接口。更重要的是,Markdown 文件容易搜索、比较和归档,AI 也能直接读取其中的标题层级、表格字段和结果说明。

因此,这次我们换一个思路:让 ANSYS Mechanical 负责仿真模型和结果,Python 负责输出 Markdown 文本,阅读器负责显示最终效果。

为什么参考 mdutils,但在 Mechanical 里自己写一个

如果你搜索 Python 生成 Markdown 的方案,会遇到 mdutils 这样的库。它的定位很接近“Markdown 文档生成器”:先创建一个 Markdown 文档对象,再通过生成标题、段落、表格、链接、列表和图片等方法组织内容,最后写入文件。具体接口可以参考 mdutils 官方仓库。

mdutils 值得借鉴的地方,不只是它支持多少种 Markdown 语法,更重要的是它把“报告内容”和“格式符号”分开了。业务代码不需要到处手写标题、表格、图片等格式符号,而是调用有明确含义的方法。

在 ANSYS Mechanical 中,我们可以沿着这个思路自己写一个轻量版本。这样做有三个现实原因:

  • • Mechanical 内置脚本通常按 Python 2.7 或 IronPython 风格运行,直接安装和维护第三方库需要先确认当前环境。
  • • 对单个仿真报告来说,真正需要的可能只有标题、段落、表格、图片和保存文件这几类操作。
  • • 自己掌握格式层后,后续可以针对 Mechanical 的结果对象、图片命名和项目目录规则继续扩展。

为什么 Markdown 更适合保存仿真结果

Markdown 的价值不只在于“没有 Word 也能写文件”。它还提供了一种更容易被工程师和 AI 同时读取的结果记录方式。

以一个结果摘要表为例:

## 结果摘要

| 分析 | 结果对象 | 最大值 | 最小值 | 单位 | 图片 |
| --- | --- | ---: | ---: | --- | --- |
| Structural | Equivalent Stress | 186.4 | 0.0 | MPa | equivalent_stress.png |

这张表里,分析名称、结果对象、极值、单位和图片文件之间的关系都被明确写出。人可以直接阅读,脚本可以继续处理,AI 也能根据表头识别每个数字的含义。

对于有限元项目,建议把下面几类信息固定下来:

  • • 模型或工况名称:说明这组结果来自哪个算例。
  • • 分析名称和结果对象名称:避免把多个结果对象的数值混在一起。
  • • 数值与单位:不要只输出一个没有单位的数字。
  • • 数据来源:记录结果对象、节点、Named Selection 或图片文件名。
  • • 处理状态:区分已求解、未求解、读取失败和需要复核的对象。

这些信息写入 Markdown 后,文件可以进入项目归档、版本管理和 AI 辅助分析流程。AI 是否能正确理解结果,仍然取决于字段是否完整、单位是否明确、结果对象是否命名稳定;格式本身不会替代数据质量。

脚本实现思路

这份热力耦合报告示例,把代码分成两层:MarkdownBuilder 负责生成文档格式,报告主体负责填入分析概况、材料参数、分析说明和结果图片。

图片

第一步,初始化文档对象。MarkdownBuilder 内部使用 lines 列表保存每一行 Markdown 文本。如果初始化时传入标题,类会自动写入一级标题。

第二步,用语义化方法写入内容。heading() 负责标题,paragraph() 负责段落,bullet_list()ordered_list() 负责列表,quote() 负责引用,调用者不需要手动维护空行。

第三步,把表格和图片单独封装。table(headers, rows) 接收表头和数据行,统一生成 Markdown 表格;figure(caption, url) 先写图片说明,再写图片引用,适合组织温度云图和等效应力云图。

第四步,获取 ANSYS Mechanical 的用户文件目录。示例使用 wbjn.ExecuteCommand() 调用 GetUserFilesDirectory(),报告文件统一保存到这个目录下,图片在 Markdown 中使用文件名引用。

第五步,渲染并保存。render()lines 列表合并成完整文本,save() 创建目标目录并以 UTF-8 写出 Markdown 文件。报告内容与文件格式在这里完成分离,后续增加新章节时,只需要组合新的构建方法。

源码及其讲解

图片

这张源码图展示了 MarkdownBuilder 的核心实现。当前类内一共定义了 17 个方法:__init__ 负责初始化,另外 16 个方法分别覆盖文本、格式、图片、列表、表格、渲染和文件保存。它们可以分成下面几组:

功能分组
已实现的方法
作用
初始化与原始行
__init__()
add_line()
创建 lines 缓冲区,并允许直接追加一行 Markdown 文本
标题与段落
heading()
paragraph()
生成 1 到 6 级标题、普通段落,并自动补充空行
行文格式
bold()
italic()link()
返回加粗、斜体和超链接对应的 Markdown 字符串
图片与代码
image()
figure()code()
写入图片、带说明的图片以及带语言标识的代码块
列表与表格
bullet_list()
ordered_list()table()
生成无序列表、有序列表和 Markdown 表格
分隔与输出
quote()
horizontal_line()render()save()
生成引用、水平分隔线,合并全文并保存到文件

其中,heading() 会把传入的标题级别限制在 1 到 6 之间;paragraph()image()table() 等方法都会在内容后追加空行,减少调用者手动维护 Markdown 排版的工作。bold()italic()link() 不直接写入 lines,它们返回格式化后的字符串,适合嵌入段落、表格单元格或列表项中。

图片部分有两个层次。image() 负责生成标准图片语法,并支持可选的图片标题;figure() 在此基础上先写入加粗的图片说明,再调用 image() 写入图片引用。这样报告中可以统一使用“说明文字 + 图片”的结构。code() 则把代码内容包进三个反引号,并可附加 python 等语言标识。

列表和表格方法接收 Python 列表作为输入。bullet_list() 在每个元素前加上 -ordered_list() 自动添加序号,table() 则根据表头数量生成分隔行,再逐行写入数据。对于 ANSYS 结果报告,这种接口可以把结果对象、最大值、最小值、单位和图片文件名组织成固定列。

本次热力耦合报告主体显式调用了 __init__()paragraph()heading()table()figure()save()figure() 内部又间接调用了 image()。其余方法虽然没有出现在当前演示报告中,但已经作为通用 Markdown 接口保留,后续增加结论引用、代码片段、工况清单或多工况对比表时可以直接复用。

报告主体的调用方式可以保持很直观:

report = MarkdownBuilder(u"热力耦合分析报告")

report.paragraph(u"本报告由 ANSYS Mechanical 自动生成。")
report.heading(u"分析概况", 2)
report.table(
    [u"项目", u"内容"],
    [
        [u"分析类型", u"热-结构耦合分析"],
        [u"求解器", u"ANSYS Mechanical"]
    ]
)
report.figure(u"温度场分布", u"temperature_distribution.png")
report.save(output_file)

这段调用代码只描述报告需要哪些内容,具体的 #、表格分隔线和图片语法由 MarkdownBuilder 负责生成。类内部的 heading() 会把标题级别限制在 1 到 6 之间,table() 会先输出表头和分隔行,再逐行拼接数据,figure() 则把图片说明和图片引用组合起来。

这种设计的价值,是把“报告写什么”和“Markdown 怎么写”拆开。后续从热分析扩展到热-结构耦合、多工况结构分析或接触分析时,报告主体可以替换数据表和结果图片,格式接口仍然保持一致。

保存部分沿用了 Mechanical 脚本常见的 Python 2.7 写法:先通过 render() 得到 Unicode 文本,再编码成 UTF-8 写入文件。

脚本运行结果

脚本运行后,会在 ANSYS Mechanical 的 user_files 目录下生成 thermal_coupling_report.md。文件内容包括:

报告调用
Markdown 内容
MarkdownBuilder(u"热力耦合分析报告")
一级标题
heading(u"分析概况", 2)
分析类型、求解器、材料和温度载荷表格
heading(u"材料参数", 2)
弹性模量、泊松比、线膨胀系数和密度表格
heading(u"分析说明", 2)
温度场传递到结构分析的过程说明
figure(u"温度场分布", ...)
温度场图片说明和图片链接
figure(u"等效应力分布", ...)
等效应力图片说明和图片链接

图片

图片


需注意的是,当前示例把表格数据和图片文件名写在报告主体中,重点演示 Markdown 文档结构的生成。它并没有在这段代码里自动读取 Solution 下的真实结果极值,也没有负责导出两张结果图片。

如果要升级为项目报告,可以在报告主体中接入真实结果读取和图片导出逻辑。MarkdownBuilder 继续负责格式,结果提取逻辑负责提供数据,两部分各自保持清晰。

脚本扩展方向

  • • 将固定的分析概况和材料参数替换成当前 Mechanical 模型中的真实属性,并把模型名称、分析名称和工况编号写入报告。
  • • 连接 Solution 下的结果对象,读取已经求解结果的最大值、最小值或平均值,生成统一的结果摘要表。
  • • 将结果云图导出与图片引用结合起来,自动把图片文件名、结果对象名称和报告章节对应起来。
  • • 增加异常提示和状态表,记录结果未求解、对象不存在、图片缺失或输出目录不可写等情况。
  • • 将 MarkdownBuilder 拆成可复用模块,后续继续增加目录、分隔线、HTML 片段或多工况汇总功能。

如果项目最终仍然需要 Word、PDF 或网页格式,可以把 Markdown 作为中间结果,再在 ANSYS Mechanical 外部完成转换。这样报告生成和格式转换各自独立,Word 或 WPS 的安装状态不会影响 Mechanical 内部的结果归档。

总结

学员关于 Word 和 WPS 环境的反馈,提醒我们重新审视报告自动化的依赖边界。对 ANSYS Mechanical 来说,仿真结果本身是结构化数据,报告生成可以先落到稳定、可搜索、易解析的 Markdown 文本上。

这份热力耦合示例通过 MarkdownBuilder 把标题、段落、表格、图片和文件保存封装成一组清晰的方法。它借鉴了 mdutils 这类 Markdown 文档生成器的接口思路,同时保留了 Mechanical Python 环境下的可控性。当前示例重点是报告结构,下一步再把真实结果读取、图片导出和多工况数据接入这套结构。

你在 ANSYS Mechanical 中生成报告时,更希望自动整理哪类内容:结果极值、热-结构耦合过程、云图图片,还是多工况对比表?如果你在 Word、WPS 或 Markdown 报告生成中遇到过具体问题,也可以把运行环境和报错现象写在评论区。



二次开发代码&命令Mechanical
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2026-08-24
最近编辑:1天前
小郭老师
硕士 小郭老师,精通ANSYS开发
获赞 145粉丝 43文章 32课程 2
点赞
收藏
作者推荐
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈