HotXLS 文件

SaveSemanticSnapshot 與 ComputeSemanticHash 方法

串流輸出帶版本號的活頁簿語意規範表示,或計算恰恰這些位元組的 SHA-256

語法

procedure SaveSemanticSnapshot(AStream: TStream); overload;
procedure SaveSemanticSnapshot(AStream: TStream;
  AProfile: TXLSSemanticSnapshotProfile;
  AOptions: TXLSSemanticSnapshotOptions); overload;

function ComputeSemanticHash: WideString; overload;
function ComputeSemanticHash(
  AProfile: TXLSSemanticSnapshotProfile;
  AOptions: TXLSSemanticSnapshotOptions): WideString; overload;

這些方法由 IXLSWorkbook 中的傳統 TXLSWorkbook 與 lxHandle,以及 TXLSXWorkbook 中的 lxHandleX

設定檔與選項型別宣告於 lxSemanticSnapshot ,並可透過兩個活頁簿單元看到

設定檔

值意義
xlsspContent規範的活頁簿內容,適用於一般的語意同一性檢查
xlsspSecurityComplete內容加上受支援的不透明安全性與保留狀態,這些狀態被刻意排除在一般內容同一性之外

選項

值包含的狀態
xlssoIncludeViewerState選取、作用中檢視狀態,以及其他受支援的檢視器導向狀態
xlssoIncludeVolatileMetadata受支援的時間戳記、產生者中繼資料,以及其他刻意多變的欄位
xlssoIncludeFormulaCachedResults儲存的公式結果與受支援的外部連結快取,不進行重新計算或外部 I/O

The option set has type TXLSSemanticSnapshotOptions = set of TXLSSemanticSnapshotOption無參數的多載使用 xlsspContent 與空的選項集合

串流與同一性規則

現代儲存格功能

TXLSSemanticCellStyle.CellControlKind 的型別為 TXLSSemanticCellControlKind ,含 xlssControlNone、 xlssControlUnknown與 xlssControlCheckbox; CellControlDefaultState 的型別為 TXLSSemanticCheckboxDefaultState ,含 xlssCheckboxUnchecked、 xlssCheckboxChecked與 xlssCheckboxBlank

XLSX 樣式讀取會解析直接與繼承的控制項而不建立儲存格;標準樣式序列化遇到 xlssControlUnknown 會拒絕,而不是把未知屬性 bag 當成普通儲存格

快照與雜湊包含正規化後的有效控制項矩形,合併相鄰的相等區域而不把整欄展開成儲存格;無關的非預設樣式覆蓋保留其既有的不受支援正規化界限

TXLSXWorkbook.ReadSemanticFeatures(xlsxSemanticCellImages, Sheet, AMaxBytes, AMaxItems) 回傳以儲存格位址為鍵值的分離項目,包含確切編碼的 PNG 或 JPEG 位元組、內容型別、替代文字與裝飾性中繼資料;配額涵蓋標準位元組與圖片項目,過大的承載會在複製前被拒絕

選取 lcoDrawings 時,活頁簿比較包含這些圖片定義,而 lcoCellStyles 與 lcoBlankStyleRegions 則包含有效的核取方塊格式;只有相符的後備錯誤並不會讓不同的圖片視為相等

未知的 rich-value 圖片圖會在選定的功能比較或快照走訪期間引發 EXLSSemanticSnapshot;這些操作保留活頁簿讀取租約,且不計算被檢查的儲存格

並行與錯誤

兩個方法在整個周遊期間都持有活頁簿讀取租約

並行的公開修改會在變更活頁簿狀態之前以 EXLSWorkbookWriteGuardUnavailable失敗,而偵測到的世代變更或不受支援的歧義語意結構會引發 EXLSSemanticSnapshot

Delphi 範例

var
  Snapshot: TFileStream;
  Hash: WideString;
begin
  Snapshot:= TFileStream.Create('workbook.semantic', fmCreate);
  try
    Workbook.SaveSemanticSnapshot(Snapshot,
      xlsspSecurityComplete,
      [xlssoIncludeFormulaCachedResults]);
  finally
    Snapshot.Free;
  end;

  Hash:= Workbook.ComputeSemanticHash;

C++Builder 範例

TFileStream *snapshot = new TFileStream(
  L"workbook.semantic", fmCreate);
try
{
  workbook->SaveSemanticSnapshot(snapshot);
}
__finally
{
  delete snapshot;
}

WideString hash = workbook->ComputeSemanticHash();

快照模型參考

快照引擎不綁定活頁簿物件:以下所有內容都宣告在 lxSemanticSnapshot中,活頁簿方法只是同一批全域進入點的薄包裝

擴充介面

實作 IXLSSemanticWorkbookSource 即可對任何來源輸出快照或計算雜湊,並可選擇性實作 IXLSSemanticFormulaResolver ,讓輸出的公式帶有已解析的外部參照與已定義名稱資訊

IXLSSemanticWorkbookSource = interface
  procedure WriteCommon(AWriter: TXLSSemanticCanonicalWriter);
end;

IXLSSemanticFormulaResolver = interface
  function ResolveFormulaReference(AExternID: Integer;
    out AInfo: TXLSSemanticFormulaReferenceInfo): Boolean;
  function ResolveFormulaName(ANameID, AExternID: Integer;
    out AInfo: TXLSSemanticFormulaNameInfo): Boolean;
end;

TXLSSemanticFormulaReferenceInfo = record
  LinkKind: TXLSSemanticFormulaLinkKind;
  BookName: WideString;
  FirstSheetName: WideString;
  LastSheetName: WideString;
end;

TXLSSemanticFormulaNameInfo = record
  NameKind: TXLSSemanticFormulaNameKind;
  LinkKind: TXLSSemanticFormulaLinkKind;
  Name: WideString;
  ScopeSheetName: WideString;
  BookName: WideString;
end;

在 WriteCommon 裡,writer 是一個不透明控制代碼:不要直接呼叫它的基元方法 —— BeginContainer / EndContainer 框出一個帶標籤的容器, WriteNull、 WriteBoolean、 WriteUInt32、 WriteUInt64、 WriteInt32、 WriteInt64、 WriteBinary64、 WriteWideString與 WriteBytes 各編碼一個 canonical 基元, Finish 封住串流、 Finished 回報完成 —— 請把它交回給下面的輸出輔助方法,讓每個生產者輸出完全一致的位元組

進入點全域函式

procedure XLSSaveSemanticSnapshot(AStream: TStream;
  const ASource: IXLSSemanticWorkbookSource;
  AProfile: TXLSSemanticSnapshotProfile;
  AOptions: TXLSSemanticSnapshotOptions);
function XLSComputeSemanticHash(
  const ASource: IXLSSemanticWorkbookSource;
  AProfile: TXLSSemanticSnapshotProfile;
  AOptions: TXLSSemanticSnapshotOptions): WideString;
procedure XLSInitializeSemanticCellStyle(out AStyle: TXLSSemanticCellStyle);
function XLSBuiltinSemanticNumberFormat(AId: Word): WideString;

XLSInitializeSemanticCellStyle 會以 canonical 預設值填滿樣式記錄,之後再個別修改欄位; XLSBuiltinSemanticNumberFormat 把內建數字格式 id(低於 164)對應到它的格式字串,消費端解讀輸出的樣式與解碼串流時會需要它

模型詞彙

GroupTypes
SheetTXLSSemanticSheetKind (worksheet、macro、chart、VBA、unknown)、 TXLSSemanticSheetVisibility (visible、hidden、very hidden)、 TXLSSemanticDefinedNameScope (活頁簿或工作表)、 TXLSSemanticRange / TXLSSemanticRanges (合併、條件式格式與資料表使用的矩形範圍)
CellTXLSSemanticCellKind (blank、number、datetime、text、boolean、error、formula)
StyleTXLSSemanticCellStyle (完整 canonical 儲存格樣式)、帶 TXLSSemanticColor (none、automatic、system、ARGB、theme、indexed)與色調的 TXLSSemanticColorKind 、 TXLSSemanticBorderEdge / TXLSSemanticBorderStyle、 TXLSSemanticFillPattern、 TXLSSemanticGradientKind / TXLSSemanticGradientStop / TXLSSemanticGradientStops、 TXLSSemanticUnderline、 TXLSSemanticFontVerticalAlign
FormulaTXLSSemanticFormulaEncoding (剖析樹或不透明文字)、 TXLSSemanticFormulaArrayKind (none、CSE、dynamic)、 TXLSSemanticFormulaNodeKind、 TXLSSemanticFormulaRangeKind、 TXLSSemanticFormulaLinkKind (同工作表、內部、外部、增益集、DDE、OLE、其他)、 TXLSSemanticFormulaNameKind
Drawing and chartsTXLSSemanticDrawingKind (image、textbox、chart、group、form control)、 TXLSSemanticDrawingAnchorMode (移動並調整大小、僅移動、絕對)、 TXLSSemanticImageFormat、 TXLSSemanticChartFamily

輸出輔助方法

這些全域函式會把一個模型片段寫進傳給 WriteCommon的 writer: XLSWriteSemanticLiteralCell、 XLSWriteSemanticCellStyle、 XLSWriteSemanticColor、 XLSWriteSemanticRanges、 XLSWriteSemanticMerge、 XLSWriteSemanticAxisEntry、 XLSWriteSemanticFormulaTree、 XLSWriteSemanticFormulaDefinition,以及 XLSWriteSemanticFormulaCell (公式儲存格會帶陣列界限與選擇性的快取結果)。 XLSWriteSemanticWorkbookCommon 會開啟活頁簿容器並呼叫 WriteCommon,自訂來源通常會先呼叫它

另請參閱

IXLSWorkbook 介面 · TXLSXWorkbook 類別 · CreateReadOnlyView 方法