{"id":15022313,"url":"https://github.com/icheer/web-spreadsheet","last_synced_at":"2025-10-23T14:31:09.252Z","repository":{"id":45960354,"uuid":"361361702","full_name":"icheer/web-spreadsheet","owner":"icheer","description":"A simple Excel-like spreadsheet web component built with svelte.","archived":false,"fork":false,"pushed_at":"2021-11-24T10:32:46.000Z","size":208,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-10-29T21:02:42.757Z","etag":null,"topics":["customelement","spreadsheet","svelte","webcomponent"],"latest_commit_sha":null,"homepage":"https://spread.vercel.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/icheer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-04-25T07:34:13.000Z","updated_at":"2024-04-13T08:26:24.000Z","dependencies_parsed_at":"2022-08-28T15:20:21.764Z","dependency_job_id":null,"html_url":"https://github.com/icheer/web-spreadsheet","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icheer%2Fweb-spreadsheet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icheer%2Fweb-spreadsheet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icheer%2Fweb-spreadsheet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/icheer%2Fweb-spreadsheet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/icheer","download_url":"https://codeload.github.com/icheer/web-spreadsheet/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":237843687,"owners_count":19375184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["customelement","spreadsheet","svelte","webcomponent"],"created_at":"2024-09-24T19:57:46.790Z","updated_at":"2025-10-23T14:31:08.878Z","avatar_url":"https://github.com/icheer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# web-spreadsheet\n\nA simple Excel-like spreadsheet web component built with [svelte](https://github.com/sveltejs/svelte).\n\n- dependency free\n- compatible with any javascript framework/UI library\n- light-weighted (size: 35KB, gzip: ~12KB)\n- multiple cell type supported (input, select, multi-select, image, date, time)\n- support customized **validator**, **formatter** and **computed** function\n- support UNDO/REDO with ctrl+Z \u0026 ctrl+Y\n\n## Online demo\n\n[https://spread.vercel.app](https://spread.vercel.app)\n\n![screenshot](https://i.ibb.co/FJrhmc4/spread-shot.png)\n\n## How to use\n\nInstall with npm:\n\n```bash\nnpm install web-spreadsheet --save\n```\n\nand import it in your code:\n\n```js\nimport 'web-spreadsheet';\n```\n\nYou can **also** load the code from a CDN such as jsdelivr:\n\n```js\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/web-spreadsheet@latest/lib/index.min.js\"\u003e\u003c/script\u003e\n```\n\nthen you can use the customElement `\u003cspread-sheet\u003e\u003c/spread-sheet\u003e` in your HTML code.\n\nIf you're using it in a Vue.js project, you can pass proper props **columns** and **data** into customElement such as `\u003cspread-sheet :columns=\"columns\" :data=\"rows\"/\u003e`\nThen your spreadsheet will come into view.\n\nThe **columns** and **data** props look like these:\n\n```js\ndata() {\n  return {\n    columns: [\n      {\n        text: 'Fullname',\n        key: 'fullname',\n        type: 'input',\n        width: '200px',\n        props: {\n          maxlength: 25\n        },\n        params: {\n          validator: (value, row) =\u003e {\n            const name = (value || '').trim();\n            if (!name) return 'Please enter Fullname';\n            if (name.length \u003e 25) return 'Fullname length should less than 25';\n          }\n        }\n      },\n      {\n        text: 'Department',\n        key: 'dept',\n        type: 'select',\n        width: '8em',\n        items: [\n          { label: 'Operation', value: 'OP' },\n          { label: 'IT Support', value: 'IT' }\n        ]\n      },\n      {\n        text: 'Identity type',\n        key: 'idType',\n        type: 'multi-select',\n        width: '6em',\n        items: [\n          { label: 'ID Card', value: 'ID' },\n          { label: 'Passport', value: 'PASSPORT' }\n        ]\n      },\n      {\n        text: 'Identity number',\n        key: 'idNumber',\n        type: 'input',\n        width: '9em',\n        props: {\n          maxlength: 18\n        }\n      },\n      {\n        text: 'Fee',\n        key: 'fee',\n        align: 'right',\n        type: 'input',\n        width: '5em',\n        props: {\n          maxlength: 8\n        },\n        params: {\n          validator: str =\u003e {\n            if (!str) return;\n            const num = +str;\n            if (Number.isNaN(num)) return 'Please enter a number';\n          },\n          formatter: str =\u003e {\n            const num = +str;\n            return num.toFixed(2);\n          }\n        }\n      },\n      {\n        text: 'Total Fee(+10)',\n        key: 'totalFee',\n        align: 'right',\n        type: 'input',\n        width: '9em',\n        props: {\n          maxlength: 8\n        },\n        params: {\n          validator: str =\u003e {\n            if (!str) return;\n            const num = +str;\n            if (Number.isNaN(num)) return 'Please enter a number';\n          },\n          formatter: str =\u003e {\n            const num = +str;\n            return num.toFixed(2);\n          },\n          computed: (row, column) =\u003e {\n            const num = +row.fee || 0;\n            return (num + 10).toFixed(2);\n          }\n        }\n      },\n      {\n        text: 'Pictures',\n        key: 'pics',\n        type: 'image',\n        width: '8.5em',\n        props: {\n          max: 3, // means can upload 3 pics at most\n          uploadApi: 'http://192.168.105.11:28080/api/file/common/upload'\n        }\n      },\n      {\n        text: 'Update Time',\n        key: 'updateTime',\n        type: 'date',\n        width: '8em'\n      }\n    ],\n    rows: [\n      {\n        fullName: 'Tony Joe',\n        dept: 'OP',\n        idType: ['ID', 'PASSPORT'],\n        idNumber: '12341122234',\n        fee: 33,\n        pics: [\n          'https://github.blog/wp-content/uploads/2019/03/product-social.png?fit=1201%2C630',\n          '//fpoimg.com/400x400?text=Preview\u0026bg_color=000000',\n          '//fpoimg.com/400x400?text=Preview\u0026bg_color=ffeeee'\n        ],\n        updateTime: '2020-02-01'\n      },\n      {\n        fullName: 'Mary Lee',\n        dept: 'IT',\n        idType: ['ID'],\n        idNumber: '6515151374',\n        fee: 25,\n        pics: [\n          '//fpoimg.com/400x400?text=Preview\u0026bg_color=eeffee'\n        ],\n        updateTime: '2020-02-02'\n      }\n    ]\n  }\n}\n```\n\nIf you want to use it in pure javascript, you can refer the [demo page](https://spread.vercel.app).\n\n## FEATURES\n- cell type: input, select, multi-select, image, date, time (depends on columns array)\n- when the row data changed, it will automaticly emit a \"change\" event, so you can handle the newest row data\n- validator / formatter / computed functions can be added in column.params object\n- log at most 20 change history in memory, so you can press ctrl+Z/Y to UNDO/REDO\n- right clicking the row head can call the context menu which can insert/delete the row\n- upload images and preview images\n- support sort by column\n- auto switch languages(CN or EN) depends on your `\u003chtml lang=\"___\"\u003e`\n- keypress behavior like Excel (arrows, escape, tab, delete, backspace etc)\n- pasted letters by ctrl+V will fill current highlighted input cell\n- for those non-modern browsers which don't support shadowDOM or customElement, you can use polyfill to let them support: just add a `\u003cscript src=\"https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs@2.5.0/webcomponents-bundle.min.js\"\u003e\u003c/script\u003e` in `\u003chead\u003e`\n\n## TODO\n- [ ] column actions such as insert/delete column\n- [ ] ...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficheer%2Fweb-spreadsheet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ficheer%2Fweb-spreadsheet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ficheer%2Fweb-spreadsheet/lists"}