跳到主要内容

analytics

---
title: "实时财务分析"
tags:
[
Beancount,
Fava,
财务分析,
开源会计,
个人理财,
小企业财务
]
keywords:
[
实时分析,
复式记账,
纯文本账本,
财务可视化,
仪表盘集成
]
description: "了解 Beancount 和 Fava 如何提供一种简化的实时财务分析方法,从而增强您通过强大的可视化和集成来管理财务的能力。"
image: "https://opengraph-image.blockeden.xyz/api/og-beancount-io?title=%E4%BD%BF%E7%94%A8%20Fava%20%E5%92%8C%20Beancount%20%E8%BF%9B%E8%A1%8C%E5%AE%9E%E6%97%B6%E8%B4%A2%E5%8A%A1%E5%88%86%E6%9E%90"
authors: [mike]
---

# 使用 Fava 和 Beancount 进行实时财务分析

## 引言

**Beancount** 是一个开源的复式记账系统,它使用纯文本文件作为账本。它强调在财务跟踪方面的简单性、透明性和灵活性。**Fava** 是 Beancount 的一个强大的基于 Web 的前端,它提供了一个交互式的界面,用于查看报表、可视化效果和管理您的账本。在本报告中,我们将探讨 Beancount 和 Fava 的核心功能,以及如何使用这些工具实现实时或接近实时的财务分析。我们将介绍自动化和数据刷新的配置技巧、Fava 的可视化功能(用于即时现金流视图和趋势分析)、与外部仪表盘(Grafana、Metabase 等)的集成、自定义仪表盘和插件的示例、在个人和小企业财务中的用例、与其他平台(Power BI、QuickBooks)的比较,以及使用 Fava+Beancount 进行数据驱动洞察的优缺点。

![analytics](https://opengraph-image.blockeden.xyz/api/og-beancount-io?title=%E4%BD%BF%E7%94%A8%20Fava%20%E5%92%8C%20Beancount%20%E8%BF%9B%E8%A1%8C%E5%AE%9E%E6%97%B6%E8%B4%A2%E5%8A%A1%E5%88%86%E6%9E%90)

## Beancount 和 Fava 的核心功能

### Beancount(纯文本会计引擎)

- **纯文本格式的复式账本:** Beancount 将交易存储在单个 `.beancount` 文本文件(或一起包含的多个文件)中。每笔交易必须在帐户之间保持平衡(借方总额 = 贷方总额),从而确保会计的完整性。纯文本格式意味着您的数据是人类可读的、可版本控制的,并且不会被锁定到任何供应商。
- **灵活的、分层的帐户:** 您可以在层次结构中定义任何帐户(例如 `Assets:Bank:Checking`、`Expenses:Food:Coffee`)。Beancount 不会限制您的会计科目表,因此它适用于个人理财、小企业账簿、投资等——它是 _“灵活的:适用于个人理财、小企业簿记、加密货币、股票投资等等。”_
- **多种货币和大宗商品:** Beancount 对多种货币和大宗商品(例如股票、加密货币)具有一流的支持。您可以用不同的货币记录交易,定义汇率(价格指令),并跟踪成本基础。如果提供价格数据,它可以生成“按成本”或“按市场价值”的报告。这使其适用于投资组合和国际金融。
- **自动检查和平衡:** 该系统支持**余额断言**(您可以声明帐户在某个日期的余额_应该_是多少,如果余额不匹配,Beancount 将报错)和用于结账的**余额交易**。它还支持**权益开盘/收盘分录**,并保留期间结束的留存收益计算。这些有助于确保您的账簿保持一致并及早发现错误。
- **强大的查询和报告引擎:** Beancount 配备了一种查询语言 BQL (Beancount Query Language) 和命令行工具,如 `bean-balance`、`bean-register` 和 `bean-query`,用于生成报告。您可以查询账本以获取自定义报告(例如,按收款人列出的费用列表、期间内的现金流)——本质上是将账本视为数据库。即使有成千上万的交易,它也很快,并且可以输出到 CSV,甚至直接输出到 Excel/LibreOffice(带有可选的插件)。
- **通过插件进行扩展:** Beancount 是用 Python 编写的,并允许自定义**插件**来扩展其功能。插件可以在处理文件时强制执行额外的规则或计算。(例如,有一些插件可以处理税务批次,或者确保没有遗漏成本的购买。)插件系统和 Python API 让高级用户可以编写自定义行为脚本或将 Beancount 与其他系统集成。
- **外部数据导入器:** 一个关键的实用功能是 Beancount 的 _ingest_ 框架,用于导入数据(例如,从银行对账单)。您可以编写或使用导入器插件来解析 CSV、OFX、PDF 报表等,并将它们转换为 Beancount 条目。这对于自动化至关重要(稍后会详细介绍)。
- **可审计和版本控制友好:** 因为它是纯文本,所以您可以将您的账本保存在 Git 或其他版本控制系统中。每个更改都是透明的,并且您拥有完整的编辑历史记录。这使得审计或审查更改变得简单明了(许多用户每天都会将更改提交到 Git 存储库,从而提供所有财务条目的防篡改日志)。这种级别的透明度是封闭式会计软件的主要区别——_“没有 SaaS 锁定——只有干净、透明的会计,具有强大的报告功能。”_

### Fava(Beancount 的 Web 界面)

- **交互式 Web UI:** Fava 提供了一个本地 Web 服务器,将您的 Beancount 账本呈现为一个丰富的 UI。它在浏览器中显示核心报告(损益表、资产负债表等)、帐户注册和日记帐,并带有交互式控件。与命令行相比,该 UI 是动态的且用户友好的。您只需使用 `fava yourfile.beancount` 即可启动它,并获得一个用于您的账簿的 Web 应用程序。
- **内置的图形和图表:** Fava 生成图形以帮助您可视化您的数据。例如,它包括一个随时间变化的 **净值** 折线图、每月收入与费用的条形图以及用于费用细分的饼图/树状图。这些视觉效果会随着您的数据而更新,并支持不同的视图(例如,投资的“按成本”与“按市场价值”)。稍后我们将详细探讨这些可视化功能。
- **过滤和搜索:** 在 Fava 页面的顶部,一个过滤器栏让您可以实时地对您的数据进行切片和切块。您可以按时间(例如年、季度、月)、按帐户正则表达式、按收款人、按说明或按标签/链接进行过滤。这使得进行_实时数据检查_变得容易——例如,快速过滤到“Tag=Travel”和“Year=2025”以查看 2025 年的所有差旅费用,并显示总计。该界面通过此过滤器栏或通过“查询”页面(您可以在其中直接执行 BQL 查询)支持复杂的查询。
- **多文件支持和合并:** Fava 可以一次加载多个 Beancount 文件(如果您分隔了账本,这将非常有用)并在它们之间切换。如果需要,它也可以合并它们(例如,同时查看个人和企业账本)。
- **数据录入和编辑:** 独特的是,Fava 不是只读的——它有一个**编辑器**和交易录入表单。您可以通过 Web 表单添加新交易(它会将条目插入您的 .beancount 文件中)。您还可以从 Fava 在外部编辑器中打开源文件。Fava 甚至支持 _“Gmail 风格”_ 的键盘快捷键(在 UI 中按 `?` 可查看它们),供高级用户使用。这会将 Fava 变成一个轻量级的会计系统,您可以在同一个界面中输入和查看数据。
- **报告和帐户钻取:** Fava 提供了标准的会计报告:损益表(利润和损失)、资产负债表、试算平衡表和投资的持有清单。**资产负债表**和**损益表**是交互式的——您可以单击一个帐户以深入了解其详细信息,或者在查看资产的成本与市场价值之间切换。如果您有价格数据,Fava 还会显示投资的“未实现收益”。它会生成所有条目的**日记帐**视图,并允许按各种标准过滤该日记帐(非常适合查找特定交易)。
- **文档管理:** 如果您附加了收据或报表,Fava 会帮助您组织这些收据或报表。Beancount 有一个文档文件夹的概念,Fava 让您可以将文件拖放到帐户或交易上——它会将它们存储起来并在您的账本中添加一个文档条目。这对于将支持文档与您的账本数据链接起来非常有用。
- **通过扩展进行自定义:** 可以使用(用 Python 编写的)插件来扩展 Fava,以添加新报告或功能。某些扩展是捆绑在一起的(例如,用于投资的**投资组合列表**报告)。稍后我们将讨论自定义扩展,但本质上,Fava 的设计允许通过其扩展 API 注入新页面,甚至自定义 JavaScript。这意味着,如果某个分析或仪表盘不是内置的,则高级用户可以添加它。
- **性能:** Fava 是高效的——它将数据重新加载到内存中并快速提供页面。底层 Beancount 解析非常快(在最新版本中进行了 C++ 优化),因此即使是大型账本也可以在一两秒内加载完毕。在实践中,Fava 可以处理多年的个人账本,尽管非常大的文件(数万笔交易)可能会受益于一些优化(例如,存档旧条目)。
- **Web 访问和移动性:** 通过在服务器甚至您的笔记本电脑上运行 Fava,您可以从任何浏览器访问您的财务数据。一些用户将 Fava 托管在专用服务器或 Raspberry Pi 上,以便他们可以随时随地查看他们的财务数据(可能会将其隐藏在密码或 VPN 后面,因为 Fava 没有内置的身份验证)。这本质上为您提供了一个用于您的财务数据的自托管“Web 应用程序”,而无需将您的数据交给第三方。

**总而言之**,Beancount 为透明的、基于文本的会计提供了一个稳健的基础,它具有严格的复式规则和多货币支持。Fava 通过提供一个可访问的界面,具有即时洞察力(报告、图表)和与您的数据交互的能力,从而构建了该基础。它们共同构成了一个高度灵活的会计和分析系统,您可以端到端地控制它。

## 使用 Beancount 和 Fava 进行实时(或接近实时)分析

使用 Beancount 和 Fava 实现**实时或接近实时分析**涉及到自动化数据流入您的账本的过程,并确保这些工具显示最新的信息。默认情况下,Beancount 是一个批处理过程(您将条目添加到文件中,然后查看报告),Fava 会检测更改并需要刷新。但是,通过正确的设置,您可以简化更新,以便新的交易和更改几乎立即显示。

**文件更改检测:** Fava 监视账本文件的更改。如果您在编辑器中编辑 `.beancount` 文件(或包含文件),Fava 将显示一个“检测到更改 - 单击以重新加载”横幅。单击(或按重新加载)后,它会重新加载数据并更新视图。在实践中,此重新加载非常快(对于典型的账本,通常不到一秒钟)。这意味着,如果您的账本文件经常更新,Fava 可以充当一个实时仪表盘。(在调试模式下,Fava 甚至可以在文件更改时自动重新加载,但默认情况下,它会等待用户确认,以避免中断您的视图。)

**持续导入/更新管道:** 要获得实时数据,您需要自动化将交易添加到 Beancount 文件的过程。有几种常见的策略:

- **计划导入作业(Cron):** 许多用户设置一个 cron 作业(或计划任务),以定期(例如每晚或每小时)从金融机构获取新的交易,并将它们附加到账本中。例如,您可以使用 Beancount **导入器插件**通过 API 或 OFX 下载来获取最新的银行交易。一位 Beancount 用户构建了一个自动化管道,以便他们的账簿自行更新:_“看到我的会计账簿在没有我触摸它的情况下以开放格式自行更新,这给我带来了纯粹的快乐”_。这是通过连接到银行 API 并安排定期更新来实现的。诸如 `bean-fetch`(用于 OFX)之类的工具或使用银行 API(例如 Plaid)的自定义 Python 脚本可以按计划运行,并将新条目写入账本。在每次计划的导入之后,如果您正在运行 Fava,您可以简单地刷新 Fava 以查看新数据。

- **文件监视程序和触发器:** 除了基于时间的计划之外,您可以使用文件监视程序来响应事件。例如,如果您的银行可以通过电子邮件向您发送每日对帐单,或者您将 CSV 放到一个文件夹中,则脚本可以检测到该文件(在 Linux 上使用 `inotify` 或类似工具),并立即运行导入例程,然后向 Fava 发出重新加载信号。虽然 Fava 尚未支持将实时重新加载推送到浏览器,但您至少可以更新数据,以便下次您检查页面或单击重新加载时,它是最新的。一些社区项目更进一步:对于 ledger(Beancount 的一个近亲),一位用户创建了一个小型服务器,该服务器将 ledger 数据实时公开给 Grafana,这表明可以使用类似的方法来处理 Beancount——本质上是构建一个守护程序,该守护程序不断地将数据馈送到您的仪表盘。

- **直接 API 集成:** 除了通过文件之外,高级用户可能会直接连接到银行 API(如 Plaid 或区域性开放银行 API)以频繁地提取交易。有进取心的人可以在一个循环中编写“实时”导入脚本(具有适当的速率限制)——有效地每隔几分钟轮询银行以获取新数据。没有什么可以阻止您_“注册 Plaid API 并在本地执行相同的[自动化]”_。每笔新的交易都可以在到达时附加到 Beancount 文件中。使用此方法,Fava 真正成为您帐户的实时仪表盘,可与商业应用程序中的最新提要相媲美。

**Fava 中的数据刷新:** 一旦您的数据被更新,让 Fava 显示它是很简单明了的:浏览器刷新 (F5) 或单击重新加载横幅将加载最新的账本状态。如果您不想单击,使用 `--debug` 运行 Fava 可以为扩展开发启用自动重新加载,有些人使用它来强制页面在更改时立即重新加载。或者,如果您正在构建自定义前端,您可以让它按计划轮询一个小型 API,该 API 从账本返回最新的余额等。

**即时计算:** Beancount 的快速解析意味着,即使您每隔几分钟更新一次账本文件,从数据获取 → 文件更新 → Fava 重新加载的周转也很快。例如,一位用户指出,对于合理大小的账本,在编辑文件后重新加载 Fava “几乎不明显……绝对少于一秒钟”。因此,您可以保持 Fava 窗口打开并定期点击刷新以模拟实时仪表盘。(要获得真正的实时体验,可以构建一个小脚本来自动刷新浏览器或使用浏览器的每隔 N 秒刷新一次的功能。)

**对帐和警报:** 要信任实时数据,您还需要经常对帐余额。Beancount 通过余额断言和一个 _“最新”指示器_ 使得此操作变得容易。实际上,如果您用某些元数据标记帐户,Fava 会在帐户旁边提供彩色指示器(例如,您可以用 `fava-uptodate` 元数据标记一个帐户,Fava 将根据上次条目是否为最近的余额检查,将其着色为红色/黄色/绿色)。这可以用于快速查看账本中的帐户余额是否与银行的最新对帐单匹配。在接近实时的设置中,您可以自动化每日余额检查(因此每天早上,账本都会包含每个帐户从银行获取的昨天的期末余额)。然后,Fava 的指示器会告诉您自动导入是否遗漏了某些内容或者是否存在差异,从而让您确信您看到的“实时”数据是准确的。

**自动化示例:** 假设您想要**每日现金流更新**。您可以设置一个 cron 作业,使其在每天晚上凌晨 3 点运行:它执行一个 Python 脚本,该脚本使用您银行的 API 来获取最后一天的交易,将它们写入 `import_today.beancount`,然后将该文件附加到您的主账本。它还会写入日终余额断言。当您醒来时,您会打开 Fava——它会显示直到昨天的所有交易,并且您会看到当月的收入/费用已更新。如果您在白天进行了消费,您可以手动添加它(例如,通过 Fava 手机上的新交易表单),或者等待每晚的导入。这种混合方法(主要是自动化的,并且能够手动添加临时条目)可以提供接近实时的快照。另一种方法是保持 Fava 的 **日记帐** 页面打开并将其用作注册表:当您消费时,您可以快速记录交易(就像在支票簿中输入一样)——然后您_是_实时提要。这种方法更手动,但有些用户喜欢它带来的意识。要获得真正_流式传输_的更新而无需手动步骤,您需要投资于编写脚本,并可能使用第三方 API,如上所述。

总而言之,通过将 Beancount 的导入自动化与 Fava 的快速刷新相结合,您可以获得接近实时的财务数据。要获得与 QuickBooks 之类的服务(自动提取银行提要)相同级别的实时提要,可能不是“一键式轻松”,但它**是**可能的——而且重要的是,您可以完全控制和透明地控制整个过程。正如一位纯文本会计倡导者所指出的那样,前期付出一点努力就可以产生一个自动化系统,该系统_“比商业解决方案好得多,而且更加灵活和可扩展”_。在下一节中,我们将看到 Fava 的可视化功能如何让您立即理解这个最新的数据,从而将原始交易转化为洞察力。

## Fava 中的可视化功能(现金流、趋势、实时检查)

([GitHub - beancount/fava: Fava - web interface for Beancount](https://github.com/beancount/fava)) _Fava 的损益表报告(在 Web UI 中)支持丰富的可视化效果,如 **树状图**(如图所示)和旭日图,以便快速了解收入和费用的构成。在此树状图中,每个矩形代表一个费用类别,其大小由其金额决定——您可以立即看到 **租金**(大的绿色块)占据了费用的主导地位。顶部的过滤器栏和控件(右上角)允许更改货币、图表类型和时间段(例如,查看每月数据)。Fava 还提供折线图(例如,随时间变化的净值)和条形图(例如,按月划分的收入与费用),以帮助您发现财务数据中的趋势。_

Fava 最大的优势之一是将账本数据即时转换为可视化的交互式报告。加载账本后,Fava 会立即生成图表,让您可以轻松地一目了然地了解现金流和趋势:

- **收入和费用树状图/旭日图:** 在“损益表”页面上,Fava 可以将您的收入和费用显示为_树状图_或_旭日图_。这些非常适合“一目了然”的现金流可视化。例如,如果您的月度费用显示为树状图,则每个矩形的面积对应于每个费用类别的大小。大的块立即显示您的大部分资金流向何处(例如,租金或抵押贷款、税款等),而较小的块显示较小的费用。这对于_发现_支出方面的_趋势_非常有用——如果“外出就餐”块每个月都在增长,您会在视觉上注意到它。您可以切换到旭日图以查看分层细分(例如,外圈可能会显示“食物”类别中的子类别,如杂货与餐馆)。这些图表会针对您已过滤的任何期间(一个月、年初至今等)进行更新,从而为您提供该期间的**即时现金流可视化**。纯文本会计论坛上的一位用户指出:_“我经常使用收入和费用树状图。它们可以很好地视觉化我们的财务动向。”_——这种即时理解正是 Fava 图表的目标。

- **随时间变化的净值和余额:** Fava 提供了随时间变化的 **净值折线图**(在“资产负债表”或“统计信息”页面上)。此图表绘制了您在每个时间点(按天、周或月)的资产总和减去负债。这对于发现趋势非常有价值——您可以看到您的财务轨迹(例如,稳定上升,或者在某些时候下降)。如果您有投资,您可以切换以显示按成本或市场(如果已记录价格数据)显示价值——例如,您可能会看到您的净值按市场价值随股票价格波动,而按成本则更平滑。Fava 还可以显示随时间变化的帐户余额。如果您单击一个帐户(例如 Assets:Bank:Checking),则该帐户页面会显示该帐户余额历史记录的图形。您可以立即检查您的现金帐户是如何移动的——这实际上是一个现金流图(余额线的斜率表示净现金流)。如果它呈下降趋势,您就知道在该期间您的支出多于收入。通过检查这些趋势,您可能会发现“每个 12 月我的储蓄都会下降(假期费用)”或“我的投资在本季度急剧增长”之类的模式。

- **用于定期比较的条形图:** 在“损益表”视图中,Fava 有“每月利润”、“每月收入”、“每月费用”等标签。选择这些会显示按月划分的条形图。例如,**每月净利润**会将每个月的盈余/赤字显示为一个条形,从而让您可以轻松地比较各个月份的绩效。您可以快速识别异常值(例如,4 月份的一个大的负条表示该月有不寻常的损失/费用)。同样,“每月费用”条形图会按月堆叠或分组费用类别,因此您可以看到哪些类别会波动。这非常适合随时间变化的趋势分析——例如,您可能会注意到您的“旅行”费用每个夏天都会飙升,或者“公用事业”账单在冬天会更高。Fava 本质上为您提供了一些预算应用程序的功能(跟踪趋势),但具有完全的自定义性(因为您可以定义类别以及它们如何汇总)。

- **实时过滤和数据检查:** Fava 中的可视化效果不是静态的;它们与 Fava 的过滤协同工作。假设您要检查一个特定的场景:“我的业务帐户的季度现金流如何?”您可以将时间过滤器设置为 2025 年第 1 季度,并将帐户过滤器设置为您的业务层次结构——Fava 将立即更新图表以显示净收入、费用树状图等,但仅针对该子集。这种交互式切片意味着您可以非常快速地进行临时分析,而无需编写查询。**日记帐**视图还支持实时过滤:您可以按收款人或说明子字符串搜索,并立即看到已过滤的交易列表。如果您正在查看实时数据(例如,您刚刚导入了上周的交易),您可以按 `#uncategorized` 之类的标签进行过滤,以查看可能需要分类的新交易,或者按 `@pending`(如果您标记了待处理的条目)进行过滤,以查看哪些内容尚未清除。这种实时检查功能有助于确保数据质量,因为您可以即时隔离和解决异常情况。

- **现金流量表(间接):** 虽然 Beancount/Fava 不会开箱即用地生成正式的现金流量表(运营/投资/融资细分),但您可以通过自定义查询或构建帐户来模拟它。例如,您可以标记某些交易或使用特定帐户进行投资和融资,然后查询总计。Fava 的查询界面让您可以运行 BQL 查询,例如:`SELECT sum(amount) WHERE account ~ "Assets:Bank" AND year = 2025` 以获取当年的现金流等。也就是说,大多数个人用户发现余额趋势和收入/费用图的组合足以理解现金流。

- **控股和投资组合可视化:** 在“控股”页面上,Fava 列出了您当前的商品(例如股票、债券、加密货币)的持有量,其中包含数量、成本、市场价值和未实现收益。虽然这是一个表格,而不是一个图表,但它对于实时检查您的投资组合状态非常有用。某些扩展(如稍后讨论的 _fava-investor_)会为投资组合添加更多视觉效果,例如资产分配饼图或绩效图表。即使没有扩展,您也可以看到例如您的股票投资组合价值如何随着最新价格的变化而变化——如果您定期更新报价(可以每天自动执行),Fava 的图表将反映您投资的最新市场价值。

在实践中,Fava 的可视化报告会与底层数据一样快地更新。添加新交易并重新加载页面后,图表会立即重新计算。不需要进行长时间的重新处理。这意味着,如果您有一个半自动化的管道在一天中输入数据,您可以保持 Fava 打开并定期点击刷新以获取更新的图表——有效地_实时财务监控_。

例如,假设您正在经营一家小企业,并且您想要监控手头现金和每日费用。您可以将 Fava 打开到一个自定义仪表盘(可能使用扩展或查询屏幕),该仪表盘显示“今日现金帐户余额”和“费用 - 今日与昨日”。每次您在导入新数据后刷新时,您都会看到这些数字更新。这类似于昂贵的实时仪表盘提供的功能,但使用的是开源工具。不同之处在于您可能需要手动刷新或安排刷新,而这些工具会自动推送更新。但从功能上讲,您获得的洞察力是相同的,而且还有一个额外的好处,即您可以深入了解 Fava 上的任何数字(单击它以查看底层交易)——这是许多 BI 仪表盘所缺乏的。

总而言之,Fava 将您的会计数据转换为即时视觉洞察力:**现金流细分、趋势线、随时间变化的比较和交互式过滤** 都有助于您了解数字背后的故事。无论您是检查上周的支出是否存在异常情况,还是查看多年来的净值趋势,Fava 的图表和报告都能实时提供清晰度(只要您的数据存在)。接下来,我们将看到,如果您需要更多自定义分析,您可以如何扩展这些功能或将它们与外部工具集成。

## 与外部仪表盘和可视化工具集成

虽然 Fava 提供了一组丰富的内置报告和图表,但您可能希望将 Beancount 的数据与其他的商业智能 (BI) 或仪表盘工具集成,例如 **Grafana**、**Metabase** 或自定义 Web 前端(例如,一个 React 应用程序)。动机可能是将财务数据与其他数据源组合起来、使用高级图表功能或以不同的格式与其他人共享仪表盘。由于 Beancount 的开放性,有多种方法可以实现集成:

- **数据库集成(Bean_SQL_ / Beanpost):** 一种简单的方法是将您的 Beancount 账本导出或同步到 SQL 数据库。一旦进入 SQL,任何 BI 工具都可以查询数据。实际上,社区成员已经为此创建了工具。例如,**Beanpost** 是一个实验,它将 Beancount 账本镜像到 PostgreSQL 数据库中,并实现了 Beancount 的大部分逻辑作为 SQL 函数。这提供了一个_“灵活的后端,可以与其他工具(如 Web 应用程序或报告系统)集成。”_ 您可以运行 Beanpost 以将您的文本账本持续同步到 Postgres。然后,像 **Metabase** 或 **Tableau** 这样的工具可以连接到该 Postgres 数据库,您可以构建您喜欢的任何图表或仪表盘(随着数据库的更新而实时更新)。一位用户报告说,他们使用 Postgres + PostGraphile 自动为账本数据公开一个 GraphQL API,然后在此之上编写一个自定义 React 前端——本质上是将账本视为 Web 服务。此方法解决了 Fava 的界面可能不足的情况(例如,多用户访问或更适合移动设备的 UI)。它需要更多的工程工作,但它显示了潜力:您可以相对轻松地将 Beancount 与现代 Web 堆栈集成。一个更轻量级的变体是使用 Beancount 的内置 SQLite 支持——运行像 `bean-query -e ledger.beancount "SELECT ..."` 这样的查询可以输出结果,或者使用 Beancount 的 Python API 来获取数据并插入到 SQLite 数据库中。有些人使用 SQLite 作为插件到 Metabase 等工具的中间层(可以通过连接读取 SQLite 文件)。

- **Grafana(时间序列仪表盘):** Grafana 在监控和时间序列数据方面很受欢迎。随时间变化的财务数据(费用、余额)可以被视为时间序列。社区已经讨论过将 Beancount 连接到 Grafana。一种想法是 Grafana **数据源插件**,该插件可以即时针对 Beancount 文件运行 BQL 查询。这将允许 Grafana 面板通过查询账本来直接显示,例如,“支票帐户余额”作为一个仪表盘或“过去 30 天的费用”作为一个图形。截至目前(2025 年),尚未发布专用插件,但爱好者们已经构建了临时解决方案。例如,一位 Reddit 用户 _aquilax_ 构建了一个简单的服务器,该服务器使 Ledger CLI 数据可用于 Grafana,并将其共享为 **grafana-ledger-datasource-server**。类似的概念可以应用于 Beancount:您可以用 Python 编写一个小型的 HTTP 服务器,该服务器加载 Beancount 账本(使用 Beancount 的 API 来查询数据)并公开返回 Grafana 的 JSON 数据帧的端点。Grafana 有一个通用的 JSON 数据源插件,然后可以从此 API 中提取数据。在实践中,这意味着您可以设计一个 Grafana 仪表盘,其中包含诸如“每月收入(条形图)”或“每日现金余额(折线图)”之类的面板,并且这些面板从您的 Beancount 驱动的 API 中获取数据。Grafana 将允许丰富的可视化选项(注释、阈值、与服务器指标结合等)。Andreas Gerstmayr(Fava 的维护者之一)完全建议采用这种方法,甚至提到他创建了一个名为 **fava-dashboards** 的 _Fava 扩展_(稍后会详细介绍),以从 BQL 查询中呈现图表,作为完整 Grafana 设置的替代方案。如果您更喜欢 Grafana 的 UI,那么集成是可行的——它只需要构建数据桥梁。

- **Metabase(临时查询和仪表盘):** Metabase 是一种用户友好的 BI 工具,让您无需编写代码即可运行查询和制作仪表盘。如果您将您的账本导出为关系格式(通过 Beanpost 或通过写出交易、过账等表),您可以将 Metabase 指向该数据库。您可以从您的账本中创建自定义表,例如 `expenses (date, category, amount)`,然后在 Metabase 中您可以轻松地生成图表(例如,上个月按类别划分的费用饼图)。好处是非技术用户(或同事)可以通过 Metabase 的 GUI 与数据交互,而无需接触 Beancount 文件。缺点是您需要维护导出/同步。一些用户已经自动化了 Beancount 账本到 SQLite 的每晚转换,然后让 Metabase 读取 SQLite;其他人可能会使用上面提到的 Postgres 方法。关键是 **Beancount 的数据可移植性使其成为可能**——您可以自由地将数据复制到您的外部工具需要的任何形式。

- **自定义前端/应用程序:** 如果您有特定的需求,您可以始终在 Beancount 之上编写自定义应用程序。Beancount Python 库让您可以访问所有已解析的条目、余额等,因此可以使用 Python Web 框架(Flask、Django、FastAPI)来构建定制的应用程序。例如,一家小企业可以通过查询账本并可能与非账本数据(如服务的客户数量)相结合,来构建一个显示 KPI 指标(如毛利率、每日销售额等)的仪表盘。一位社区成员构建了一个适合移动设备的 Web UI,因为 Fava 对他们的配偶来说不够直观——他们利用数据库中的账本来驱动这个自定义 UI。如果您更喜欢 JavaScript/TypeScript,您可以使用一个工具将账本转换为 JSON 并从那里构建。社区中已经提出了诸如 **beancount-web** 或 **beancount-query-server** 之类的项目,以通过 API 公开 Beancount 数据,尽管 Fava 的 API(如果在“无头”模式下运行)也可以使用——Fava 确实有一个用于内部查询的 API 端点。

- **Excel/PowerBI 集成:** 值得注意的是,您甚至可以与 Excel 或 PowerBI 集成。Beancount(以及通过插件的 Fava)可以将查询结果导出到 CSV 或 Excel 文件。一个工作流程可以是:一个每晚作业从 Beancount 生成一个包含关键财务数据的 Excel 文件,并将 PowerBI 设置为导入该文件。这有点间接,但对于已经大量使用 Excel/PowerBI 的组织来说,这是一个低摩擦的集成。PowerBI 还支持 Python 数据源,因此您可以编写一个运行 BQL 查询的简短 Python 脚本,并将其用作 PowerBI 中的数据源,从而实现直接连接。

**案例研究——Grafana 集成想法:** Beancount 用户 Josh 在邮件列表中询问了将 Beancount 指标推送到 Prometheus 并在 Grafana 中查看的问题。核心开发人员回应说,与在 Prometheus 中复制数据不同,更好的方法是 Grafana 插件或服务,该插件或服务直接查询 Beancount 账本。Andreas 分享了他的 `fava-dashboards` 扩展,该扩展在 Fava 本身中呈现自定义图表作为示例解决方案。要点是:您有多种选择——要么通过现有的 BI 基础设施(Prometheus+Grafana 或 SQL+Metabase)集成,要么扩展 Fava 以满足您的需求(下一节将深入探讨)。

**安全性和多用户注意事项:** 如果集成到外部工具中,请注意数据的敏感性。Beancount 的纯文本通常包含私人的财务信息,因此任何公开它的服务器都应该受到保护(经过身份验证)。如果您将数据移动到云 BI 工具中,您可能会失去一些隐私。自托管工具(Grafana/Metabase 开源版本)可以在本地运行以缓解这种情况。此外,如果有多个人需要查看仪表盘,那么一个外部的只读仪表盘可能比让每个人都访问 Fava 更可取(如果不小心,他们可能会在其中编辑数据)。例如,一家初创公司可以在内部使用 Beancount,但使用 Metabase 让部门主管查看支出与预算,而无需接触账本文件。

总而言之,**Beancount 和 Fava 可以很好地与其他的工具配合使用**。您可以使用整个数据工具生态系统,只需一点粘合代码:将账本数据推送到 SQL 数据库中以用于 BI 工具,通过 API 为 Web 应用程序提供数据,甚至使用专门的库将其流式传输到时间序列系统。这种灵活性意味着,如果 Fava 的内置视觉效果不能满足您的特殊需求,您永远不会陷入困境——您可以始终集成到另一个平台中,同时继续使用 Beancount 作为您的事实来源。接下来,我们将了解如何使用插件和自定义仪表盘来扩展 Fava 本身,如果您只需要几个额外的功能,这通常是一个更简单的途径,而不是外部集成。

## 自定义仪表盘和使用插件扩展 Fava(代码示例)

Fava 被设计成可扩展的:您可以通过用 Python 编写 **Fava 插件(扩展)** 来添加新页面、图表和行为。这允许定制 Web 界面以满足您的特定需求,而无需构建整个单独的应用程序。我们将探讨两种关键的自定义途径:(1)使用或编写 Fava 扩展,以及(2)通过社区插件(如 _fava-dashboards_)设置自定义仪表盘。

### Fava 扩展(自定义插件)

Fava **扩展** 本质上是一个 Python 模块,它定义了 `FavaExtensionBase` 的一个子类。当 Fava 启动时,它可以加载此模块并将其集成到应用程序中。扩展可以注册新的报告页面、挂接到事件,甚至包括用于交互的自定义 JavaScript。某些扩展与 Fava 捆绑在一起(例如,用于投资概览页面的 `portfolio_list`)。其他的可以通过 pip 安装或从头开始编写。

要启用扩展,您需要在您的账本文件中使用 Beancount **custom 指令**:

```bean
2010-01-01 custom "fava-extension" "my_extension_module" "{'option': 'value'}"