A drop-in javascript spreadsheet library that provides rich features like Excel and Google Sheets

Overview

FortuneSheet

FortuneSheet is a drop-in javascript spreadsheet library that provides rich features like Excel and Google Sheets

CircleCI Status Known Vulnerabilities Build with father xiemala

English | 简体中文

Purpose

The goal of FortuneSheet is to make a feature-rich, easy-to-configure online spreadsheet that you can use out-of-the-box.

This project is originated from Luckysheet and has inherited many code from it. Lots of efforts have done to translate the whole project to typescript (still in progress), and solved problems in the design of the original project.

We aim to make FortuneSheet powerful yet easy to maintain.

Live demo

Take a look at the live demo at fortune-sheet-demo

Attention

Before stable release of 1.0, input data structure and APIs may change during development. If you encounter errors after upgrading a version, check Changelog and Migration Guide.

Improvements to Luckysheet

  • Written fully in typescript.
  • You can now use import / require to use the library.
    import { Workbook } from '@fortune-sheet/react'
  • Multiple instance on the same page is supported.
  • Dropped jQuery dependency, uses native React / Vue + immer to manage the dom and state.
  • Changed to a forked handsontable/formula-parser to handle formula calculations.
  • Optimized the dom structure.
  • Replaced icons from iconfont with SVGs, as iconfont icons are inconvenient to update for other maintainers.
  • No visible elements is created outside container.
  • Never stores data in the window object.

Features

  • Data structure is mostly compatible with Luckysheet (see Migration Guide).
  • Formatting: style, text alignment and rotation, text truncation, overflow, automatic line wrapping, multiple data types, cell segmentation style
  • Cells: multiple selection, merge cells
  • Row & column: insert, delete rows or columns
  • Operation: copy, paste, cut, hot key
  • Formulas & Functions: Built-in formulas

Roadmap

  • Support cooperative editing with backend storage.
  • Support undo/redo.
  • Mobile adaption.
  • Expose APIs.
  • Add tests.
  • More basic features:
    • fill handle
    • fonts
    • format painter
    • comments
    • insert images
    • more toolbar buttons
  • Excel import and export.
  • Support Vue.
  • More features:
    • sort
    • filter
    • hooks
    • conditional formatting
    • drag and drop
    • find and replace
    • location
    • data verification
    • freeze
    • hide, and split text
  • More advanced features:
    • pivot tables
    • charts
    • screenshots

Documentation

See detailed documentation at fortune-sheet-doc

Get started (react)

Download and install the library

yarn add @fortune-sheet/react

or using npm:

npm install @fortune-sheet/react

Create an HTML placeholder

<style>
  html, body, #root {
    width: 100%;
    height: 100%;
  }
</style>
<div id="root"></div>

NOTE: width and height doesn't have to be 100%, but should at least have a value. If set to auto, table area may not show.

Render the sheet

import React from 'react';
import ReactDOM from 'react-dom';
import { Workbook } from "@fortune-sheet/react";
import "@fortune-sheet/react/dist/index.css"

ReactDOM.render(
  <Workbook data={[{ name: "Sheet1" }]} />,
  document.getElementById('root')
);

Backend storage and collabration

Each time a user operates on the sheet, an array of Op will be emiited through onOp callback. An op describes how to modify the current data to reach the new data after the user's operation. For example, here is an op when user sets the cell font to be bold on cell A2.

[
    {
        "op": "replace",
        "index": "0",
        "path": ["data", 1, 0, "bl"],
        "value": 1
    }
]

The op is useful for database modification and syncing state in online collabration.

A working example with Express (backend server) and MongoDB (data persistence) is avaiable in backend-demo folder.

Run it with node index.js and visit Collabration example (initialize data by visiting http://localhost:8081/init)

For detailed doc about Op, refer to fortune-sheet-doc

Migrating data from Luckysheet

The overall data structure of FortuneSheet is the same as Luckysheet, with some naming differences:

  1. sheet.index -> sheet.id
  2. sheet.calcChain[].id -> sheet.calcChain[].id

Contributing

Expected workflow is: Fork -> Patch -> Push -> Pull Request

Please make sure to read the Contributing Guide before making a pull request.

Development

Installation

yarn

Development

yarn dev

Packaging

yarn build

License

This project is licensed under the MIT License. See MIT for the full license text.

Comments
  • 请问如何二次使用data参数重新初始化?

    请问如何二次使用data参数重新初始化?

    Is your feature request related to a problem? Please describe. 目前表格的初始化为获取到远端data配置后完成第一次加载,但如果使用useState存储data的时候,当data更新后表格不会重新渲染到新的data配置,不知道是否有其他方法可以手动/自动触发这个加载?

    Describe the solution you'd like 当data存储在useSatate时,若更新data则表格重新渲染到新的data

    opened by Minfee 13
  • Uncaught TypeError: Cannot use 'in' operator to search for 'mc' in 1286

    Uncaught TypeError: Cannot use 'in' operator to search for 'mc' in 1286

    Describe the bug

    I'm trying to show a SQL query output in a fortune-sheet worksheet. I'm rendering the worksheet using the following code

    <Workbook
      showToolbar={false}
      showSheetTabs={false}
      data={[
        {
          name: "Sheet1",
          celldata: cellData,
        },
      ]}
    />
    
    

    There is a glimpse of the worksheet being rendered for a second and the app crashes with the following exception,

    Uncaught TypeError: Cannot use 'in' operator to search for 'mc' in 1286
        at mergeBorder (index.esm.js:48304:1)
        at getCellRowColumn (index.esm.js:55025:1)
        at index.esm.js:2247:1
        at index.esm.js:2260:1
        at e.produce (immerClass.ts:94:1)
        at e.produceWithPatches (immerClass.ts:141:1)
        at index.esm.js:7438:1
        at basicStateReducer (react-dom.development.js:16540:1)
        at updateReducer (react-dom.development.js:16664:1)
        at updateState (react-dom.development.js:17004:1)
    

    To Reproduce Steps to reproduce the behavior:

    1. Render the sheet
    2. Wait for a couple of seconds before the app is crashed

    Expected behavior The worksheet shouldn't crash.

    Screenshots ezgif com-gif-maker (5)

    opened by sandilya28 8
  • Issue with line breaking

    Issue with line breaking

    Describe the bug When there is multiple rows in a cell, then delete the last row, then the words aligment is wrong, especially under "horizontal center" style.

    To Reproduce Steps to reproduce the behavior:

    1. Input multipe rows in the same cell with "alt+enter".
    2. Delete the last row, and the count of ramining rows is more than one.
    3. See the style error.

    Screenshots image

    opened by SuyongSun 8
  • Add default rows to add from configuration of sheet

    Add default rows to add from configuration of sheet

    Pick number of rows for add button from default configuration. IMG_20221219_000355

    Pic from configuration of sheet data. https://ruilisi.github.io/fortune-sheet-docs/guide/sheet.html

    opened by gudipudipradeep 7
  • steps to setup development environment

    steps to setup development environment

    how to setup the development environment to customized or extend functionality. Please guide the steps after cloning this repo with some example to change the type script.

    So that people can contribute and raise the pull request for bugs and importants.

    Development steps and guidelines, pull request standards.

    How to setup package folder contains core, formula and react to start and open basic sheet by importing modules, it will help.

    opened by gudipudipradeep 6
  • Options column, row, lang

    Options column, row, lang "zh_tw" are ignored

    Describe the bug Options column, row, lang "zh_tw" are ignored

    To Reproduce Steps to reproduce the behavior:

    1. Try to fill in any number for column or row, also set lang option "zh_tw"
    2. Column / row count is still the default, despite options passed. Language zh_tw render English context menu

    Expected behavior For the documented options to work as advertised.

    Screenshots image

    Additional context I see that this sandbox uses an old version, but it's the same in the latest that I installed today.

    opened by kimgysen 5
  • When readOnly mode, text field formula bar is still editable + the user can swtich the sheet position

    When readOnly mode, text field formula bar is still editable + the user can swtich the sheet position

    Describe the bug When the config allowEdit is false, the text field in the formula bar should not be editable AND The user can still move the sheet name from the right or left position

    To Reproduce

    1. Set config allowEdit to false
    2. Select a cell
    3. click on the formula bar and edit the content (the cell value is not updated, but the formula bar value should be editable)
    4. Open an Excel file with more than 1 sheet (2 or 3)
    5. You can still move (drag and drop) one sheet before or after another

    Expected behavior The text field should not be editable (read-only) and the sheet order should not be changed

    Screenshots image image

    opened by nicoesiea 5
  • Scrollbar out of the box

    Scrollbar out of the box

    Describe the bug The horizontal scrollbar is out of the container. The scroll bar width exceeds the width of the container

    To Reproduce Default behavior

    Expected behavior The scrollbar width stays inside the container

    Screenshots image I can change my application setting to use a discreet scrollbar design, even in this mode we can see the width is too big: image

    Additional context I'm using Angular 13 with the react plugin loaded with a wrapper (just for you to know)

    opened by nicoesiea 5
  • devicePixelRatio seems to be ignored

    devicePixelRatio seems to be ignored

    Describe the bug The devicePixelRatio seems to be ignored

    To Reproduce Steps to reproduce the behavior:

    1. Add devicePixelRatio prop
    2. Set any number

    Expected behavior Expecting to get some visual feedback when changing the value. (Also needs to work when the prop changes value)

    Screenshots image

    opened by kimgysen 4
  • Limiting rows and columns are not working

    Limiting rows and columns are not working

    "row": 36, //the number of rows in a sheet "column": 18, //the number of columns in a sheet

    set the attributes as per the document https://ruilisi.github.io/fortune-sheet-docs/guide/sheet.html#initial followed the above document got more rows and columns image

    opened by gudipudipradeep 4
  • Workbook sheets does not re-render when I update the data prop.

    Workbook sheets does not re-render when I update the data prop.

    Describe the bug Workbook sheets does not re-render when I change the data prop within a button click event.

    To Reproduce Steps to reproduce the behavior:

    1. Go to fortune-sheet-react-sample repo and clone it.
    2. yarn install
    3. yarn start
    4. When I click the "Set New Sheets" button then I create the new state with newData object and pass it to Workbook's data prop. But Workbook components does not re-render with new sheet and cells.

    Expected behavior I expect the Workbook component to re-render with new sheet.

    opened by yusufkayaer 4
  • fix: UNSAFE_componenWillUpdate and upgrade react to 18 version

    fix: UNSAFE_componenWillUpdate and upgrade react to 18 version

    image

    to resolve this exception:

    • refactor ContentEditable from a class to hooks
    • update react from 16 to 18
    • and as a bonus - upgrade another npm packages (jest, ...)
    opened by cybermerlin 1
  • React 18, filter menu: maximum update depth exceeded

    React 18, filter menu: maximum update depth exceeded

    Describe the bug A clear and concise description of what the bug is.

    To Reproduce Steps to reproduce the behavior:

    1. "@fortune-sheet/react": "^0.12.3",
    2. 右键展开菜单
    3. 点击筛选选区
    4. 点击单元格内选区按钮
    5. 可以看到报错 Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

    Expected behavior A clear and concise description of what you expected to happen.

    Screenshots

    image

    Unhandled Runtime Error
    Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
    
    Call Stack
    checkForNestedUpdates
    node_modules\.pnpm\[email protected][email protected]\node_modules\react-dom\cjs\react-dom.development.js (27292:0)
    scheduleUpdateOnFiber
    node_modules\.pnpm\[email protected][email protected]\node_modules\react-dom\cjs\react-dom.development.js (25475:0)
    dispatchSetState
    node_modules\.pnpm\[email protected][email protected]\node_modules\react-dom\cjs\react-dom.development.js (17527:0)
    

    Additional context Add any other context about the problem here.

    opened by fantasticit 3
  • replace image ops not work

    replace image ops not work

    Describe the bug

    replace image ops not work

    To Reproduce Steps to reproduce the behavior:

    workBook.applyOp([
            {
              op: "replace",
              value: [
                {
                  id: "img_0Ced0W06H1pa_1672390182991",
                  src: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAYAAADimHc4AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAUOSURBVHgB7Z1Lb1tFFMf/c+84ftsFQltBqdKoVQkpqkQpLFmAEGsktkiIDStWbFjxBfgCLPgQ8BkqVPEoCxSECrRF4IiGJhAnTurce2c44wc0TdJk5o49bnx+0liKHD9yfvM4c+4jQn95chtax2ACIJSEpgYhwQRAJRGYoLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwIymCJd1QUU+0lugxnW+R+E3OioFTr8FnHsPHTmL1eWv8XTrM5S7v1PBVYDZi9BfzCZeytGmx8+9Dyx+gnZWxM21+8go6DK9h4Wld1Dp3gbzMNpjObrwBHDxIxpTFdxe74J0kF2NLJ7F8pkPTekbzF78CaieBYonkCqN7Uw/8IRGp3qFp6AD8LgGiEEbPv6PpsU4TcyBt8j3hx7OTDb4EpPZAcYSi3RLYunzF2i8CRRo0C0UZzCWcAgaiRWa+hbv9tsEShiLAK0EJUhRfwSYqUiOcfvRjoFrc8C9KvDarYmTMB0bsZhGws1Z4J8yJo0p2glTz281MWlMjwCTmKkpXQMmAor9VitCokf7J5dOKhRPq77wIzA9Amisr1+XWFspYVSoHYFzH3dQPGLwDdNVKYv79cFRIWsK1Yu070iOPtVxOdoTphTWuJrS1sNunWEBnhC0wDeuUDU4tXsdC/CEbCqUzirYwgI8YKafyospYpvVdwAL8AEJaL5sP/0YWIAH5AmNynwGF1hATuiYE6rPZ87pLQvISyrQfJVK3m4DgAXkJSrT5mvBYfIfvh6MOzT9NC5nVGZyL/KxgByY9LP+SuKU/QxhATmIa+7ZzxAW4Egv+6HCW5zzIBsLcCWj2s9V9+xnCAtwRNZVL/+HffVhFyzABQp6+bxCPIPcsAAHtNl8mezHvvi5BxbggCgo1C8nuacfAwuwhYJev5QNz7LMDQuwxKSfDVP7Sf2c4sICLInLtPk672HyH8ACLBGU+cQlD5P/ABZgSdoW6Nzyd4MxFmALdf72d7J/wq8HWIAlJvvZuCHJAy/CwUjXI2z9FsGHAxbgQDSjsfFtgQUEgwK/QeuAylkJNbAAR5K1CPeX82dDLMARQVlQ+yvZO+M6DyzAFYrc5o+yV5rI+TaMK8mawPadfCFkATkwvb99o5AriiwgB/9tylhAOJLVCN2WexhZQE6E1Fj/RjpvysYmQGUCSvUbfDdzXZY4rGE096egN938XjofnRzLVZLRjMKzr7dgvq00Z1L6vFcEvdWvP0jcWZKPDLBx9NRWB0X4p3uXNmV/Riifsj9QMxYBcSHFqUt/UUccwT/qoA3R6i8l/LxaRHSAV9M7m/T4DPwdSNkFfW77ukT57R3rE7WmYg2IKfAXvBWQ92KyoU0agYim+Bqxg4JrQnKGWg0YVf/v0ZuG/rAf4Y+/AFqEa09qWtz3f7pGYZ+n5u8w+kHfwxwpsy9RP/4CqFs/t5igsM/qamKxQL/goWp8KGZ5a5t01HJVPRZTUL2h8cYHnd5tS3sjgaQoI4ZqBVXd/3kcbWeFNmUrdkPg2NysY+5Chnc/3cBP1wpo0+40pjjMAyNbePfD1IbSvwWKNCVO5e1qKiWNl97cQVCGI+KIHL/b1Yx8tfUL14ICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICwwICI6FFhtyXmmH3+R8PvVvvrEy9zxNTj8j+BW6Jeix1AVG9AAAAAElFTkSuQmCC",
                  left: 296,
                  top: 20,
                  width: 48,
                  height: 48,
                  originWidth: 96,
                  originHeight: 96,
                },
              ],
              path: ["images"],
              id: "cae3b6d9-2be6-43ba-b0d9-52beb24a2f05",
            },
          ])
    

    workbook not show image.

    Expected behavior A clear and concise description of what you expected to happen.

    Screenshots If applicable, add screenshots to help explain your problem.

    Additional context Add any other context about the problem here.

    opened by fantasticit 1
Releases(v0.12.3)
Owner
Suzhou Ruilisi Technology Co., Ltd
Suzhou Ruilisi Technology Co., Ltd
DataGridXL2 - Excel-like Experience for Web Apps Built in JavaScript

DataGridXL 2 Excel-like Experience for Web Apps Built in JavaScript ES6. Made in

DataGridXL 381 Jan 2, 2023
Powerful virtual data grid smartsheet with advanced customization. Best features from excel plus incredible performance 🔋

Powerful data grid component built with StencilJS. Support Millions of cells and thousands of columns easy and efficiently for fast data rendering. Ea

Revolist 2.2k Dec 30, 2022
react-xls is the fastest in-browser excel ( .xls & .xlsx ) parser for React. It is full of useful features such as useExcelDownloader, ... etc.

react-xls react-xls is the fastest in-browser excel ( .xls & .xlsx ) parser for React. ?? Features Compatible with both JavaScript and TypeScript ?? U

Bunlong VAN 13 Oct 12, 2022
An Excel-like grid component for React with custom cell editors, performant scroll & resizable columns

An Excel-like grid component for React with custom cell editors, performant scroll & resizable columns

Denis Raslov 1.1k Dec 30, 2022
react hook for using google spreadsheet as a data table (API endpoint)

use-google-spreadsheet helps developers use google spreadsheet as their data table (backend endpoint) Live Demo install npm install use-google-spreads

Dongwon Lim 106 Jul 13, 2022
Add spreadsheet-like behavior to your React app

ReactGrid MIT Add spreadsheet-like behavior to your React app ?? Browse our examples & docs: ?? reactgrid.com Before running ReactGrid you need to hav

Silevis Software 603 Jan 3, 2023
React component like SpreadSheet

React component like SpreadSheet

null 133 Dec 28, 2022
Beautiful and fast spreadsheet React component

Beautiful and fast spreadsheet React component

Farseer 39 Jul 15, 2022
React Data Grid with Spreadsheet Look & Feel. Official React wrapper for Handsontable.

Important information We permanently moved this project to the main Handsontable repository at https://github.com/handsontable/handsontable/tree/maste

Handsontable 520 Jan 2, 2023
A simple proof-of-concept probabilistic spreadsheet in React with Material-UI.

A simple proof-of-concept probabilistic spreadsheet in React with Material-UI.

David Singleton 12 Dec 22, 2022
React Tabulator is based on Tabulator - a JS table library with many advanced features.

react-tabulator React Tabulator is based on Tabulator - a JS table library with many advanced features. Link. Live Demo: Codesandbox Example code: /sr

Duc Ng 342 Dec 30, 2022
A high-performance React grid component, with rich rendering and first-class TypeScript support.

Glide Data Grid We built Data Grid as the basis for the Glide Data Editor. It's a React component built on top of HTML Canvas. It scales to millions o

Glide 2.4k Dec 27, 2022
Datatable for React based on material-ui's table with additional features

⚠️ Please do not create pull requests that contains a lot of change. Because we are working on refactoring and testing. Just pull requests that fixes

Mehmet Baran 3.4k Jan 4, 2023
A react table component with fucking difficult features

Fucking React Table A react table component with fucking difficult features, including Virtualized rows with fucking native table elements Sticky head

翁治平 9 Apr 1, 2022
@o2xp/react-datatable is a modulable component to render data in a table with some nice features !

@o2xp/react-datatable @o2xp/react-datatable is a modulable component to render data in a table with some nice features ! See a show case just here. Ta

O2XP 52 Dec 28, 2022
A powerful Bootstrap-like responsive grid system for React.

React Grid System A powerful Bootstrap-like responsive grid system for React. ⚠️ Upgrading to v7 react-grid-system v7 adds a new screen class xxl for

Sealninja 760 Jan 4, 2023
React Filtering like modern websites searching.

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Abolfaz 3 Apr 27, 2022
Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components

Module SonarCloud Status ag-grid-community ag-grid-enterprise ag-Grid ag-Grid is a fully-featured and highly customizable JavaScript data grid. It del

ag-Grid 9.5k Jan 7, 2023
A simple table library with built in sorting, pagination, selection, expandable rows and customizable styling.

React Data Table Component Demo and Examples Key Features Requirements Installation Logging Issues and Contributions API and Usage Columns column.hide

John Betancur 1.7k Dec 31, 2022