Introduction

Aspose.Cells FOSS for C++ is built as two layers. The layer most code touches is the facade: Workbook, Worksheet, Cell, and Style, which is what the announcement and feature posts for this platform cover. Underneath it sits a second layer, in the Aspose::Cells_FOSS::Core namespace, made up of plain data records — WorkbookModel, WorksheetModel, CellRecord, StyleValue, and roughly four dozen related *Model and *Value types. These records hold the actual parsed spreadsheet state: cell values keyed by CellAddress, style attributes as StyleValue, workbook and worksheet settings, page setup, filters, and load diagnostics. The facade classes read from and write to this layer rather than storing state themselves.

The bridge between the two layers is explicit and public. Workbook::GetModel() returns a Core::WorkbookModel, Worksheet::GetModel() returns a Core::WorksheetModel, and Style::ToCore() / Style::FromCore() convert a mutable Style to and from a Core::StyleValue. DocumentProperties::GetModel() and ExtendedDocumentProperties::GetModel() do the same for document metadata. A consumer reaches for this layer directly in a narrower set of cases than the everyday cell-editing API: inspecting the DiagnosticBag recorded while a workbook was loaded or saved, normalizing a style through the workbook-level StyleRepository, or working with the plain-old-data cell and row records directly instead of the Cell / Row wrapper objects.

Everything described here ships in the same MIT-licensed, dependency-free source tree as the rest of Aspose.Cells FOSS for C++, built with CMake and included as headers and source rather than a prebuilt binary. If you have not worked with the facade API yet, start with the Workbook/Worksheet/Cell features post first — this post assumes that grounding and focuses on what sits underneath it.


What’s Included

The Workbook and Worksheet Model Tree

Core::WorkbookModel is the root record. GetWorksheets() returns a std::deque<WorksheetModel>, GetSettings() a WorkbookSettingsModel, GetProperties() a WorkbookPropertiesModel, GetDocumentProperties() a DocumentPropertiesModel, GetDiagnostics() a DiagnosticBag, GetStyles() a StyleRepository, GetSharedStrings() a SharedStringRepository, and GetDefaultStyle() / SetDefaultStyle() a StyleValue. It also tracks GetActiveSheetIndex() and a std::vector<DefinedNameModel> from GetDefinedNames(). Workbook::GetModel() is the entry point to this record.

Core::WorksheetModel, reached through Worksheet::GetModel(), stores cells as std::unordered_map<CellAddress, CellRecord> via GetCells(), rows as std::unordered_map<int, RowModel> via GetRows(), column ranges as std::vector<ColumnRangeModel> via GetColumns(), and merged ranges as std::vector<MergeRegion> via GetMergeRegions(). It also carries GetHyperlinks(), GetValidations(), GetConditionalFormattings(), GetPageSetup(), GetView(), GetProtection(), GetAutoFilter(), GetTabColor(), and GetVisibility() (a SheetVisibility value: Visible, Hidden, or VeryHidden).

CellAddress is the hashable key type used for that cell map. It parses A1-style text into zero-based row/column indexes and back — this is one of the few classes in this cluster with direct test coverage in the FOSS repo:

#include "aspose/cells_foss/core/CellAddress.h"

using namespace Aspose::Cells_FOSS;

Core::CellAddress parsed = Core::CellAddress::Parse("AB3");
// parsed.GetRowIndex()    == 2    (zero-based row index)
// parsed.GetColumnIndex() == 27   (zero-based column index)
// parsed.ToString()       == "AB3"

CellRecord holds a cell’s CellValue, CellValueKind, an optional formula string, a StyleValue, and a GetIsExplicitlyStored() flag that distinguishes a cell that was actually written from one that only exists because a row or column default touches it. RowModel carries an optional height, a hidden flag, and an optional style index; ColumnRangeModel carries the same three plus the min/max column span it applies to. MergeRegion is a plain first-row/first-column/total-rows/total-columns rectangle.

Style Data as Plain Values

StyleValue is the Core counterpart to the mutable Style facade — Style::ToCore() converts a Style to one, and Style::FromCore() builds a Style from one. It groups GetFont() (FontValue), GetPattern() (FillPatternKind), GetForegroundColor() / GetBackgroundColor() (ColorValue), GetBorders() (BordersValue), GetAlignment() (AlignmentValue), GetProtection() (ProtectionValue), and GetNumberFormat() (NumberFormatValue), plus a static StyleValue::Default() and a Clone(). FontValue mirrors Font field for field: name, size, bold, italic, underline, strike-through, and a ColorValue. ColorValue itself is a plain ARGB tuple (GetA(), GetR(), GetG(), GetB(), Equals(), GetHashCode()) — unlike the facade Color class it has no FromArgb()-style factory, so a ColorValue is normally obtained from an existing style rather than constructed directly.

BordersValue holds five BorderSideValue members — left, right, top, bottom, and diagonal — each pairing a BorderStyle enum value with a ColorValue. AlignmentValue models horizontal and vertical alignment, wrap text, indent level, text rotation, shrink-to-fit, and reading order. ProtectionValue and NumberFormatValue back the cell-protection flags and the number-format id/custom-string pair that Style exposes.

StyleRepository, reached through WorkbookModel::GetStyles(), exposes one operation: Normalize(style) -> StyleValue. The workbook uses it internally while loading and saving to intern equivalent styles rather than duplicating identical StyleValue records — it is not a general-purpose style cache with index-based lookup in the current API surface.

Document Properties and Workbook-Level Settings

DocumentPropertiesModel groups GetCore() (CoreDocumentPropertiesModel: title, subject, creator, keywords, description, last-modified-by, revision, category, content status, and created/modified timestamps) and GetExtended() (ExtendedDocumentPropertiesModel: application, app version, company, manager, doc security, hyperlink base, and the scale-crop / links-up-to-date / shared-doc flags). DocumentProperties::GetModel() and ExtendedDocumentProperties::GetModel() bridge from the facade classes to these records.

WorkbookPropertiesModel mirrors WorkbookProperties — code name, show-objects, filter privacy, backup-file, and related flags — and nests WorkbookProtectionModel (lock structure/windows/revision, workbook and revisions password), WorkbookViewModel (window position and size, first visible sheet, scroll-bar and sheet-tab visibility, tab ratio, minimized state, auto-filter date grouping), and CalculationPropertiesModel (calculation mode, iteration settings, full precision, concurrent calculation). WorkbookSettingsModel carries a DateSystem value (Windows1900 or Mac1904) and a display culture — the model-level counterpart of WorkbookSettings::GetDate1904() / GetCulture(). Most *Model types in this group expose CopyFrom(source) and HasStoredState(), which the serializer uses to tell an explicitly-set value from an unset default before writing XML.

Worksheet Feature Models

WorksheetProtectionModel mirrors WorksheetProtection field for field and adds the stored password fields — GetPasswordHash(), GetAlgorithmName(), GetHashValue(), GetSaltValue(), GetSpinCount() — that the facade WorksheetProtection does not surface directly. WorksheetViewModel holds grid-line, header, and zero visibility, right-to-left layout, and zoom scale. PageSetupModel nests PageMarginsModel (left/right/top/bottom/header/footer margins as doubles), PrintOptionsModel (grid lines, headings, horizontal and vertical centering), and HeaderFooterModel (left/center/right header and footer text), alongside paper size, orientation, scale, fit-to-width/height, print area, print title rows/columns, and page-break vectors.

AutoFilterModel holds a range string, a std::vector<FilterColumnModel>, and an AutoFilterSortStateModel. FilterColumnModel in turn nests AutoFilterColorFilterModel, AutoFilterDynamicFilterModel, and AutoFilterTop10Model, plus a plain list of filter value strings and a std::vector<AutoFilterCustomFilterModel>. ConditionalFormattingModel pairs a std::vector<CellArea> with a std::vector<FormatConditionModel> — each condition carrying its type, operator, formulas, color-scale/data-bar/icon-set fields, and a StyleValue for the resulting format. ValidationModel and HyperlinkModel mirror the Validation and Hyperlink facades as plain records, and DefinedNameModel mirrors DefinedName. SheetVisibility is the model-layer enum behind Worksheet::GetVisibilityType().

Some of the facade features that these records back — AutoFilter and ConditionalFormattingCollection in particular — are called out in the product documentation as still under active development in this release. Treat the shapes above as the structural target the model and serializer are built around rather than a guarantee that every field round-trips through a saved workbook today.

Diagnostics and Shared State

DiagnosticBag, reached via WorkbookModel::GetDiagnostics(), collects DiagnosticEntry records — each with a GetCode(), a GetSeverity() (DiagnosticSeverity: Warning, Recoverable, or LossyRecoverable), a GetMessage(), a GetRepairApplied() flag, and a GetDataLossRisk() flag — generated while a workbook is parsed or serialized. This runs alongside Workbook::GetLoadDiagnostics(), whose facade-level LoadDiagnostics / LoadIssue types share the same DiagnosticSeverity enum; code that needs the raw model record instead of the LoadIssue wrapper reaches it through GetDiagnostics() on the workbook model.

SharedStringRepository backs the xlsx shared-strings table: GetValues() returns the interned string vector, TryGetValue(index, value) resolves an index back to text, and Intern(value) adds or reuses an entry — used internally when SaveOptions::SetUseSharedStrings(true) is set. DateSerialConverter converts between a DateTime and the OLE-style serial number Excel stores in a cell, taking a DateSystem so 1900- and 1904-based workbooks decode to the same calendar date.


Quick Start

Add the library to a CMake project as a subdirectory and link the target it defines:

add_subdirectory(path/to/Aspose.Cells-FOSS-for-Cpp)
target_link_libraries(MyApp PRIVATE Aspose.Cells.Foss.Cpp)

The example below writes a cell through the facade, then reaches into the underlying model for a diagnostic bag and a CellAddress parse — the same operation WorksheetModel::GetCells() uses internally to key its cell map:

#include "aspose/cells_foss/Workbook.h"
#include "aspose/cells_foss/Worksheet.h"
#include "aspose/cells_foss/Cell.h"
#include "aspose/cells_foss/core/CellAddress.h"
#include <iostream>

using namespace Aspose::Cells_FOSS;

int main() {
    Workbook workbook;
    Worksheet& sheet = workbook.GetWorksheets()[0];
    sheet.SetName("Report");
    sheet.GetCells()["A1"].PutValue("Total");
    workbook.Save("report.xlsx");

    Core::CellAddress address = Core::CellAddress::Parse("A1");
    std::cout << "Row: " << address.GetRowIndex()
              << " Column: " << address.GetColumnIndex() << "\n";

    for (const auto& entry : workbook.GetModel().GetDiagnostics().GetEntries()) {
        std::cout << "Diagnostic: " << entry.GetMessage() << "\n";
    }

    return 0;
}

Supported Formats

FormatExtensionReadWrite
XLSX.xlsx

The model layer described here is the in-memory representation the xlsx reader and writer operate on; it is not itself tied to any additional file format beyond the Xlsx import/export the rest of the library supports.


Open Source & Licensing

Aspose.Cells FOSS for C++ is MIT licensed. Source code, including the Aspose::Cells_FOSS::Core model headers referenced in this post, is on GitHub; commercial use, modification, and redistribution are permitted.


Getting Started