在金融分析与投资研究领域,上市公司财报解读是最基础也最耗时的工作之一。一份完整的年度财报篇幅较长,不仅包含资产负债表、利润表、现金流量表、股东权益变动表等核心报表,还涵盖附注中大量明细数据。分析师需从中提取关键数据并生成可视化图表,方能形成投资判断。传统做法通常需要人工翻阅 PDF、手动录入 Excel、手工绘制图表并撰写分析结论,整套流程耗时 4-8 小时,且极易因数据录入错误导致结论偏差。
但解析只是第一步。在真实的投研与财务建模流程里,数据最终要落到分析师自己的估值模型里。而估值模型恰恰是整个工作流中最"娇贵"的部分:它通常由分析师经年累月打磨而成,内含大量自定义宏(VBA)、数据透视表以及层层嵌套的复杂公式。传统做法只能靠人工把数据一格一格敲进去——之所以不敢用脚本批量写入,是因为绝大多数第三方 Excel 库在读写文件时会重建工作簿结构,结果是宏指令丢失、数据透视表失效、嵌套公式被改成静态值,一个精心维护的模型就此报废。
本文用两个前后衔接的案例,借助 Spire.Agent.Office 的 Excel AI 能力,串起从「PDF 财报」到「估值结论」的完整链路:
有关产品安装和 SpireToken 配置,请参考 在 .NET 项目中集成 Spire.Agent.Office。以下示例默认已安装 Spire.Agent.Office 并完成 SpireToken 配置。
对比传统SDK API处理
| 传统 Spire.Office for .NET API | Spire.Agent.Office 处理 | |
|---|---|---|
| 驱动方式 | 编写 PDF 解析 + 单元格写入 + 图表创建 + 公式计算代码 | 用自然语言描述目标,AI 理解后自动编排执行路径 |
| 代码量 | 两个案例合计通常需要 800-1500 行 C# 代码(含 PDF 表格定位、行列解析、图表配置等) | 约 20 行调用代码 + 两条自然语言指令 |
| 表格识别 | 需手动定位 PDF 中表格位置,处理跨页表格拆分、合并单元格等逻辑 | AI 自动识别文档中的表格结构,理解表头和层级关系 |
| 图表生成 | 需手动创建 Chart 对象、配置数据区域、设定图表类型和样式 | AI 根据数据语义自动选择最合适的图表类型 |
| 数据注入 | 需硬编码"源表第 N 行 → 模板第 M 行"的映射表,报表口径一变就要改代码 | AI 按科目名称语义匹配,源报表行列顺序变化不影响结果 |
| 宏与透视表 | 需自行处理 VBA 工程与透视缓存的保留逻辑,稍有不慎即损坏 | 原样保留宏指令、数据透视表与图表,AI 只写入目标单元格 |
| 需求变更 | 新增分析维度需改代码 → 编译 → 部署 | 修改指令中的描述,即刻生效 |
案例一:长文本财报数据提取与分析
AI 读取 PDF 财报文件,自动识别其中的财务报表表格并提取至 Excel 文件中,同时自动生成可视化图表与财务分析。整个过程仅需一份代码、一条指令。
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Xls;
// 需要处理的 PDF 财报文件(作为附件传入)
string[] attachmentPaths = new string[] { @"C:\FinancialReport\上市公司2025年度报告.pdf" };
// 结果 Excel 文档的保存路径
string savePath = @"C:\FinancialReport\分析结果.xlsx";
// SpireToken Key(需在官网页面申请)
string key = "sk-***************************";
// 自然语言指令
string instruction =
"请按以下步骤处理附件文件: " +
"1. 提取财务报告板块中的所有表格,每张表格独立为一个工作表,工作表名与原始表格名保持一致。 " +
"2. 严格保留原始数据,不添加、不修改任何数值。 " +
"3. 应用适当格式提升表格可读性。 " +
"4. 将跨页表格合并到同一张工作表中。 " +
"5. 为每张表格的数据生成合适的图表。 " +
"6. 直接使用提取的原始数据制图,不添加、不修改任何数值。 " +
"7. 基于提供的数据,分析并总结公司的财务状况与变化趋势。";
// AI 生成
AIResult result = AnalyzeFinancialReport(instruction, savePath, key, attachmentPaths);
// AI 辅助的财报分析处理
static AIResult AnalyzeFinancialReport(string instruction, string savePath, string key, string[] attachmentPaths)
{
// 配置 AI 处理选项
AIOptions options = new AIOptions();
options.SpireToken = key;
options.TimeoutMs = 10000000;
using (Workbook wb = new Workbook())
{
AIDocumentProcessor processor = wb.AI(options);
return processor.ExecuteInstruction(wb, instruction, savePath, attachmentPaths);
}
}
财报数据处理与图表分析结果:
说明:原输入文件
输出结果包含两部分:
说明:从 PDF 财报中提取的表格数据,并生成对应的可视化图表。
说明:基于提取的数据生成的财务分析结论。
案例二:财报数据注入预设估值模型
案例一产出的是"数据",案例二要做的是"建模"。整个过程的输入有两份:预设的估值模型模板(.xlsm,内含宏、数据透视表与嵌套公式)与案例一产出的财报数据工作簿(.xlsx)。AI 读取财报数据,按科目名称对应关系注入模板的「数据录入」工作表,模型内的公式随即重算,估值曲线自动更新。
using Spire.Agent.Office.AI;
using Spire.Agent.Office.Extensions;
using Spire.Xls;
// 预设的估值模型模板(含宏 / 数据透视表 / 嵌套公式 / 估值曲线图)
string inputPath = @"C:\FinancialReport\估值模型模板.xlsm";
// 案例一产出的财报数据工作簿(作为附件传入)
string[] attachmentPaths = new string[] { @"C:\FinancialReport\分析结果.xlsx" };
// 结果文档路径(此处为 null,将使用下面设置的输出文件夹路径)
string savePath = null;
// 输出目录
string OutDir = @"C:\FinancialReport\output";
// SpireToken Key(需在官网页面申请)
string key = "sk-***************************";
// 自然语言指令
string instruction =
"读取附件中的财报数据,按科目名称对应填入当前估值模型模板的「数据录入」工作表,本期与上年同期分别填入对应两列;" +
"只填写浅黄色底纹的单元格,不要改动已有公式;" +
"保留模板中已有的宏、数据透视表、公式与图表;" +
"填入后重算模型、刷新数据透视表,并更新「估值曲线」;" +
"最终保存为启用宏的 Excel 文件";
// AI 生成
AIResult result = InjectDataIntoModel(instruction, inputPath, savePath, key, OutDir, attachmentPaths);
// AI 辅助的估值模型数据注入处理
static AIResult InjectDataIntoModel(string instruction, string inputPath, string savePath,
string key, string output, string[] attachmentPaths)
{
// 配置 AI 处理选项
AIOptions options = new AIOptions();
options.WorkDir = output; // 设置工作目录为输出目录
options.SpireToken = key; // 设置 SpireToken Key
using (Workbook workbook = new Workbook())
{
// 从文件加载估值模型模板
if (!string.IsNullOrEmpty(inputPath) && File.Exists(inputPath))
{
workbook.LoadFromFile(inputPath);
}
// 创建 AI 文档处理器
AIDocumentProcessor processor = workbook.AI(options);
// 执行 AI 指令
return processor.ExecuteInstruction(workbook, instruction, savePath, attachmentPaths);
}
}
注入前的估值模型模板:
说明:预设的估值模型模板,浅黄色单元格为待注入的数据区。
案例一产出的财报数据工作簿,作为本次注入的数据来源填充到估值模板的数据录入区:
说明:填充合并资产负债表、合并利润表、合并现金流量表等其中的数据。
注入后自动重算得到的估值曲线:
说明:数据注入完成后,模型自动重算并刷新的估值曲线。
常见问题
提取的表格数据与 PDF 不一致
原因:PDF 中的表格可能包含跨页拆分、合并单元格、旋转文本等复杂布局,AI 在识别时可能出现偏差。
解决:在指令中添加"仔细核对数据准确性,特别注意合并单元格和跨页表格的拼接";或限定具体的页码范围分批次提取,审核后再整合。
注入数据后估值曲线不更新
原因:模型重算与数据透视表刷新是两步独立动作。仅写入数据不会自动刷新透视缓存;部分阅读器也不会主动重算整条公式链。
解决:在指令中显式要求"填入后重算模型、刷新数据透视表"。此外,模板中可设置打开时强制重算,确保曲线始终为最新值。
获取SpireToken Key
- 联系 该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。 或访问 https://www.e-iceblue.com/TemLicense.html 获得试用/商业 API 密钥
在代码中配置:
AIOptions options = new AIOptions();
options.SpireToken = key;






