inspect() JSON schema, version 1

inspect(input, options?) (and inspectFile(path, options?) from xlvane/node) returns plain JSON data describing a workbook. JSON.stringify of the result is lossless. The field schemaVersion changes only when a field is removed or changes meaning; new fields may be added within a version.

Options

OptionDefaultMeaning
limitssee DEFAULT_READ_LIMITSresource limits used while reading the file
maxColumns200maximum number of columns described per sheet; columnsTruncated says whether more exist
headerScanRows20number of leading non-empty rows searched for a header row
formulaSamples10maximum number of example formulas per sheet

Workbook

FieldTypeMeaning
schemaVersion1version of this schema
format"xlsx" | "xlsm" | "xltx" | "xltm" | "unknown"from the content type of the workbook part
conformance"transitional" | "strict"Office Open XML conformance class of the package
dateSystem"1900" | "1904"date system used for serial dates
hasMacrosbooleanthe package contains a VBA project or Excel 4.0 macro sheets (never run)
externalLinkCountnumberlinks to other workbooks (never followed)
propertiesobjectdocument properties that are set (title, creator, created, …, from docProps/core.xml); all values are strings, dates as ISO 8601 in UTC ("2026-10-01T00:00:00.000Z"); {} when the file has none
definedNames{ name, refersTo, sheet, hidden }[]defined names in file order, at most 100; refersTo is the formula text without "=", cut to 100 characters; sheet is null for a workbook-level name; built-in names such as _xlnm._FilterDatabase are included
definedNamesTruncatedbooleanthe workbook has more than 100 defined names
sheetCountnumbernumber of sheets
sheetsarray of sheet objectsin workbook order
warningsarray of warning objectssee below

Sheet

FieldTypeMeaning
namestringsheet name
indexnumber0-based position
sheetIdnumber or nullthe sheet's id in the file (sheet@sheetId), independent of its position; null when the file has none, an invalid one or a repeated one
kind"worksheet" | "chartsheet" | "dialogsheet" | "macrosheet"only worksheets have cells
state"visible" | "hidden" | "veryHidden"visibility
dimensionstring or nullrange declared in the file, e.g. "A1:D20"
usedRangestring or nullsmallest range containing every cell with a value or formula; null for an empty sheet
rowCount, columnCountnumbersize of usedRange
cellCountnumbercells with a value or formula
formulaCountnumbercells with a formula
mergedRangesstring[]merged ranges, e.g. ["A1:D1"]; at most the first 100
mergedRangeCountnumbernumber of merged ranges on the sheet
mergedRangesTruncatedbooleantrue when mergedRanges lists only the first 100
headerRow{ row, confidence } or nulldetected header row (1-based) and "high" or "low" confidence
columnsarray of column objectsone per column of usedRange, at most maxColumns
columnsTruncatedbooleanusedRange has more columns than were described
formulas{ cell, formula }[]up to formulaSamples examples; formula is the text without "=" or null for cells that reuse a shared formula
richTextCellCountnumbercells whose text has formatted runs (Cell.richText)
richTextCellsstring[]up to ten of those cells
styledColumnsstring[]columns with a default style (col@style, ColumnInfo.style), e.g. ["B", "D:F"]; at most maxColumns entries
hyperlinkCountnumberhyperlinks of the sheet (Sheet.hyperlinks)
hyperlinksobject[]up to ten of them: ref, target (external URL or path as stored, or null), location (place in the workbook, or null); targets are never opened
noteCountnumbernotes (comments) of the sheet (Sheet.notes)
imageCountnumberpictures of the sheet's drawing (Sheet.images); charts and shapes are not counted
imagesarrayup to 10 pictures: cell of the top-left corner (null for an absolute position) and format (png, jpeg, gif, or null for other formats)
notesstring[]up to ten cells that have a note
protectedbooleanthe sheet is protected (Sheet.protection.sheet)
printAreastring[] | nullthe print area (Sheet.printArea), at most ten ranges
pageBreakCountnumbermanual page breaks, rows and columns together (Sheet.pageBreaks)
dataValidationCountnumberdata validation rules (Sheet.dataValidations)
conditionalFormatCountnumberconditional formatting rules over all ranges (Sheet.conditionalFormats)
tablesarraytables of the sheet (Sheet.tables): name (the name used in formulas), ref (header and totals rows included) and columns (column names); at most 20 tables and 50 columns each

Header detection. Among the first headerScanRows non-empty rows, the header row is the first one in which:

  • cells with a formula are left out (a total such as =SUM(B3:B9) may sit next to the column names);
  • every other cell is non-blank text or a year: a whole number from 1900 to 2100 (Region | 2023 | 2024). The years of the row must be consecutive, and in the next non-empty row at least one value below them must not be such a year, so that a data row with years (Alice | 1985) is not taken for a header;
  • at least one cell is text, and the cells cover at least half of the used width.

Repeated names are allowed; readTable gives the second one the key name_2, and so on. The confidence is "high" when the names are distinct and the next non-empty row contains a value that is not text (number, date, boolean or error), otherwise "low". A year used as a column name is reported as text in header ("2023"). This is a heuristic; check confidence before relying on it, or give the header row yourself (readTable(…, { header: 2 }), xlvane read --header 2).

Column

FieldTypeMeaning
indexnumber1-based column number
letterstringcolumn letters, e.g. "C"
headerstring or nulltext of the header cell, null without a header row
dominantType"number" | "string" | "date" | "boolean" | "error" | "empty"most frequent non-empty type in the data rows (ties: number, string, date, boolean, error)
types{ number, string, boolean, date, error, empty }counts over the data rows: the rows below the header row (or all rows without one) down to the end of usedRange
samplesarrayup to three distinct example values from the data rows

Values in samples are JSON-safe: numbers, booleans, strings (cut to 100 characters) and dates as ISO 8601 strings without a time zone, as in CSV: the date alone at midnight ("2024-01-31"), otherwise date and time ("2024-01-31T13:45:00", with .sss when there are milliseconds), because spreadsheet dates have no time zone. Error cells appear as their code, e.g. "#DIV/0!".

Warning

FieldTypeMeaning
codestringXLV_W_* code, see docs/errors.md
messagestringwhat was found and what xlvane did
locationobjectsheet and/or part where it applies
countnumbernumber of occurrences (warnings are aggregated per sheet)
cellsstring[] (optional)up to ten example cells

Example

{
  "schemaVersion": 1,
  "format": "xlsx",
  "conformance": "transitional",
  "dateSystem": "1900",
  "hasMacros": false,
  "externalLinkCount": 0,
  "properties": { "title": "Sales 2024", "creator": "Finance" },
  "definedNames": [{ "name": "Total", "refersTo": "Sales!$C$3", "sheet": null, "hidden": false }],
  "definedNamesTruncated": false,
  "sheetCount": 1,
  "sheets": [
    {
      "name": "Sales",
      "index": 0,
      "sheetId": 1,
      "kind": "worksheet",
      "state": "visible",
      "dimension": "A1:C3",
      "usedRange": "A1:C3",
      "cellCount": 9,
      "formulaCount": 1,
      "mergedRanges": [],
      "mergedRangeCount": 0,
      "mergedRangesTruncated": false,
      "formulas": [{ "cell": "C3", "formula": "SUM(C2:C2)" }],
      "richTextCellCount": 0,
      "richTextCells": [],
      "styledColumns": [],
      "hyperlinkCount": 0,
      "hyperlinks": [],
      "noteCount": 0,
      "imageCount": 0,
      "images": [],
      "notes": [],
      "protected": false,
      "printArea": null,
      "pageBreakCount": 0,
      "dataValidationCount": 0,
      "conditionalFormatCount": 0,
      "tables": [],
      "rowCount": 3,
      "columnCount": 3,
      "headerRow": { "row": 1, "confidence": "high" },
      "columns": [
        { "index": 1, "letter": "A", "header": "Date", "dominantType": "date", "types": { "number": 0, "string": 0, "boolean": 0, "date": 2, "error": 0, "empty": 0 }, "samples": ["2024-01-31", "2024-02-01"] },
        { "index": 2, "letter": "B", "header": "Customer", "dominantType": "string", "types": { "number": 0, "string": 1, "boolean": 0, "date": 0, "error": 0, "empty": 1 }, "samples": ["ACME"] },
        { "index": 3, "letter": "C", "header": "Amount", "dominantType": "number", "types": { "number": 2, "string": 0, "boolean": 0, "date": 0, "error": 0, "empty": 0 }, "samples": [100.5] }
      ],
      "columnsTruncated": false
    }
  ],
  "warnings": []
}

Source: docs/inspect-json.md (version 1.2.2)