如果把企业版 Spreadsheet 模板理解成“存一份 JSON,然后新建时 copy 出去”,你会低估它很多关键机制。documents_spreadsheet 真正做的,是把一个模板变成一份可协作、可追踪、可排序的新文档。
主要参考:
enterprise/documents_spreadsheet/models/spreadsheet_template.pyenterprise/documents_spreadsheet/models/documents_document.pyenterprise/documents_spreadsheet/models/spreadsheet_contributor.py
一、模板生成文档时,复制的不只是 spreadsheet_data
action_create_spreadsheet() 会新建 documents.document,把 handler 设为 spreadsheet,写入模板当前的 spreadsheet_data。但这只是第一层。
紧接着它还会把:
spreadsheet_snapshot一并带过去- 模板上的 revisions 复制到新文档
- 注释数据做清理
- 当前用户 locale 用命令更新进文档
这说明模板生成文档不是“静态快照复制”,而是一次把模板变成活文档的初始化过程。
二、为什么要复制 revision,而不是只保留最新状态
如果只看最终表格内容,revision 似乎可有可无。但企业版并不这样设计。模板在落地为新文档时,会把 revision 链一并迁过去,这样后续协作、回溯和差异记录才有连续的历史起点。
也就是说,新文档不是从“无历史”开始,而是从模板定义好的结构性历史起步。
三、snapshot 的意义,不是多存一份,而是给后续体验一个稳定基线
spreadsheet_snapshot 的价值在于:某些界面、分享视角或派生能力,需要一份快速可展示、相对稳定的基线。如果只有不断变化的正文数据,很多“立即打开”“最近预览”“模板缩略”体验就会变得不稳定。
所以 snapshot 更像面向展示与载入效率的衍生层,而不只是数据冗余。
四、contributor 排序背后其实是在做“最近打开优先”
spreadsheet.contributor 很小,但很关键。每次用户编辑或打开活跃 spreadsheet,系统都会更新 last_update_date。_get_spreadsheets_to_display() 再据此把当前用户最近碰过的表格排在前面。
这意味着最近列表并不是简单按文档更新时间,而是按“当前用户最近参与过的程度”排序。这个设计对协作型表格非常合理。
五、容易误解的地方:模板、文档、冻结副本不是同一类对象
企业版里至少有三种 spreadsheet 语义:
- 模板
spreadsheet.template - 活文档
documents.document(handler='spreadsheet') - 冻结副本
handler='frozen_spreadsheet'
它们的访问规则、是否允许继续写入、是否更新 contributor,都是不同的。开发时若混为一谈,最容易把模板当协作文档、把冻结副本当可继续编辑对象,导致权限和历史都错位。
六、结论
Spreadsheet 模板的真正价值,不是帮你少建一张表,而是帮你把初始结构、协作历史起点、展示基线和最近参与关系一起落到新文档上。
从开发视角看,这是一条“模板物化”链,而不是一次普通 copy。
DISCUSSION
评论区