diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 14d9aae5c..000000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -build -dist -out -spec/manual/public/ diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 03557ea7a..000000000 --- a/.eslintrc +++ /dev/null @@ -1,49 +0,0 @@ -{ - "parserOptions": { - "sourceType": "script" - }, - "extends": [ - "airbnb-base", - "prettier", - "plugin:node/recommended" - ], - "env": { - "es6": true, - "mocha": true, - "node": true - }, - "rules": { - "arrow-parens": ["error", "as-needed"], - "class-methods-use-this": ["off"], - "comma-dangle": ["error", {"arrays": "always-multiline", "objects": "always-multiline", "imports": "always-multiline", "exports": "always-multiline", "functions": "never"}], - "default-case": ["off"], - "func-names": ["off", "never"], - "global-require": ["off"], - "max-len": ["error", {"code": 120, "ignoreComments": true, "ignoreStrings": true}], - "no-console": ["error", { "allow": ["warn"] }], - "no-continue": ["off"], - "no-mixed-operators": ["error", {"allowSamePrecedence": true}], - "no-multi-assign": ["off"], - "no-param-reassign": ["off"], - "no-path-concat": ["off"], - "no-plusplus": ["off"], - "no-prototype-builtins": ["off"], - "no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "WithStatement"], - "no-return-assign": ["off"], - "no-trailing-spaces": ["error", { "skipBlankLines": true }], - "no-underscore-dangle": ["off", { "allowAfterThis": true, "allowAfterSuper": true }], - "no-unused-vars": ["error", {"vars": "all", "args": "none", "ignoreRestSiblings": true}], - "no-use-before-define": ["error", { "variables": false, "classes": false, "functions": false }], - "node/no-unsupported-features/es-syntax": ["error", {"version": ">=10.0.0","ignores": []}], - "node/process-exit-as-throw": ["off"], - "object-curly-spacing": ["error", "never"], - "object-property-newline": ["off", { "allowMultiplePropertiesPerLine": true }], - "prefer-destructuring": ["warn", {"array": false, "object": true}], - "prefer-object-spread": ["off"], - "prefer-rest-params": ["off"], - "quotes": ["error", "single"], - "semi": ["error", "always"], - "space-before-function-paren": ["error", {"anonymous": "never", "named": "never", "asyncArrow": "always"}], - "strict": ["off"] - } -} diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index b2230c1d0..000000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: #[siemienik] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index dccc9a560..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: 🐛 Bug report -about: Create a report to help us improve -title: '[BUG] XYZ' -labels: ':bug: Bug' ---- - -## 🐛 Bug Report - - - -Lib version: X.Y.Z - -## Steps To Reproduce - - - -```javascript -const wb = new ExcelJS.Workbook(); -const ws = wb.addWorksheet('XYZ'); - -ws.getCell('A1').value = 7; -expect(ws.getCell('A1').value).to.equal(7); -``` - -## The expected behaviour: - - - - -## Possible solution (optional, but very helpful): - -```javascript - -``` diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md deleted file mode 100644 index 6e0cbcb3b..000000000 --- a/.github/ISSUE_TEMPLATE/feature.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: 🚀 Feature Proposal -title: '[F] XYZ' -labels: ':rocket: Feature Request' -about: Submit a proposal for a new feature ---- - -## 🚀 Feature Proposal - -A clear and concise description of what the feature is. - -## Motivation - -Please outline the motivation for the proposal. - -## Example - -Please provide an example for how this feature would be used. diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index 4209929eb..000000000 --- a/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: 💬 Questions / Help -title: '[Q] PLEASE USE DISCUSSIONS' -label: ':speech_balloon: Question' -about: https://github.com/exceljs/exceljs/discussions/categories/q-a ---- - -## 💬 Questions and Help - -Please do not use issues for making a questions, for this purposes much better is GitHub Discussions feature: -https://github.com/exceljs/exceljs/discussions/categories/q-a - -### How to make a question? - -1. First, try to find it by using search bar - anware what are you looking for was be done before. -2. Push the `New discussion` button. -3. Select `Q&A` category. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 469fc0d20..000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,13 +0,0 @@ - - -## Summary - - - -## Test plan - - - -## Related to source code (for typings update) - - diff --git a/.github/lock.yml b/.github/lock.yml deleted file mode 100644 index a09dd77d5..000000000 --- a/.github/lock.yml +++ /dev/null @@ -1,38 +0,0 @@ - Configuration for Lock Threads - https://github.com/dessant/lock-threads-app - -# Number of days of inactivity before a closed issue or pull request is locked -daysUntilLock: 60 - -# Skip issues and pull requests created before a given timestamp. Timestamp must -# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable -skipCreatedBefore: false - -# Issues and pull requests with these labels will be ignored. Set to `[]` to disable -exemptLabels: [keepunlock] - -# Label to add before locking, such as `outdated`. Set to `false` to disable -lockLabel: 'outdated' - -# Comment to post before locking. Set to `false` to disable -lockComment: > - This thread has been automatically locked since there has not been - any recent activity after it was closed. Please open a new issue for - related bugs. - -# Assign `resolved` as the reason for locking. Set to `false` to disable -setLockReason: true - -# Limit to only `issues` or `pulls` -# only: issues - -# Optionally, specify configuration settings just for `issues` or `pulls` -# issues: -# exemptLabels: -# - help-wanted -# lockLabel: outdated - -# pulls: -# daysUntilLock: 30 - -# Repository to extend settings from -# _extends: repo diff --git a/.github/workflows/asset-size.yml b/.github/workflows/asset-size.yml deleted file mode 100644 index f9c813146..000000000 --- a/.github/workflows/asset-size.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Asset size - -on: [pull_request] - -jobs: - compare: - timeout-minutes: 15 - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - uses: chrysanthos/simple-asset-size-reporter@1.0.2 - with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - files: '["dist/*.js"]' - with-same: "false" - build-assets: "npm run install-build" diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml new file mode 100644 index 000000000..a0455f84e --- /dev/null +++ b/.github/workflows/cicd.yml @@ -0,0 +1,57 @@ +name: CI/CD + +on: + push: + branches: + - master + tags: + - "v*" + pull_request: + branches: + - master + workflow_dispatch: + +permissions: + checks: write + contents: read + packages: write + statuses: write + +jobs: + buildAndPublish: + name: Build (and publish) to NPM (GH) + runs-on: ubuntu-24.04 + env: + PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: '1' + PUPPETEER_EXECUTABLE_PATH: /usr/bin/google-chrome + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Enable corepack + run: corepack enable + - name: Set up Node.js + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 + with: + node-version: 24.16.0 + cache: yarn + registry-url: https://npm.pkg.github.com + scope: '@evidenceprime' + - name: Install dependencies + run: yarn install --immutable + - name: Run build + run: yarn build + - name: Run tests + run: yarn test + - name: Publish package + if: ${{ github.event_name == 'push' && github.ref_type == 'tag' }} + run: yarn release + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Notify Google Chat + uses: evidenceprime/google-chat-notifications@master + if: ${{ !cancelled() && github.event_name == 'push' }} + with: + title: ${{ github.ref_name }} + subtitle: ${{ github.event.head_commit.message }} + webhookUrl: ${{ secrets.GOOGLE_CHAT_WEBHOOK_URL }} + status: ${{ job.status }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index 7e696d799..000000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Tests - -on: - push: - branches: [ master ] - pull_request: - branches: [ '**' ] - -jobs: - test: - timeout-minutes: 10 - name: Node v${{ matrix.node-version }} on ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - node-version: [10.x, 12.x, 14.x, 16.x, 17.x, 18.x, 19.x, 20.x] - os: [ubuntu-latest, macOS-latest, windows-latest] - runs-on: ${{ matrix.os }} - - steps: - - name: Set git config - shell: bash - run: | - git config --global core.autocrlf false - git config --global core.symlinks true - if: runner.os == 'Windows' - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #latest v4. TODO upgrade - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #latest v3. TODO upgrade - with: - node-version: ${{ matrix.node-version }} - - name: Create the npm cache directory - run: mkdir npm-cache && npm config set cache ./npm-cache --global - - name: Cache node modules - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #latest v3 TODO upgrade - with: - path: ./npm-cache - key: v1-${{ runner.os }}-node-${{ matrix.node-version }}-npm-${{ hashFiles('**/package.json') }} - restore-keys: | - v1-${{ runner.os }}-node-${{ matrix.node-version }}-npm- - - run: npm install - - run: npm test - env: - CI: true - - benchmark: - timeout-minutes: 15 - name: Measure performance impact of changes - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #latest v4. TODO upgrade - - uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #latest v3. TODO upgrade - with: - node-version: 18 - - name: Create the npm cache directory - run: mkdir npm-cache && npm config set cache ./npm-cache --global - - name: Cache node modules - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #latest v3 TODO upgrade - with: - path: ./npm-cache - key: v1-npm-${{ hashFiles('**/package.json') }} - restore-keys: | - v1-npm- - - run: npm install - - run: npm run benchmark - env: - CI: true - - typescript: - timeout-minutes: 15 - name: Ensure typescript compatibility - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 #latest v4. TODO upgrade - - uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d #latest v3. TODO upgrade - with: - node-version: 18 - - name: Create the npm cache directory - run: mkdir npm-cache && npm config set cache ./npm-cache --global - - name: Cache node modules - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #latest v3 TODO upgrade - with: - path: ./npm-cache - key: v1-npm-${{ hashFiles('**/package.json') }} - restore-keys: | - v1-npm- - - run: npm install - - run: npm install typescript - - run: tsc index.d.ts - env: - CI: true diff --git a/.gitignore b/.gitignore index 8026a7080..3b96bcc35 100644 --- a/.gitignore +++ b/.gitignore @@ -66,4 +66,21 @@ _SpecRunner.html # Ignore xlsx files generated during testing *.xlsx -enpm-lock.yaml \ No newline at end of file +enpm-lock.yaml + +# misc +.env.local +.env.development.local +.env.test.local +.env.production.local +.agents/ +.idea/ +.vscode +!.vscode/extensions.json +!.vscode/tasks.json +.yarnrc +.yarnrc.yml +.yarn/ +.copilot-instructions.md +.cursorrules +.devcontainer/ diff --git a/.prettier b/.prettier deleted file mode 100644 index cbd7f9818..000000000 --- a/.prettier +++ /dev/null @@ -1,7 +0,0 @@ -{ - "bracketSpacing": false, - "printWidth": 100, - "trailingComma": "all", - "arrowParens": "avoid", - "singleQuote": true, -} diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 14d9aae5c..000000000 --- a/.prettierignore +++ /dev/null @@ -1,4 +0,0 @@ -build -dist -out -spec/manual/public/ diff --git a/benchmark.js b/benchmark.js index 9070a0013..c1a3dc9e7 100644 --- a/benchmark.js +++ b/benchmark.js @@ -9,16 +9,16 @@ const runs = 3; return new Promise((resolve, reject) => { // Data taken from http://eforexcel.com/wp/downloads-18-sample-csv-files-data-sets-for-testing-sales/ const workbookReader = new ExcelJS.stream.xlsx.WorkbookReader( - './spec/integration/data/huge.xlsx' + './spec/integration/data/huge.xlsx', ); workbookReader.read(); let worksheetCount = 0; let rowCount = 0; - workbookReader.on('worksheet', worksheet => { + workbookReader.on('worksheet', (worksheet) => { worksheetCount += 1; console.log(`Reading worksheet ${worksheetCount}`); - worksheet.on('row', row => { + worksheet.on('row', (row) => { rowCount += 1; if (rowCount % 50000 === 0) console.log(`Reading row ${rowCount}`); }); @@ -35,7 +35,7 @@ const runs = 3; await runProfiling('huge xlsx file async iteration', async () => { // Data taken from http://eforexcel.com/wp/downloads-18-sample-csv-files-data-sets-for-testing-sales/ const workbookReader = new ExcelJS.stream.xlsx.WorkbookReader( - 'spec/integration/data/huge.xlsx' + 'spec/integration/data/huge.xlsx', ); let worksheetCount = 0; let rowCount = 0; @@ -60,7 +60,7 @@ async function runProfiling(name, run) { console.log(''); console.log('####################################################'); console.log( - `WARMUP: Current memory usage: ${currentMemoryUsage({runGarbageCollector: true})} MB` + `WARMUP: Current memory usage: ${currentMemoryUsage({ runGarbageCollector: true })} MB`, ); console.log(`WARMUP: ${name} profiling started`); const warmupStartTime = Date.now(); @@ -69,10 +69,10 @@ async function runProfiling(name, run) { console.log( `WARMUP: Current memory usage (before GC): ${currentMemoryUsage({ runGarbageCollector: false, - })} MB` + })} MB`, ); console.log( - `WARMUP: Current memory usage (after GC): ${currentMemoryUsage({runGarbageCollector: true})} MB` + `WARMUP: Current memory usage (after GC): ${currentMemoryUsage({ runGarbageCollector: true })} MB`, ); for (let i = 1; i <= runs; i += 1) { @@ -85,17 +85,17 @@ async function runProfiling(name, run) { console.log( `RUN ${i}: Current memory usage (before GC): ${currentMemoryUsage({ runGarbageCollector: false, - })} MB` + })} MB`, ); console.log( `RUN ${i}: Current memory usage (after GC): ${currentMemoryUsage({ runGarbageCollector: true, - })} MB` + })} MB`, ); } } -function currentMemoryUsage({runGarbageCollector}) { +function currentMemoryUsage({ runGarbageCollector }) { if (runGarbageCollector) global.gc(); return Math.round((process.memoryUsage().heapUsed / 1024 / 1024) * 100) / 100; } diff --git a/biome.json b/biome.json new file mode 100644 index 000000000..dd2f94226 --- /dev/null +++ b/biome.json @@ -0,0 +1,141 @@ +{ + "root": false, + "$schema": "https://biomejs.dev/schemas/2.5.3/schema.json", + "vcs": { + "enabled": false, + "clientKind": "git", + "useIgnoreFile": true, + "defaultBranch": "master" + }, + "files": { + "ignoreUnknown": true, + "includes": [ + "**/*.js", + "**/*.jsx", + "**/*.ts", + "**/*.tsx", + "**/*.json", + "!**/node_modules", + "!**/node_modules/**", + "!**/*.min.js", + "!**/dist", + "!**/dist/**" + ] + }, + "formatter": { + "enabled": true, + "useEditorconfig": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 100, + "attributePosition": "auto", + "bracketSpacing": true + }, + "assist": { "actions": { "source": { "organizeImports": "on" } } }, + "linter": { + "enabled": true, + "rules": { + "recommended": false, + "complexity": { + "noExtraBooleanCast": "error", + "noUselessCatch": "error", + "noAdjacentSpacesInRegex": "error" + }, + "correctness": { + "noConstAssign": "error", + "noConstantCondition": "error", + "noEmptyCharacterClassInRegex": "error", + "noEmptyPattern": "error", + "noGlobalObjectCalls": "error", + "noInvalidBuiltinInstantiation": "error", + "noInvalidConstructorSuper": "error", + "noNonoctalDecimalEscape": "error", + "noPrecisionLoss": "error", + "noSelfAssign": "error", + "noSetterReturn": "error", + "noSwitchDeclarations": "error", + "noUndeclaredVariables": "error", + "noUnreachable": "error", + "noUnreachableSuper": "error", + "noUnsafeFinally": "error", + "noUnsafeOptionalChaining": "error", + "noUnusedLabels": "error", + "noUnusedPrivateClassMembers": "error", + "noUnusedVariables": "warn", + "useIsNan": "error", + "useValidForDirection": "error", + "useYield": "error", + "useExhaustiveDependencies": { + "level": "warn", + "options": { + "hooks": [ + { + "name": "useSyncedRef", + "stableResult": true + } + ] + } + }, + "useValidTypeof": "error" + }, + "style": { + "noParameterAssign": "warn", + "noRestrictedImports": { + "level": "error", + "options": { + "paths": { + "@testing-library/react": "Use custom testing utils from src/test/rtl.tsx instead" + } + } + } + }, + "suspicious": { + "noAssignInExpressions": "error", + "noAsyncPromiseExecutor": "error", + "noCatchAssign": "error", + "noClassAssign": "error", + "noCompareNegZero": "error", + "noConsole": "off", + "noControlCharactersInRegex": "error", + "noDebugger": "warn", + "noDuplicateCase": "error", + "noDuplicateClassMembers": "error", + "noDuplicateObjectKeys": "error", + "noDuplicateParameters": "error", + "noEmptyBlockStatements": "error", + "noFallthroughSwitchClause": "error", + "noFunctionAssign": "error", + "noGlobalAssign": "error", + "noImportAssign": "error", + "noMisleadingCharacterClass": "error", + "noPrototypeBuiltins": "error", + "noRedeclare": "error", + "noShadowRestrictedNames": "error", + "noSparseArray": "error", + "noUnsafeNegation": "error", + "useAwait": "error", + "useGetterReturn": "error", + "noWith": "error" + }, + "performance": { + "noAccumulatingSpread": "warn" + } + } + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSameLine": false, + "quoteStyle": "single", + "attributePosition": "auto", + "bracketSpacing": true + }, + "globals": ["module", "process"] + } +} diff --git a/excel.js b/excel.js index acbb71bb8..e7ed63a45 100644 --- a/excel.js +++ b/excel.js @@ -6,7 +6,7 @@ if (parseInt(process.versions.node.split('.')[0], 10) < 10) { throw new Error( - 'For node versions older than 10, please use the ES5 Import: https://github.com/exceljs/exceljs#es5-imports' + 'For node versions older than 10, please use the ES5 Import: https://github.com/exceljs/exceljs#es5-imports', ); } diff --git a/gruntfile.js b/gruntfile.js index 384b04500..c60bb1745 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -1,6 +1,6 @@ 'use strict'; -module.exports = function(grunt) { +module.exports = function (grunt) { grunt.loadNpmTasks('grunt-babel'); grunt.loadNpmTasks('grunt-browserify'); grunt.loadNpmTasks('grunt-terser'); @@ -114,9 +114,9 @@ module.exports = function(grunt) { copy: { dist: { files: [ - {expand: true, src: ['**'], cwd: './build/lib', dest: './dist/es5'}, - {src: './build/lib/exceljs.nodejs.js', dest: './dist/es5/index.js'}, - {src: './LICENSE', dest: './dist/LICENSE'}, + { expand: true, src: ['**'], cwd: './build/lib', dest: './dist/es5' }, + { src: './build/lib/exceljs.nodejs.js', dest: './dist/es5/index.js' }, + { src: './LICENSE', dest: './dist/LICENSE' }, ], }, }, diff --git a/index.d.ts b/index.d.ts index af7524ca7..e70302e4c 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,1508 +1,1613 @@ -declare interface Buffer extends ArrayBuffer { } +declare interface Buffer extends ArrayBuffer {} export declare enum RelationshipType { - None = 0, - OfficeDocument = 1, - Worksheet = 2, - CalcChain = 3, - SharedStrings = 4, - Styles = 5, - Theme = 6, - Hyperlink = 7 + None = 0, + OfficeDocument = 1, + Worksheet = 2, + CalcChain = 3, + SharedStrings = 4, + Styles = 5, + Theme = 6, + Hyperlink = 7, } export declare enum DocumentType { - Xlsx = 1 + Xlsx = 1, } export const enum PaperSize { - Legal = 5, - Executive = 7, - A4 = 9, - A5 = 11, - B5 = 13, - Envelope_10 = 20, - Envelope_DL = 27, - Envelope_C5 = 28, - Envelope_B5 = 34, - Envelope_Monarch = 37, - Double_Japan_Postcard_Rotated = 82, - K16_197x273_mm = 119, + Legal = 5, + Executive = 7, + A4 = 9, + A5 = 11, + B5 = 13, + Envelope_10 = 20, + Envelope_DL = 27, + Envelope_C5 = 28, + Envelope_B5 = 34, + Envelope_Monarch = 37, + Double_Japan_Postcard_Rotated = 82, + K16_197x273_mm = 119, } export interface WorksheetViewCommon { - /** - * Sets the worksheet view's orientation to right-to-left, `false` by default - */ - rightToLeft: boolean; - - /** - * The currently selected cell - */ - activeCell: string; - - /** - * Shows or hides the ruler in Page Layout, `true` by default - */ - showRuler: boolean; - - /** - * Shows or hides the row and column headers (e.g. A1, B1 at the top and 1,2,3 on the left, - * `true` by default - */ - showRowColHeaders: boolean; - - /** - * Shows or hides the gridlines (shown for cells where borders have not been defined), - * `true` by default - */ - showGridLines: boolean; - - /** - * Percentage zoom to use for the view, `100` by default - */ - zoomScale: number; - - /** - * Normal zoom for the view, `100` by default - */ - zoomScaleNormal: number; + /** + * Sets the worksheet view's orientation to right-to-left, `false` by default + */ + rightToLeft: boolean; + + /** + * The currently selected cell + */ + activeCell: string; + + /** + * Shows or hides the ruler in Page Layout, `true` by default + */ + showRuler: boolean; + + /** + * Shows or hides the row and column headers (e.g. A1, B1 at the top and 1,2,3 on the left, + * `true` by default + */ + showRowColHeaders: boolean; + + /** + * Shows or hides the gridlines (shown for cells where borders have not been defined), + * `true` by default + */ + showGridLines: boolean; + + /** + * Percentage zoom to use for the view, `100` by default + */ + zoomScale: number; + + /** + * Normal zoom for the view, `100` by default + */ + zoomScaleNormal: number; } export interface WorksheetViewNormal { - /** - * Controls the view state - */ - state: 'normal'; + /** + * Controls the view state + */ + state: 'normal'; - /** - * Presentation style - */ - style: 'pageBreakPreview' | 'pageLayout'; + /** + * Presentation style + */ + style: 'pageBreakPreview' | 'pageLayout'; } export interface WorksheetViewFrozen { - /** - * Where a number of rows and columns to the top and left are frozen in place. - * Only the bottom left section will scroll - */ - state: 'frozen'; - - /** - * Presentation style - */ - style?: 'pageBreakPreview'; - - /** - * How many columns to freeze. To freeze rows only, set this to 0 or undefined - */ - xSplit?: number; - - /** - * How many rows to freeze. To freeze columns only, set this to 0 or undefined - */ - ySplit?: number; - - /** - * Which cell will be top-left in the bottom-right pane. Note: cannot be a frozen cell. - * Defaults to first unfrozen cell - */ - topLeftCell?: string; + /** + * Where a number of rows and columns to the top and left are frozen in place. + * Only the bottom left section will scroll + */ + state: 'frozen'; + + /** + * Presentation style + */ + style?: 'pageBreakPreview'; + + /** + * How many columns to freeze. To freeze rows only, set this to 0 or undefined + */ + xSplit?: number; + + /** + * How many rows to freeze. To freeze columns only, set this to 0 or undefined + */ + ySplit?: number; + + /** + * Which cell will be top-left in the bottom-right pane. Note: cannot be a frozen cell. + * Defaults to first unfrozen cell + */ + topLeftCell?: string; } export interface WorksheetViewSplit { - /** - * Where the view is split into 4 sections, each semi-independently scrollable. - */ - state: 'split'; - - /** - * Presentation style - */ - style?: 'pageBreakPreview' | 'pageLayout'; - - /** - * How many points from the left to place the splitter. - * To split vertically, set this to 0 or undefined - */ - xSplit?: number; - - /** - * How many points from the top to place the splitter. - * To split horizontally, set this to 0 or undefined - */ - ySplit?: number; - - /** - * Which cell will be top-left in the bottom-right pane - */ - topLeftCell?: string; - - /** - * Which pane will be active - */ - activePane?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'; -} - -export type WorksheetView = - & WorksheetViewCommon - & (WorksheetViewNormal | WorksheetViewFrozen | WorksheetViewSplit); + /** + * Where the view is split into 4 sections, each semi-independently scrollable. + */ + state: 'split'; + + /** + * Presentation style + */ + style?: 'pageBreakPreview' | 'pageLayout'; + + /** + * How many points from the left to place the splitter. + * To split vertically, set this to 0 or undefined + */ + xSplit?: number; + + /** + * How many points from the top to place the splitter. + * To split horizontally, set this to 0 or undefined + */ + ySplit?: number; + + /** + * Which cell will be top-left in the bottom-right pane + */ + topLeftCell?: string; + + /** + * Which pane will be active + */ + activePane?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'; +} + +export type WorksheetView = WorksheetViewCommon & + (WorksheetViewNormal | WorksheetViewFrozen | WorksheetViewSplit); export interface WorkbookView { - x: number; - y: number; - width: number; - height: number; - firstSheet: number; - activeTab: number; - visibility: string; + x: number; + y: number; + width: number; + height: number; + firstSheet: number; + activeTab: number; + visibility: string; } export type FillPatterns = - | 'none' | 'solid' - | 'darkVertical' | 'darkHorizontal' | 'darkGrid' | 'darkTrellis' | 'darkDown' | 'darkUp' - | 'lightVertical' | 'lightHorizontal' | 'lightGrid' | 'lightTrellis' | 'lightDown' | 'lightUp' - | 'darkGray' | 'mediumGray' | 'lightGray' | 'gray125' | 'gray0625'; + | 'none' + | 'solid' + | 'darkVertical' + | 'darkHorizontal' + | 'darkGrid' + | 'darkTrellis' + | 'darkDown' + | 'darkUp' + | 'lightVertical' + | 'lightHorizontal' + | 'lightGrid' + | 'lightTrellis' + | 'lightDown' + | 'lightUp' + | 'darkGray' + | 'mediumGray' + | 'lightGray' + | 'gray125' + | 'gray0625'; export interface FillPattern { - type: 'pattern'; - pattern: FillPatterns; - fgColor?: Partial; - bgColor?: Partial; + type: 'pattern'; + pattern: FillPatterns; + fgColor?: Partial; + bgColor?: Partial; } export interface GradientStop { - position: number; - color: Partial; + position: number; + color: Partial; } export interface FillGradientAngle { - type: 'gradient'; - gradient: 'angle'; + type: 'gradient'; + gradient: 'angle'; - /** - * For 'angle' gradient, specifies the direction of the gradient. 0 is from the left to the right. - * Values from 1 - 359 rotates the direction clockwise - */ - degree: number; + /** + * For 'angle' gradient, specifies the direction of the gradient. 0 is from the left to the right. + * Values from 1 - 359 rotates the direction clockwise + */ + degree: number; - /** - * Specifies the gradient colour sequence. Is an array of objects containing position and - * color starting with position 0 and ending with position 1. - * Intermediary positions may be used to specify other colours on the path. - */ - stops: GradientStop[]; + /** + * Specifies the gradient colour sequence. Is an array of objects containing position and + * color starting with position 0 and ending with position 1. + * Intermediary positions may be used to specify other colours on the path. + */ + stops: GradientStop[]; } export interface FillGradientPath { - type: 'gradient'; - gradient: 'path'; + type: 'gradient'; + gradient: 'path'; - /** - * For 'path' gradient. Specifies the relative coordinates for the start of the path. - * 'left' and 'top' values range from 0 to 1 - */ - center: { left: number; top: number }; + /** + * For 'path' gradient. Specifies the relative coordinates for the start of the path. + * 'left' and 'top' values range from 0 to 1 + */ + center: { left: number; top: number }; - /** - * Specifies the gradient colour sequence. Is an array of objects containing position and - * color starting with position 0 and ending with position 1. - * Intermediary positions may be used to specify other colours on the path. - */ - stops: GradientStop[]; + /** + * Specifies the gradient colour sequence. Is an array of objects containing position and + * color starting with position 0 and ending with position 1. + * Intermediary positions may be used to specify other colours on the path. + */ + stops: GradientStop[]; } export type Fill = FillPattern | FillGradientAngle | FillGradientPath; export interface Font { - name: string; - size: number; - family: number; - scheme: 'minor' | 'major' | 'none'; - charset: number; - color: Partial; - bold: boolean; - italic: boolean; - underline: boolean | 'none' | 'single' | 'double' | 'singleAccounting' | 'doubleAccounting'; - vertAlign: 'superscript' | 'subscript'; - strike: boolean; - outline: boolean; + name: string; + size: number; + family: number; + scheme: 'minor' | 'major' | 'none'; + charset: number; + color: Partial; + bold: boolean; + italic: boolean; + underline: boolean | 'none' | 'single' | 'double' | 'singleAccounting' | 'doubleAccounting'; + vertAlign: 'superscript' | 'subscript'; + strike: boolean; + outline: boolean; } export type BorderStyle = - | 'thin' | 'dotted' | 'hair' | 'medium' | 'double' | 'thick' | 'dashed' | 'dashDot' - | 'dashDotDot' | 'slantDashDot' | 'mediumDashed' | 'mediumDashDotDot' | 'mediumDashDot'; + | 'thin' + | 'dotted' + | 'hair' + | 'medium' + | 'double' + | 'thick' + | 'dashed' + | 'dashDot' + | 'dashDotDot' + | 'slantDashDot' + | 'mediumDashed' + | 'mediumDashDotDot' + | 'mediumDashDot'; export interface Color { - /** - * Hex string for alpha-red-green-blue e.g. FF00FF00 - */ - argb: string; + /** + * Hex string for alpha-red-green-blue e.g. FF00FF00 + */ + argb: string; - /** - * Choose a theme by index - */ - theme: number; + /** + * Choose a theme by index + */ + theme: number; } export interface Border { - style: BorderStyle; - color: Partial; + style: BorderStyle; + color: Partial; } export interface BorderDiagonal extends Border { - up: boolean; - down: boolean; + up: boolean; + down: boolean; } export interface Borders { - top: Partial; - left: Partial; - bottom: Partial; - right: Partial; - diagonal: Partial; + top: Partial; + left: Partial; + bottom: Partial; + right: Partial; + diagonal: Partial; } export interface Margins { - top: number; - left: number; - bottom: number; - right: number; - header: number; - footer: number; + top: number; + left: number; + bottom: number; + right: number; + header: number; + footer: number; } export declare enum ReadingOrder { - LeftToRight = 1, - RightToLeft = 2, + LeftToRight = 1, + RightToLeft = 2, } export interface Alignment { - horizontal: 'left' | 'center' | 'right' | 'fill' | 'justify' | 'centerContinuous' | 'distributed'; - vertical: 'top' | 'middle' | 'bottom' | 'distributed' | 'justify'; - wrapText: boolean; - shrinkToFit: boolean; - indent: number; - readingOrder: 'rtl' | 'ltr'; - textRotation: number | 'vertical'; + horizontal: 'left' | 'center' | 'right' | 'fill' | 'justify' | 'centerContinuous' | 'distributed'; + vertical: 'top' | 'middle' | 'bottom' | 'distributed' | 'justify'; + wrapText: boolean; + shrinkToFit: boolean; + indent: number; + readingOrder: 'rtl' | 'ltr'; + textRotation: number | 'vertical'; } export interface Protection { - locked: boolean; - hidden: boolean; + locked: boolean; + hidden: boolean; } export interface Style { - numFmt: string; - font: Partial; - alignment: Partial; - protection: Partial; - border: Partial; - fill: Fill; + numFmt: string; + font: Partial; + alignment: Partial; + protection: Partial; + border: Partial; + fill: Fill; } export type DataValidationOperator = - | 'between' | 'notBetween' | 'equal' | 'notEqual' | 'greaterThan' | 'lessThan' - | 'greaterThanOrEqual' | 'lessThanOrEqual'; + | 'between' + | 'notBetween' + | 'equal' + | 'notEqual' + | 'greaterThan' + | 'lessThan' + | 'greaterThanOrEqual' + | 'lessThanOrEqual'; export interface DataValidation { - type: 'list' | 'whole' | 'decimal' | 'date' | 'textLength' | 'custom'; - formulae: any[]; - allowBlank?: boolean; - operator?: DataValidationOperator; - error?: string; - errorTitle?: string; - errorStyle?: string; - prompt?: string; - promptTitle?: string; - showErrorMessage?: boolean; - showInputMessage?: boolean; + type: 'list' | 'whole' | 'decimal' | 'date' | 'textLength' | 'custom'; + formulae: any[]; + allowBlank?: boolean; + operator?: DataValidationOperator; + error?: string; + errorTitle?: string; + errorStyle?: string; + prompt?: string; + promptTitle?: string; + showErrorMessage?: boolean; + showInputMessage?: boolean; } export declare enum ErrorValue { - NotApplicable = '#N/A', - Ref = '#REF!', - Name = '#NAME?', - DivZero = '#DIV/0!', - Null = '#NULL!', - Value = '#VALUE!', - Num = '#NUM!', + NotApplicable = '#N/A', + Ref = '#REF!', + Name = '#NAME?', + DivZero = '#DIV/0!', + Null = '#NULL!', + Value = '#VALUE!', + Num = '#NUM!', } export interface CellErrorValue { - error: '#N/A' | '#REF!' | '#NAME?' | '#DIV/0!' | '#NULL!' | '#VALUE!' | '#NUM!'; + error: '#N/A' | '#REF!' | '#NAME?' | '#DIV/0!' | '#NULL!' | '#VALUE!' | '#NUM!'; } export interface RichText { - text: string; - font?: Partial; + text: string; + font?: Partial; } export interface CellRichTextValue { - richText: RichText[]; + richText: RichText[]; } export interface CellHyperlinkValue { - text: string; - hyperlink: string; - tooltip?: string; + text: string; + hyperlink: string; + tooltip?: string; } export interface CellFormulaValue { - formula: string; - result?: number | string | boolean | Date | CellErrorValue; - date1904?: boolean; + formula: string; + result?: number | string | boolean | Date | CellErrorValue; + date1904?: boolean; } export interface CellSharedFormulaValue { - sharedFormula: string; - readonly formula?: string; - result?: number | string | boolean | Date | CellErrorValue; - date1904?: boolean; + sharedFormula: string; + readonly formula?: string; + result?: number | string | boolean | Date | CellErrorValue; + date1904?: boolean; } export declare enum ValueType { - Null = 0, - Merge = 1, - Number = 2, - String = 3, - Date = 4, - Hyperlink = 5, - Formula = 6, - SharedString = 7, - RichText = 8, - Boolean = 9, - Error = 10 + Null = 0, + Merge = 1, + Number = 2, + String = 3, + Date = 4, + Hyperlink = 5, + Formula = 6, + SharedString = 7, + RichText = 8, + Boolean = 9, + Error = 10, } export declare enum FormulaType { - None = 0, - Master = 1, - Shared = 2 + None = 0, + Master = 1, + Shared = 2, } export type CellValue = - | null | number | string | boolean | Date | undefined - | CellErrorValue - | CellRichTextValue | CellHyperlinkValue - | CellFormulaValue | CellSharedFormulaValue; + | null + | number + | string + | boolean + | Date + | undefined + | CellErrorValue + | CellRichTextValue + | CellHyperlinkValue + | CellFormulaValue + | CellSharedFormulaValue; +export interface CommentMargins { + insetmode: 'auto' | 'custom'; + inset: Number[]; +} - export interface CommentMargins { - insetmode: 'auto' | 'custom'; - inset: Number[]; - } - - export interface CommentProtection { - locked: 'True' | 'False'; - lockText: 'True' | 'False'; - } +export interface CommentProtection { + locked: 'True' | 'False'; + lockText: 'True' | 'False'; +} - export type CommentEditAs = 'twoCells' | 'oneCells' | 'absolute'; +export type CommentEditAs = 'twoCells' | 'oneCells' | 'absolute'; - export interface Comment { - texts?: RichText[]; - margins?: Partial; - protection?: Partial; - editAs?: CommentEditAs; - } +export interface Comment { + texts?: RichText[]; + margins?: Partial; + protection?: Partial; + editAs?: CommentEditAs; +} export interface CellModel { - address: Address; - style: Style; - type: ValueType; - text?: string; - hyperlink?: string; - value?: CellValue; - master: string; - formula?: string; - sharedFormula?: string; - result?: string | number | any; - comment: Comment; + address: Address; + style: Style; + type: ValueType; + text?: string; + hyperlink?: string; + value?: CellValue; + master: string; + formula?: string; + sharedFormula?: string; + result?: string | number | any; + comment: Comment; } export interface Cell extends Style, Address { - readonly worksheet: Worksheet; - readonly workbook: Workbook; - - readonly effectiveType: ValueType; - readonly isMerged: boolean; - readonly master: Cell; - readonly isHyperlink: boolean; - readonly hyperlink: string; // todo - readonly text: string; - readonly fullAddress: { - sheetName: string; - address: string; - row: number; - col: number; - }; - model: CellModel; - /** - * Assign (or get) a name for a cell (will overwrite any other names that cell had) - */ - name: string; - - /** - * Assign (or get) an array of names for a cell (cells can have more than one name) - */ - names: string[]; - - /** - * Cells can define what values are valid or not and provide - * prompting to the user to help guide them. - */ - dataValidation: DataValidation; - - /** - * Value of the cell - */ - value: CellValue; - - /** - * comment of the cell - */ - note: string | Comment; - - /** - * convenience getter to access the formula - */ - readonly formula: string; - - /** - * convenience getter to access the formula result - */ - readonly result: number | string | Date; - - /** - * The type of the cell's value - */ - readonly type: ValueType; - - /** - * The type of the cell's formula - */ - readonly formulaType: FormulaType; - - /** - * The styles of the cell - */ - style: Partial