CreateReadOnlyView 方法
在已加载的经典或 XLSX 工作簿模型之上创建一个轻量级只读视图
语法
function CreateReadOnlyView: IXLSReadOnlyWorkbookView;
CreateReadOnlyView 由 IXLSWorkbook 中的经典 lxHandle 和 IXLSXWorkbookOwner 中的 XLSX lxHandleX声明;共享的视图接口、选项和快照类型则在 lxStandard
视图状态与生命周期
创建视图耗时恒定,不会遍历工作表、单元格、样式、名称或绘图
每个视图都有自己从 1 开始的 ActiveSheetIndex,因此多个视图可以选择不同的工作表,而不会更改经典的 ActiveSheetIndex 或 XLSX 的 ActiveIndex、 IsSelected和 ActiveTab
视图在存在期间持有一个读取租约,工作簿变更在更改模型之前会因 EXLSWorkbookWriteGuardUnavailable 而快速失败
使用视图时,经典工作簿应通过 IXLSWorkbook 持有,XLSX 工作簿应通过 IXLSXWorkbookOwner 持有;这样所有者接口和每个视图都会保留同一个引用计数的工作簿,并且可以按任意顺序释放
当所有者接口或视图仍引用具体的 Free 或 TXLSWorkbook 时,不要对其调用 TXLSXWorkbook ,只要所有者接口或视图仍在引用它
单元格快照
TryReadCell 使用视图活动工作表上从 1 开始的行和列坐标,只有在该坐标处不存在已存储单元格时才返回 False ——仅当该坐标不存在已存储单元格时
读取缺失的单元格不会创建存储,也不会推进工作簿世代
TXLSReadOnlyCellSnapshot 拥有其工作表名称、值、公式文本、缓存与求值信息、坐标、种类和样式索引,并且从不暴露可写的工作簿对象
| 字段 | 含义 |
|---|---|
SheetIndex / SheetName | 视图本地的工作表标识 |
Row / Col | 从 1 开始的单元格坐标 |
StyleIndex | 已存储的经典 XF 索引或 XLSX 单元格格式索引 |
Kind | 文本、数字、日期时间、布尔、公式、错误或空白分类 |
Value | 已存储的标量值或公式缓存值,不重新计算 |
HasFormulaCache / FormulaCache | 公式缓存的存在性、来源、值种类和自有缓存值TXLSFormulaCacheState), value kind (TXLSFormulaCacheValueKind), and owned cached value |
FormulaEvaluation | A TXLSFormulaEvaluationInfo record whose TXLSFormulaEvaluationState 求值属于不适用、未请求、已计算或已失败中的哪一种,以及求值器结果代码和自有结果值 |
Formula | 默认为空,仅在显式启用公式文本时才填充 |
公式策略
默认情况下,公式单元格使用已有的存储缓存,绝不计算、调用用户函数、更新脏状态或把缓存写回工作簿
Add xlsvIncludeFormulaText 需要公式文本时,在 Options 中加入 TXLSReadOnlyViewOptions = set of TXLSReadOnlyViewOption;经典引擎按需创建视图私有的解码器,XLSX 则复制其存储的公式字符串,两条路径都不会初始化或修改工作簿计算器
没有已加载或已计算缓存的公式会报告 HasFormulaCache=False ,并把 Value 留为 Unassigned
加入 xlsvEvaluateFormulas 可通过视图私有的计算器、递归状态、标量缓存、数组矩阵缓存和 XLSX 编译公式缓存来对公式求值;得到的 Value 和 FormulaEvaluation.Value 绝不会替换工作簿的存储缓存或编译公式运行时字段
标准电子表格错误会作为 Variant 错误值连同 xlfesCalculated一起返回,而不受支持或内部的求值失败会报告 xlfesFailed 并在 FormulaCache
通过同一视图的重复读取会在该租约世代内重用其私有求值缓存,而不同视图保持独立,可以并发对同一共享公式求值
XLSX 外部公式求值只读取文件本地的 externalLink 缓存,绝不会解引用弱注册的实时工作簿,也不执行外部 I/O
线程与性能
每个工作线程使用一个视图;不同视图可以并发扫描不同的工作表或对同一公式求值,但调用方不得从另一个线程修改某个视图的活动工作表或选项
创建之后,普通的单元格读取不会进入监视器或临界区,因为租约阻止了并发的工作簿变更
发布验证保证每个空闲视图的固定状态低于 64 KiB,一百个空闲视图低于 8 MiB,并且在一百万单元格模型上以 1 毫秒的 p95 门槛保证视图创建与工作簿大小无关
性能套件还把空闲视图对既有单线程游标扫描的影响限制在百分之五以内,并要求在验证主机上八个视图扫描各自独立的工作表时,达到至少五倍于单视图的吞吐量
示例
var
Workbook: IXLSWorkbook;
View: IXLSReadOnlyWorkbookView;
Cell: TXLSReadOnlyCellSnapshot;
begin
Workbook := TXLSWorkbook.Create;
Workbook.Sheets.Add;
Workbook.Sheets[1].Cells[1, 1].Value := 'ready';
View := Workbook.CreateReadOnlyView;
View.Options := [xlsvEvaluateFormulas];
if View.TryReadCell(1, 1, Cell) then
Memo1.Lines.Add(VarToStr(Cell.Value));
end;对于 XLSX,请在创建视图之前通过其所有者接口保留具体的工作簿
var
Owner: IXLSXWorkbookOwner;
Workbook: TXLSXWorkbook;
View: IXLSReadOnlyWorkbookView;
begin
Workbook := TXLSXWorkbook.Create;
Owner := Workbook;
Workbook.Sheets.Add('Data').Cells[1, 1].Value := 42;
View := Owner.CreateReadOnlyView;
end;