@saptools/sharepoint-excel
v0.1.3
Published
Create, read, and update SharePoint-hosted Excel workbooks through Microsoft Graph with safe local credential profiles
Maintainers
Readme
๐ @saptools/sharepoint-excel
Safe SharePoint Excel automation for Microsoft Graph app-only integrations.
Create .xlsx files, read workbook content, append records, update cells, and add sheets from a focused CLI or typed TypeScript API without overwriting somebody else's SharePoint file by accident.
Install โข Quick Start โข CLI โข Security
โจ Features
- ๐ Safe local profiles: stores profile metadata under
~/.saptools/sharepoint-excel/and keepsclientSecretin the OS credential vault by default - ๐งญ Graph app-only flow: uses Azure AD client credentials to resolve SharePoint sites and document libraries
- ๐งฑ Local workbook engine: edits
.xlsxbytes withexceljs, avoiding delegated-only Microsoft Graph workbook endpoints - ๐ก๏ธ No accidental overwrite on create: refuses to create when the target path already exists
- ๐ ETag-protected updates: append/update/add-sheet operations upload with
If-Matchso concurrent SharePoint edits fail fast instead of being silently overwritten - ๐ Workbook reads: inspect all sheets, a single sheet, or an A1 range
- โ Content mutation: append JSON objects/rows, update a single cell, and add new sheets with headers
- ๐งช Fake-backed e2e tests: package tests do not call real Microsoft Graph or SharePoint
- ๐งฐ CLI and typed API: every CLI action is backed by exported TypeScript functions
๐ฆ Install
npm install -g @saptools/sharepoint-excelRequires Node.js >= 20. The CLI binary is sharepoint-excel.
๐ Quick Start
# 1. Store an app-only SharePoint profile
sharepoint-excel config set \
--tenant "11111111-1111-1111-1111-111111111111" \
--client-id "22222222-2222-2222-2222-222222222222" \
--client-secret "<your-client-secret>" \
--site "contoso.sharepoint.com/sites/demo" \
--drive "Documents"
# 2. Prove auth and target resolution
sharepoint-excel test
# 3. Create a workbook without overwriting an existing file
sharepoint-excel create \
--path "Reports/orders.xlsx" \
--sheet "Orders" \
--headers "Name,Amount,Status" \
--rows '[{"Name":"Coffee","Amount":3,"Status":"open"}]'
# 4. Append one object by matching row 1 headers
sharepoint-excel append \
--path "Reports/orders.xlsx" \
--sheet "Orders" \
--record '{"Name":"Tea","Amount":8,"Status":"open"}'
# 5. Update one cell
sharepoint-excel update-cell \
--path "Reports/orders.xlsx" \
--sheet "Orders" \
--cell "C2" \
--value '"closed"'
# 6. Read workbook JSON
sharepoint-excel read --path "Reports/orders.xlsx" --jsonFor CI, every command can also read credentials from environment variables:
export SHAREPOINT_EXCEL_TENANT_ID="11111111-1111-1111-1111-111111111111"
export SHAREPOINT_EXCEL_CLIENT_ID="22222222-2222-2222-2222-222222222222"
export SHAREPOINT_EXCEL_CLIENT_SECRET="<your-client-secret>"
export SHAREPOINT_EXCEL_SITE="contoso.sharepoint.com/sites/demo"
export SHAREPOINT_EXCEL_DRIVE="Documents"The CLI also accepts the shorter SHAREPOINT_TENANT_ID, SHAREPOINT_CLIENT_ID, SHAREPOINT_CLIENT_SECRET, SHAREPOINT_SITE, and SHAREPOINT_DRIVE fallbacks for consistency with @saptools/sharepoint-check.
๐งฐ CLI
Common auth flags
| Flag | Env | Description |
| --- | --- | --- |
| --profile <name> | SHAREPOINT_EXCEL_PROFILE | Stored profile name; default is default |
| --tenant <id> | SHAREPOINT_EXCEL_TENANT_ID | Azure AD tenant id |
| --client-id <id> | SHAREPOINT_EXCEL_CLIENT_ID | App registration client id |
| --client-secret <secret> | SHAREPOINT_EXCEL_CLIENT_SECRET | App registration client secret |
| --site <ref> | SHAREPOINT_EXCEL_SITE | SharePoint site, e.g. contoso.sharepoint.com/sites/demo |
| --drive <nameOrId> | SHAREPOINT_EXCEL_DRIVE | Document library name or id |
| --json | - | Machine-readable output |
๐ config set
Store a reusable local profile.
sharepoint-excel config set \
--profile finance \
--tenant "$SHAREPOINT_EXCEL_TENANT_ID" \
--client-id "$SHAREPOINT_EXCEL_CLIENT_ID" \
--client-secret "$SHAREPOINT_EXCEL_CLIENT_SECRET" \
--site "contoso.sharepoint.com/sites/finance" \
--drive "Documents"By default, the secret goes to the OS credential vault:
- macOS: Keychain
- Windows: Credential Manager
- Linux: Secret Service-compatible keyring
For headless CI containers where an OS keyring is unavailable, an explicit plaintext fallback exists:
SAPTOOLS_SHAREPOINT_EXCEL_ALLOW_PLAINTEXT=1 \
sharepoint-excel config set --store file --allow-plaintext-secret ...Use that only in controlled CI environments. The file is written with 0600 permissions under ~/.saptools/sharepoint-excel/secrets.json.
๐ config get
sharepoint-excel config get --profile finance
sharepoint-excel config get --profile finance --jsonSecrets are never printed.
๐งน config remove
sharepoint-excel config remove --profile financeRemoves both profile metadata and the stored secret.
โ
test
Authenticate, resolve the site, and list document libraries.
sharepoint-excel test
sharepoint-excel test --json๐๏ธ drives
sharepoint-excel drives
sharepoint-excel drives --jsonUse this when you are unsure whether the document library is named Documents, Shared Documents, or something custom.
๐ create
sharepoint-excel create \
--path "Reports/orders.xlsx" \
--sheet "Orders" \
--headers "Name,Amount,Status" \
--rows '[{"Name":"Coffee","Amount":3,"Status":"open"}]' \
--table "OrdersTable"create fails if Reports/orders.xlsx already exists.
๐ read
sharepoint-excel read --path "Reports/orders.xlsx"
sharepoint-excel read --path "Reports/orders.xlsx" --sheet "Orders" --range "A1:C10" --jsonโ append
sharepoint-excel append \
--path "Reports/orders.xlsx" \
--sheet "Orders" \
--record '{"Name":"Tea","Amount":8,"Status":"open"}'Objects are mapped by the first row's headers by default. Use --no-match-header to append object values by their JSON key order instead.
๐ฏ update-cell
sharepoint-excel update-cell \
--path "Reports/orders.xlsx" \
--sheet "Orders" \
--cell "B2" \
--value "42"--value accepts a JSON scalar (42, true, null, "text") or a raw string.
๐ add-sheet
sharepoint-excel add-sheet \
--path "Reports/orders.xlsx" \
--sheet "Audit" \
--headers "At,Action,Actor"Fails if the sheet already exists.
๐ Credential Security
@saptools/sharepoint-excel handles Microsoft Graph app secrets. Treat them like production credentials.
- The CLI never prints
clientSecret. - Default secret storage uses OS-provided credential storage via
@napi-rs/keyring. - Local profile metadata lives under
~/.saptools/sharepoint-excel/profiles.jsonwith0600permissions. - Plaintext secret files require explicit opt-in and should only be used in controlled automation.
- Mutating workbook commands use SharePoint ETags so a stale local download cannot silently replace a newer SharePoint edit.
Required Graph application permissions depend on your tenant model. Typical setups use Sites.Selected with site-specific grant plus file read/write access, or a broader Files.ReadWrite.All/Sites.ReadWrite.All policy where your organization permits it.
๐ ๏ธ Development
From the monorepo root:
pnpm install
pnpm --filter @saptools/sharepoint-excel lint
pnpm --filter @saptools/sharepoint-excel typecheck
pnpm --filter @saptools/sharepoint-excel build
pnpm --filter @saptools/sharepoint-excel test:unit
pnpm --filter @saptools/sharepoint-excel test:e2e:fakeThe e2e suite uses a fake Microsoft Graph server and does not call real SharePoint.
๐ Related
- ๐
@saptools/sharepoint-checkโ pre-flight Graph and SharePoint diagnostics - ๐๏ธ saptools monorepo โ the full toolbox
๐จโ๐ป Author
dongtran โจ
๐ License
MIT
Made with โค๏ธ to make your work life easier!