Search and Discovery

Use search and discovery APIs when a script needs to understand a workbook before editing it. These operations are designed for targeted inspection: find relevant cells, discover table-shaped regions, read compact TSV, and locate values by row and column labels.

Use Cell Values and Annotations for the direct read/write model, including typed values, formulas, notes, hyperlinks, and threaded comments.

Find Cells

findCells searches display text by default:

witan xlsx exec model.xlsx --stdin <<'WITAN'
return await xlsx.findCells(wb, /revenue|ebitda/i, {
  in: "Summary!A1:Z200",
  context: 2,
  limit: 20
})
WITAN

Matchers can be strings, numbers, booleans, regular expressions, or arrays of string and regular-expression matchers. Results include the address, value, display text, row/column coordinates, sheet, visibility, role, and optional context.

Pass formulas: true when the script needs to search formulas rather than display text:

await xlsx.findCells(wb, /XLOOKUP|VLOOKUP/, {
  in: "Summary",
  formulas: true
})

Find Rows

findRows returns matching rows as TSV snippets:

const rows = await xlsx.findRows(wb, [/North/, /South/], {
  in: "Sales!A1:H200",
  context: 1,
  limit: 10
})

Use it when a cell match is not enough context and the caller needs the surrounding row.

Describe Sheets

describeSheet detects table-shaped regions and returns a compact structure summary:

const summary = await xlsx.describeSheet(wb, "Summary")
return {
  tables: summary.tables,
  structure: summary.structure
}

Each detected table includes an address, headerRows, optional headerCols, and optional tableName when it maps to a workbook ListObject.

The exec prelude also provides describeSheets, a helper that calls listSheets and then describeSheet for each sheet.

Lookup By Labels

Use tableLookup when a task names a row and column rather than a concrete address:

witan xlsx exec model.xlsx --stdin <<'WITAN'
const summary = await xlsx.describeSheet(wb, "Summary")
const table = Object.values(summary.tables)[0]

return await xlsx.tableLookup(wb, {
  table: table.address,
  rowLabel: "Revenue",
  columnLabel: "Q4"
})
WITAN

tableLookup accepts a table address or table name. Results include the matched output cell plus where the row and column labels were found. This is usually the right first step before editing a workbook whose layout was authored by a person.

Compact Reads

Use TSV reads when the script needs a dense view with fewer tokens than JSON cell arrays:

const tsv = await xlsx.readRangeTsv(wb, "Summary!A1:H25", {
  includeEmpty: false,
  includeFormulas: true
})

readRangeTsv, readRowTsv, and readColumnTsv are best for broad inspection. Use readCell, readRange, readRow, and readColumn when you need typed cell objects.

Find And Replace

Use findAndReplace for bounded text edits:

const replace = await xlsx.findAndReplace(
  wb,
  "FY25",
  "FY26",
  {
    in: "Summary!A1:Z200",
    matchCase: true,
    wholeCell: false,
    limit: 50
  }
)

Pass inFormulas: true to replace formula text. The result reports replacement count, changed cells, and formula errors introduced by recalculation.

See xlsx API for exact search and discovery signatures.