원클릭으로
원클릭으로
| name | uzoncalc-writer |
| description | 使用 uzoncalc 以编写 python 代码的方式创建工程计算书,实现公式自动计算、自动排版、自动渲染 HTML 文档等功能 |
UzonCalc 是一个基于 Python 的工程计算书生成工具。通过在 async def 函数中编写计算逻辑,UzonCalc 能自动捕获变量赋值、公式推导过程,并渲染为带目录、数学公式、表格、图表的 HTML 计算书。
在编写计算书时,应从专业高级设计工程师的角度,以工程计算算单为风格,以直接交付为目标进行编写。
from uzoncalc import *
@uzon_calc()
async def sheet():
doc_title("计算书标题")
H1("示例章节")
"这是一段说明文字。"
a = 10 * unit.meter
b = 5 * unit.meter
c = a + b # 自动渲染公式:c = a + b = 15 m
if __name__ == "__main__":
ctx = run_sync(sheet)
ctx.save("output.html") # 也可在函数外保存
| 规则 | 说明 |
|---|---|
函数必须 async def | @uzon_calc() 仅支持异步函数 |
| 字符串字面量即段落 | 函数体内裸字符串 "文本" / """多行""" 作为段落输出 |
| 变量赋值自动渲染 | x = expr 被捕获并渲染为数学公式 x = expr = 值 |
| 变量名用 camelCase | _ 被解析为下标(H_2 → H₂),避免用下划线命名变量 |
| 希腊字母自动转换 | alpha→α,Beta→Β,首字母大写得大写希腊字母 |
| 纯函数调用不会插桩输出调用过程 | 如 f(x) 不会渲染为 f(x),而是直接调用 |
用于定义文档的结构和布局。
doc_title("页眉标题") # 设置页面/打印页眉标题
page_size("A4") # 页面大小:A4、A3、Letter 等
toc("目录") # 在当前位置插入目录(自动编号)
font_family("Arial") # 设置字体
H1("一级标题") # H1~H6 对应六级标题,自动带有编号
H2("二级标题")
H3("三级标题")
Br() # 插入空行
Info("提示信息") # 蓝色信息框
Code("代码", "python") # 代码块,支持语法高亮
P("段落") # 显式段落(等价于裸字符串)
可以使用以下预定义的函数,简化 HTML 内容的生成。其中,以小写字母开头的函数会返回 HTML 结果,而以大写字母开头的函数会直接渲染到文档中。
# 小写函数:返回 HTML 字符串,适合组合嵌套内容
content = div(
[
h2("截面参数"),
p("以下参数用于承载力验算。"),
span("重要", classes="text-red-600 font-bold"),
],
classes="border p-2",
)
P(content)
# 大写函数:直接追加到当前文档
H1("设计依据")
P("本节列出主要设计参数。")
Div(
[
h3("材料"),
p("混凝土强度等级为 C50。"),
],
classes="bg-gray-50 p-3",
)
常用 HTML 元素如下:
| 函数 | 说明 |
|---|---|
h(tag, children, ...) | 通用 HTML 构造器,children 支持字符串或字符串列表 |
h1h6 / H1H6 | 标题元素,小写返回字符串,大写直接渲染 |
title / Title | 文档大标题,默认居中、加粗、大字号 |
subtitle / Subtitle | 文档副标题,默认居中、加粗 |
p / P | 段落 |
div / Div | 块级容器 |
span / Span | 行内容器 |
row / Row | 行容器,默认渲染为 div,可通过 tag 指定标签 |
br / Br | 换行,自闭合元素 |
img / Img | 图片,支持 alt、width、height |
input / Input | 输入元素,当前主要用于生成带 value 的 HTML 输入标签 |
code / Code | 代码块,language 会生成 language-python 等高亮类名 |
info / Info | 蓝色提示框 |
laTex / LaTex | 原始 LaTeX 内容标签 |
plot / Plot | Matplotlib 图像或 PNG 二进制内容转为内嵌 base64 图片 |
属性与样式使用 classes 和 props():
# classes 会写入 HTML class 属性,适合 Tailwind/页面样式类
P("控制性参数", props=props(id="control-params"))
Div("验算通过", classes="text-green-700 font-bold")
# props 支持 id、classes、styles,并将自定义属性中的下划线转为短横线
P(
"带自定义属性的段落",
props=props(
id="note-1",
classes="text-sm",
styles={"color": "#444", "margin-top": "8px"},
data_value="section-note",
aria_label="说明段落",
),
)
# 当同时传入 classes 和 props.classes 时,函数参数 classes 优先
Div(
"最终使用 text-blue-700",
classes="text-blue-700",
props=props(classes="text-red-700"),
)
复杂内容建议先用小写函数组合,再用大写函数渲染:
parameterPanel = div(
[
h3("几何参数"),
p(f"梁高:{beamHeight}"),
p(f"梁宽:{beamWidth}"),
info("单位统一采用 SI 制。"),
],
classes="my-3 p-3 border",
)
P(parameterPanel)
插入图片、代码、LaTeX 与 Matplotlib 图:
Img("assets/section.png", alt="截面示意图", width=480)
Code(
"""
stress = force / area
""",
language="python",
)
LaTex(r"\sigma = \frac{N}{A}")
import matplotlib.pyplot as plt
hide()
fig, ax = plt.subplots()
ax.plot([0, 1, 2], [0, 1, 4])
show()
Plot(fig, width=520)
注意:
children,用户输入或外部文本应先自行清洗后再拼入 HTML。children 列表会按顺序直接拼接,适合嵌套由 p()、div()、span() 等返回的 HTML 片段。img() 会额外包一层居中容器;设置 alt 时会在图片下方显示说明文字。Plot() 支持 Matplotlib savefig 对象,也支持 PNG 二进制数据;普通文件路径图片使用 Img()。# 普通变量赋值(自动渲染公式)
force = 100 * unit.newton
area = 2 * unit.meter**2
stress = force / area
# 别名(用于中文变量名或复杂下标)
alias("rhoWater", "ρ_水")
rhoWater = 1000 * unit.kilogram / unit.meter**3
alias("rhoWater", None) # 传 None 移除别名
# f-string:默认只显示结果
f"应力为 {stress}。"
# 启用后同时显示公式和结果
enable_fstring_equation()
f"应力为 {stress}。"
disable_fstring_equation()
# 海象运算符在 f-string 中赋值
f"面积 = {(A := 3 * unit.meter**2)}"
from uzoncalc import unit
l = 5 * unit.meter
f = 100 * unit.newton
p = f / (l * l) # 自动单位运算
v = l.to(unit.centimeter) # 单位换算
# 常用单位:meter/m、kilogram/kg、newton/N、MPa、kN、second/s、hour、kilometer/km 等
# 完整列表见 pint 文档
hide() # 后续内容不输出到文档
def helper(): ... # 辅助函数定义,不渲染
show() # 恢复渲染
inline() # 后续元素内联排列
x = 1; y = 2
endInline() # 结束内联
enable_substitution() # 开启变量值代入(默认开启)
disable_substitution() # 关闭代入(仅显示符号公式)
Table(
headers=[ # 表头支持多行、th 合并单元格
[
th("构件", rowspan=2),
th("材料", rowspan=2),
th("弹性模量 (MPa)", colspan=2),
],
["Ec", "Es"],
],
rows=[ # 二维列表表示多行
["盖梁", "C60", 36000, 34500],
["墩柱", "C50", 34500, 32500],
],
title="材料参数",
)
# Td 可设置单元格样式;Tr 可设置整行样式
Table(
headers=["项目", "数值", "备注"],
rows=[
Tr(
[
Td("梁高", classes="font-bold"),
1.8 * unit.meter, # 任意值会通过 str() 渲染
Td("控制参数", classes="text-red-600"),
],
classes="bg-yellow-50",
),
Tr(["混凝土等级", "C50", None]), # None 会显示为 "None"
],
)
# 扁平 rows 表示单行;Td 列表也会作为单行处理
Table(
headers=["名称", "值"],
rows=[Td("宽度", classes="font-bold"), 2.5 * unit.meter],
)
生成图表的过程不需要显示过程,若图表复杂,在单独的函数中定义。 静态图首先使用 svg 方式,交互式图表使用 echarts 方式。
echarts 图表
通过 echarts 生成交互式图表, 在使用中,若对 echarts 中的参数不确定,读取 https://echarts.apache.org/zh/option.html 读取文档
# ECharts 交互式图表(推荐)
from uzoncalc.extension.echarts import use_echarts, EChart, Javascript
EChart({
"xAxis": {"type": "category", "data": ["Mon", "Tue", "Wed"]},
"yAxis": {"type": "value"},
"series": [{"type": "bar", "data": [120, 200, 150]}],
})
# use_gl=True 时,渲染 ECharts GL 3D 图表
EChart({...}, use_gl=True)
svg 图表
对于静态图表,建议使用 svg 方式,以保持图表的清晰度和可打印性。
Matplotlib 图表
也可以使用 Matplotlib 生成静态图表
# Matplotlib 静态图(适合打印)
import matplotlib.pyplot as plt
hide()
def make_fig():
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])
return plt
show()
Plot(make_fig())
from uzoncalc import UI, Field, FieldType
inputs = await UI(
"结构参数",
[
Field("width", "宽度", FieldType.number, value=10),
Field("height", "高度", FieldType.number, value=5),
Field("mat", "材料", FieldType.selectOne, options=["C30", "C40", "C50"]),
],
)
width = inputs.width * unit.meter
FieldType 可选值:text、number、selectOne、selectMany、boolean、textarea
from uzoncalc.extension.excel import get_excel_table
P(get_excel_table(
excel_path="examples/calc.xlsx",
values={
"Sheet1!A2": 6,
"Sheet1!B2": 10,
},
range="Sheet1!A1:C3",
))
# 在函数内部保存
save("output/result.html")
# 在函数外部保存
ctx = run_sync(sheet)
ctx.save("output/result.html")
生成的 HTML 可用浏览器打印为 PDF,或用 pandoc 转为 Word。
if __name__ == "__main__":
ctx = run_sync(sheet) # 同步执行(静默模式,UI 用默认值)
ctx.save("output.html")
# 多个计算书
ctx1 = run_sync(sheet1)
ctx2 = run_sync(sheet2)
ctx1.save("out1.html")
ctx2.save("out2.html")
hide() / show() 包裹@uzon_calc() 函数外,其他函数均不被渲染_ 渲染为下标,命名时应使用 camelCasearr[0, 1] 自动渲染为下标形式@uzon_calc() 函数支持相互嵌套调用,内层函数的内容合并到当前上下文@uzon_calc() 函数中编写,不要单独封装,其它函数不会渲染