发布于 2026-01-05 2 阅读
0

Python 自动报表制作 - 第一部分:从规划到 Hello World

Python 自动报表制作 - 第一部分:从规划到 Hello World

我想记录并逐步演示用 Python 实现一个简单的概念:创建一个自动 HTML 报告工具。

最终会生成一个独立的HTML文件。HTML文件是一个很棒的报表工具:即使没有后端服务器,你也可以在一个页面中打包大量信息,并实现便捷的交互功能。

平心而论,这并不是一个多么令人兴奋或引人注目的项目。尽管如此,自动生成报告却是一项非常实用的技巧,尤其是在商业环境中。正如人们常说的,把枯燥乏味的事情自动化。

就我个人而言,我主要打算用它来自动生成机器学习领域模型性能的报告,但你当然也可以把它用于任何场景!

当然,类似的工具已经存在了。但我想要自己开发一个,因为它能给我带来更多经验和灵活性。

本指南是如何呈现的?

我不想只提供一段能运行的代码,而是想一步一步地逐步推进开发。你会看到我看到的——我写的代码!

就我个人而言,我一直觉得这种类型的教程更有效:

  • 它能让你了解其他人是如何解决问题的。
  • 这实际上反映了我的编码方式——逐个功能地实现,逐次提交地进行编码。

这是给谁看的?

本文假定读者已对 Python 有一定了解。我不会赘述标准语法等内容,但会确保在遇到特别棘手的问题时及时解释。我也会尽可能引用更清晰易懂的解释。


第一步——停下来一分钟

我其实是化学工程师出身。虽然我确实从这个专业背景中学到并运用了很多实用或深奥的知识,但我学到的最有用的建议或许也是最简单的:

遇到新问题时,画一幅图。

我说的“画出来”,是指把问题外化。把它画出来,把想法和思路都写在纸上。

在着手这个(规模相对较小的)项目之前,我坐下来花了 10-15 分钟,勾勒出我认为我可能会如何着手,哪些部分会移动,哪些部分会保持静止,以及项目的(非常)粗略结构。

我自己画的草图几乎难以理解,如下所示。

早期规划的一些关键经验

根据我早期的“计划”,一些事情变得清晰起来:

  • 使用HTML 模板系统非常合理。这类系统旨在将动态内容插入静态模板:这正是我们所需要的。在 Python 中,Jinja是一个常见的选择,任何使用过Flask 的人可能都比较熟悉它。
  • 在机器学习领域,我不断发现一些值得关注的新事物,或者比较模型的新方法,或者分析数据集的新方法——因此,报告的内容以及我可以添加到任何报告中的功能都应该是灵活的。
  • 我处理的大部分数据都是 .csv 格式,所以如果能有工具处理这种格式并从中生成可查询的 HTML 代码块就太好了。

第一步——奠定基础

对于任何规模大于在命令行中摆弄几分钟的项目,我都喜欢建立一个 Github 仓库和一个一致的环境。

我认为这将是一个规模相当小的项目,所以我并不太在意制定完整的项目结构,但为了方便日后参考,熟悉一下还是很有必要的。

这:

  • 鼓励养成保持项目清洁的良好习惯
  • 它能帮助我轻松地从我的Mac笔记本电脑切换到我的Linux桌面(或者任何其他环境)。

先给我们几个简单的目标:

建立虚拟环境

我们希望为这个项目创建一个独立的 Python 实例,也就是“虚拟环境”,而不是使用机器上现有的通用 Python 安装。这样可以隔离依赖项,也方便项目迁移。我使用的是 PyCharm,它允许你从一开始就创建新的虚拟环境。

为了便于迁移,我将requirements.txt在项目目录的根目录中保留一个文件,详细说明环境中需要哪些软件包。

关于这个主题有很多很多指南可以参考这些指南了解更多具体细节

设置 Git/GitHub 仓库

为了实现版本跟踪并允许与 GitHub 进行双向传输,我们将在本地(项目文件夹中)初始化一个 Git 仓库,并在 GitHub 上创建一个新仓库。然后可以将本地 Git 仓库推送到 GitHub。

Github.com 上提供了一份简明指南

作为使用 Git/Github 代码库的常规操作,我们会将以下内容添加到项目根目录:

  • 一份readme.md简要描述项目的文件,以及
  • 一个.gitignore用于指定哪些文件和文件夹不应被 Git 跟踪并推送到 GitHub 的文件。这可能包括自动生成的文件(例如来自 IDE 或虚拟环境的文件)、敏感文件和配置数据,或者任何其他您在本地创建且无需与外界共享的内容。对我来说,它看起来像这样:
# .gitignore

# Don't add the virtual environment, IDE, and Jupyter notebook info
venv
.idea
.ipynb_checkpoints
Write-up.ipynb
Enter fullscreen mode Exit fullscreen mode

GitHub 状态

至此,你的项目框架应该大致如下所示


第二步——“Hello, World”模板

目前,我们已经有了一个简单的项目结构,可以开始填充代码和模板了。为了进行一些简单的测试,并为后续开发奠定基础,我想创建一个尽可能简单的报告。

第一个实现版本应该不输入任何信息,并输出一个简单的“Hello, world!”HTML页面。

模板制作简介

本项目基于模板和模板处理器的概念构建。这是网络出版领域一个庞大而又至关重要的领域。

简单来说:我们将HTML页面的结构和要发布的内容分开。当需要生成新的网页(或者在本例中,生成报告!)时,我们可以将内容输入到标准化的结构中,然后生成新的网页。

模板现在已经非常普遍了,但如果你想了解没有一致的手动或自动模板的生活是什么样的,你可以在Geocities 的存档中找到许多不带讽刺意味的迷人例子。

构建“Hello, World”功能

基于结构内容之间的这种区别,我们可以创建非常简单的示例来测试系统。

结构

在这种情况下,我们的结构是一个几乎为空的 HTML 页面,其中包含用于输入数据的位置。我们称之为“模板”,并将其与其他模板一起存储template在项目根目录下的一个文件夹中。我们将在该文件夹下创建一个新的 HTML 文件{project_folder}/template/report.html。该文件的内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ content }}</title>
</head>
<body>
{{ content }}
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

请注意花括号内的元素(本例中为花括号——` &`{{和 `& }}`)。动态内容将在此处输入。

像 Jinja 这样的模板处理器功能非常强大,除了简单的插入之外,它还允许在模板中添加许多其他功能。请查看Jinja 主页上的第一个示例,看看您是否能理解它。

内容

目前,我们的内容可以很简单,例如hello, world!

我们将在项目目录的根目录下创建一个名为 `<filename>` 的新文件{project_folder}/autoreporting.py,并首先将我们的“内容”硬编码进去。

content = "Hello, world!"
Enter fullscreen mode Exit fullscreen mode

功能

我们已经有了结构和内容——现在我们只需要使用 Jinja 将它们结合起来。

首先,创建一个outputs目录并将其添加到你的.gitignore文件中。我们会把创建的内容放到这个文件夹里,但你没必要把最终存在这里的任何内容都放到你的仓库里。

Jinja 需要一个Environment对象来存储和定义诸如配置和加载器之类的东西——也就是我们从中获取模板的地方。在本例中,我们运行在本地文件系统上,因此FileSystemLoader指定在目录中搜索templates即可。

利用我们的env实例,我们可以渲染基本模板并将其写入文件。

我们的autoreporting.py脚本现在看起来像这样:

from jinja2 import FileSystemLoader, Environment

# Content to be published
content = "Hello, world!"

# Configure Jinja and ready the template
env = Environment(
    loader=FileSystemLoader(searchpath="templates")
)
template = env.get_template("report.html")


def main():
    """
    Entry point for the script.
    Render a template and write it to file.
    :return:
    """
    with open("outputs/report.html", "w") as f:
        f.write(template.render(content=content))


if __name__ == "__main__":
    main()

Enter fullscreen mode Exit fullscreen mode

注意参数 ` template.render, content=content`。它将模板和我们的代码关联起来。第一个content参数指的是模板中的值{{ content }},第二个参数是脚本中定义的字符串。我们定义了这种关系,并将该字符串传递给模板进行替换。

目前的结果

如果运行此脚本并且一切顺利,report.html将会在指定目录下创建一个新文件outputs/。打开此文件,看看你创造了什么!


这当然符合“非常简单但实用”的标准。

如果你检查页面的 HTML,你会注意到{{ content }}模板中的标签被巧妙地替换成了Hello, world!字符串,这就是问题的关键所在。

GitHub 状态

你已经开发了一个新功能,所以现在是提交并推送到 Github 的好时机。

你的仓库应该看起来像这样

后续步骤

记者边走边工作,但我们目前确实没有任何实质性的发言权或灵活性。下一步,我们将探索如何读取数据并生成报告,并开始使用 JavaScript 和 CSS。

文章来源:https://dev.to/goyder/automatic-reporting-in-python---part-1-from-planning-to-hello-world-32n1