Handsontable example

HTML

<script src="https://cdn.jsdelivr.net/npm/handsontable@15.3/dist/handsontable.full.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable@15.3/styles/handsontable.min.css" /> 
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable@15.3/styles/ht-theme-main.css" /> 
<link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/handsontable@15.3/styles/ht-theme-horizon.css" /> 
<script src="https://handsontable.com/docs/scripts/fixer.js"></script>

<div id="example1" class="hot ht-theme-main " ></div>

Babel + JSX

import Handsontable from 'handsontable';
import 'handsontable/styles/handsontable.css';
import 'handsontable/styles/ht-theme-main.css';

const data = new Array(10) 
  .fill(null)
  .map((_, row) =>
    new Array(5)
      .fill(null)
      .map((_, column) => `${row}, ${column}`)
  );

const container = document.querySelector('#example1');

new Handsontable(container, {
  data,
  height: 320,
  colWidths: 50,
  rowHeaders: true,
  colHeaders: true,
  contextMenu: true,
  autoWrapRow: true,
  autoWrapCol: true,
  navigableHeaders: true,
  licenseKey: 'non-commercial-and-evaluation',
  beforeCopy: function(data) {
    const isHeaderSelected = this.getSelectedLast()[0] < 0;

    if(isHeaderSelected){
        data.length = 0;
        
        const selection = this.getSelectedLast();
        const startCol = selection[1];
        const endCol = selection[3];
        
        const headers = [];
        for(let col = startCol; col <= endCol; col++) {
            const headerName = this.getColHeader(col);
            headers.push(headerName);
        }
        data.push(headers);
        
        const rowCount = this.countRows();
        for(let row = 0; row < rowCount; row++) {
            const rowData = [];
            for(let col = startCol; col <= endCol; col++) {
                const cellValue = this.getDataAtCell(row, col);
                rowData.push(cellValue);
            }
            data.push(rowData);
        }
    }
    // if isHeaderSelected is false we leave it as it is
}
});