Unfortunately, you cannot use quill-better-table with ngx-quill wrapper. ngx-quill is still based on quilljs v1. quill-better-table requires quilljs v2.0.0-dev.3. You can read about that in the Requirements section: here

I can share with you how I implemented simple paste and read table in my case. Its inspired by this article and created with custom block. And its not a correct way to add elements to quill. But we are using editor internally so we are sure that it is in safe hands.

  1. Create a new 'Block Embed' like this:
import Quill from 'quill';
const BlockEmbed = Quill.import('blots/block/embed');

    export class TableBlockEmbed extends BlockEmbed {

      static blotName = 'TableBlockEmbed';
      static tagName = 'table';

      static create(value) {
        const node = super.create();
        let valueToReturn = value;
        if (!value.includes('assignedTableId')) {
          const tableId = `assignedTableId-${Date.now()}`;
          valueToReturn = value
            .replace('#tableId', `#${tableId}`)
            .replace('table-layout: fixed;', '');
          node.setAttribute('id', tableId);
        } else {
          const existedId = valueToReturn.match(/#assignedTableId-(\d+)/i)[1];
          node.setAttribute('id', `assignedTableId-${existedId}`);
        }
        node.innerHTML = this.transformValue(valueToReturn);
        return node;
      }

      static transformValue(value) {
        let handleArr = value.split('\n');
        handleArr = handleArr.map(e => e.replace(/^[\s]+/, '')
          .replace(/[\s]+$/, ''));
        return handleArr.join('');
      }

      static value(node) {
        return node.innerHTML;
      }
    }
  1. Run registration of new embed block in the constructor of your component which uses ngx-quill:
constructor() {
    Quill.register(TableBlockEmbed, true);
  }
  1. add on editor Created this code below. (you can of course add/remove styles here you need. I added for example margin: 0 auto !important; because I want to force table to be always centered):
onEditorCreated(quill: Quill): void {
    quill.clipboard.addMatcher('TABLE', (node, delta) => {
      const Delta = Quill.import('delta');
      const tableTagStyles = node.getAttribute('style');
      return new Delta([
        {
          insert: {
            TableBlockEmbed:
              `<style>#tableId {${tableTagStyles} margin: 0 auto !important; }</style>` + delta.ops[0].insert.TableBlockEmbed
          }
        }
      ]);
    });
  }
  1. I added also some styles:
quill-view,
quill-editor{
  ::ng-deep {
    table {
      width: 100%; // if table has no width - then give it by default 100%
      max-width: 100% !important;
      box-sizing: border-box;
    }
  }
}

I know this solution is just workaround but until waiting for ngx-quill based on quill 2, I was able at least to give the feature of pasting tables inside the editor which looks quite nice.

Example:

table in office word:

table in ngx-quill:

table in excel:

table in ngx-quill:

Answer from Potwór z Lochness on Stack Overflow
🌐
GitHub
github.com › KillerCodeMonkey › ngx-quill › issues › 546
ngx-quill support table? · Issue #546 · KillerCodeMonkey/ngx-quill
August 7, 2019 - ngx-quill works fine; very good. but i have a problem with table. When i set table: true in the imports; an error come: ... QuillModule.forRoot({ modules: { table: true, //without table: true it works fine. } .... "quill Cannot import mo...
Author   nosz
Top answer
1 of 1
2

Unfortunately, you cannot use quill-better-table with ngx-quill wrapper. ngx-quill is still based on quilljs v1. quill-better-table requires quilljs v2.0.0-dev.3. You can read about that in the Requirements section: here

I can share with you how I implemented simple paste and read table in my case. Its inspired by this article and created with custom block. And its not a correct way to add elements to quill. But we are using editor internally so we are sure that it is in safe hands.

  1. Create a new 'Block Embed' like this:
import Quill from 'quill';
const BlockEmbed = Quill.import('blots/block/embed');

    export class TableBlockEmbed extends BlockEmbed {

      static blotName = 'TableBlockEmbed';
      static tagName = 'table';

      static create(value) {
        const node = super.create();
        let valueToReturn = value;
        if (!value.includes('assignedTableId')) {
          const tableId = `assignedTableId-${Date.now()}`;
          valueToReturn = value
            .replace('#tableId', `#${tableId}`)
            .replace('table-layout: fixed;', '');
          node.setAttribute('id', tableId);
        } else {
          const existedId = valueToReturn.match(/#assignedTableId-(\d+)/i)[1];
          node.setAttribute('id', `assignedTableId-${existedId}`);
        }
        node.innerHTML = this.transformValue(valueToReturn);
        return node;
      }

      static transformValue(value) {
        let handleArr = value.split('\n');
        handleArr = handleArr.map(e => e.replace(/^[\s]+/, '')
          .replace(/[\s]+$/, ''));
        return handleArr.join('');
      }

      static value(node) {
        return node.innerHTML;
      }
    }
  1. Run registration of new embed block in the constructor of your component which uses ngx-quill:
constructor() {
    Quill.register(TableBlockEmbed, true);
  }
  1. add on editor Created this code below. (you can of course add/remove styles here you need. I added for example margin: 0 auto !important; because I want to force table to be always centered):
onEditorCreated(quill: Quill): void {
    quill.clipboard.addMatcher('TABLE', (node, delta) => {
      const Delta = Quill.import('delta');
      const tableTagStyles = node.getAttribute('style');
      return new Delta([
        {
          insert: {
            TableBlockEmbed:
              `<style>#tableId {${tableTagStyles} margin: 0 auto !important; }</style>` + delta.ops[0].insert.TableBlockEmbed
          }
        }
      ]);
    });
  }
  1. I added also some styles:
quill-view,
quill-editor{
  ::ng-deep {
    table {
      width: 100%; // if table has no width - then give it by default 100%
      max-width: 100% !important;
      box-sizing: border-box;
    }
  }
}

I know this solution is just workaround but until waiting for ngx-quill based on quill 2, I was able at least to give the feature of pasting tables inside the editor which looks quite nice.

Example:

table in office word:

table in ngx-quill:

table in excel:

table in ngx-quill:

Discussions

Quill table
Can you please provide some code. More on reddit.com
🌐 r/Angular2
4
1
August 27, 2019
How do I fix this error I get whenever I try to register quill-better-table with my quill editor component in Angular 8? - Stack Overflow
> npm install quill@dev quill-better-table ngx-quill More on stackoverflow.com
🌐 stackoverflow.com
How to bind data to the editor
I recently updated ngx-quill and now I cannot bind the data that is coming from the db at the start of the application. But before that I could bind the data with the old version of ngx-quill. For ... More on github.com
🌐 github.com
24
May 29, 2018
Table in ngx-quill
Is this package support table? If yes, how can I use it? More on github.com
🌐 github.com
13
September 27, 2019
🌐
npm
npmjs.com › package › ngx-quill
ngx-quill - npm
Angular components for the easy use of the QuillJS richt text editor.. Latest version: 30.0.1, last published: 3 months ago. Start using ngx-quill in your project by running `npm i ngx-quill`. There are 161 other projects in the npm registry using ngx-quill.
      » npm install ngx-quill
    
Published   Dec 03, 2025
Version   30.0.1
Author   Bengt Weiße
🌐
StackBlitz
stackblitz.com › edit › stackblitz-starters-13iu4c7q
ngx-quill & quill-table-up Test - StackBlitz
An angular-cli project based on @angular/animations, @angular/common, @angular/compiler, @angular/core, @angular/forms, @angular/platform-browser, @angular/platform-browser-dynamic, @angular/router, core-js, rxjs, tslib and zone.js
🌐
npm
npmjs.com › package › ngx-quill-v2
ngx-quill-v2 - npm
May 23, 2019 - An angular (>= v2) component for the easy use of the QuillJS rich text editor for v2 release. The v2 release is a dev preview which has new experimental features like table support..
      » npm install ngx-quill-v2
    
Published   May 23, 2019
Version   0.0.1
Author   Arghya Saha
Top answer
1 of 1
4

I am assuming you already have angular project configured. If not, you can use this command to create a new angular project npx @angular/cli@next new editor

  1. Use yarn/npm to add quill.js packages to angular project.
> npm install quill@dev quill-better-table ngx-quill

After installation, your project's package.json should have following dependencies

  "dependencies": {
    "ngx-quill": "^7.3.9",
    "quill": "^2.0.0-dev.3 ",
    "quill-better-table": "^1.2.4",
   }
  1. Import quill.js snow theme(or any other theme). In file src/styles.scss, add this snippet
@import "~quill/dist/quill.snow.css";
  1. Import and configure Quill Module (File: src/app/app.module.ts)
import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { QuillConfig, QuillModule } from "ngx-quill";
import * as Quill from "quill";
import QuillBetterTable from "quill-better-table";
import { AppComponent } from "./app.component";

Quill.register(
  {
    "modules/better-table": QuillBetterTable
  },
  true
);

const quillConfig: QuillConfig = {
  modules: {
    table: false, // disable table module
    "better-table": {
      operationMenu: {
        items: {
          unmergeCells: {
            text: "Another unmerge cells name"
          }
        },
        color: {
          colors: ["#fff", "red", "rgb(0, 0, 0)"], // colors in operationMenu
          text: "Background Colors" // subtitle
        }
      }
    },
    keyboard: {
      bindings: QuillBetterTable.keyboardBindings
    }
  }
};
@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, QuillModule.forRoot(quillConfig)],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}
  1. Add HTML tag. (File: src/app/app.component.html)
<quill-editor (onEditorCreated)="editorCreated($event)"></quill-editor>
  1. Insert table in editor (File: src/app/app.component.ts)
import { ChangeDetectionStrategy, Component } from "@angular/core";

interface Quill {
  getModule(moduleName: string);
}

interface BetterTableModule {
  insertTable(rows: number, columns: number): void;
}

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
  public quill: Quill;

  private get tableModule(): BetterTableModule {
    return this.quill.getModule("better-table");
  }

  public editorCreated(event: Quill): void {
    this.quill = event;
    // Example on how to add new table to editor
    this.addNewtable();
  }

  private addNewtable(): void {
    this.tableModule.insertTable(3, 3);
  }
}

This is how the output looks like at the end:

Find elsewhere
🌐
CodePen
codepen.io › soccerloway › pen › WWJowj
Quill-better-table Demo
Quill.register({ 'modules/better-table': quillBetterTable }, true) window.onload = () => { const quill = new Quill('#editor', { theme: 'snow', modules: { table: false, 'better-table': { operationMenu: { items: { unmergeCells: { text: 'Another unmerge cells name' } }, color: { colors: ['green', 'red', 'yellow', 'blue', 'white'], text: 'Background Colors:' } } }, // keyboard: { // bindings: quillBetterTable.keyboardBindings // } } }) let tableModule = quill.getModule('better-table') document.body.querySelector('#insert-table') .onclick = () => { tableModule.insertTable(3, 3) } document.body.quer
🌐
npm Trends
npmtrends.com › ngx-quill-vs-ngx-quill-editor-vs-quill-better-table-vs-quill-table
ngx-quill vs ngx-quill-editor vs quill-better-table vs quill-table | npm trends
Comparing trends for ngx-quill 28.0.1 which has 264,182 weekly downloads and 1,836 GitHub stars vs. ngx-quill-editor 2.2.2 which has 708 weekly downloads and 231 GitHub stars vs. quill-better-table 1.2.10 which has 18,342 weekly downloads and 340 GitHub stars vs. quill-table 1.0.0 which has ...
🌐
IssueHunt
oss.issuehunt.io › r › KillerCodeMonkey › ngx-quill-example › issues › 217
Whenever I try to integrate quill-better-table with ngx- ...
KillerCodeMonkey/ngx-quill-example · The issue has been closed · Alec-Aldrine-Lakra posted onGitHub · Update comments · Fund this Issue · $0.00 · Funded · Pull requests · Submit a pull request · AboutMission · SpectrumEmbed · FAQTerms of usePrivacy policyCode of conductCredits ·
🌐
StackBlitz
stackblitz.com › edit › ngx-quill
Ngx Quill - StackBlitz
Starter project for Angular apps that exports to the Angular CLI
🌐
GitHub
github.com › KillerCodeMonkey › ngx-quill › issues › 258
How to bind data to the editor · Issue #258 · KillerCodeMonkey/ngx-quill
May 29, 2018 - I recently updated ngx-quill and now I cannot bind the data that is coming from the db at the start of the application. But before that I could bind the data with the old version of ngx-quill. For binding the data I am using [(ngModel)]....
Author   RaveenPromodya
🌐
StackBlitz
stackblitz.com › edit › ngx-quill-angular
Ngx Quill Angular - StackBlitz
Starter project for Angular apps that exports to the Angular CLI
🌐
GitHub
github.com › KillerCodeMonkey › ngx-quill › issues › 544
Table in ngx-quill · Issue #544 · KillerCodeMonkey/ngx-quill
September 27, 2019 - Is this package support table? If yes, how can I use it?
Author   Exee03
🌐
GitHub
github.com › KillerCodeMonkey › ngx-quill
GitHub - KillerCodeMonkey/ngx-quill: Angular (>=2) components for the Quill Rich Text Editor · GitHub
Just create a quill editor without a toolbar and in readonly mode. With some simple css lines you can remove the default border around the content. As a helper ngx-quill provides a component where you can pass many options of the quill-editor like modules, format, formats, customOptions, but renders only the content as readonly and without a toolbar.
Starred by 1.8K users
Forked by 273 users
Languages   TypeScript 96.3% | JavaScript 3.7%
Top answer
1 of 2
9

I managed to do this after some time thanks to this fiddle and a bit of playing around.See here.

component.html:

<quill-editor [(ngModel)]="editorContent"
              [options]="editorOptions" 
              (ready)="onEditorCreated($event)"
              (change)="onContentChanged($event)"></quill-editor>

component.ts:

public editor;
  public editorContent = '<h3>Type Something...</h3>';
  public editorOptions = {
     theme: 'snow',
    modules: {
        toolbar: {
        container:
        [
            [{ 'placeholder': ['[GuestName]', '[HotelName]'] }], // my custom dropdown
            ['bold', 'italic', 'underline', 'strike'],        // toggled buttons
            ['blockquote', 'code-block'],

            [{ 'header': 1 }, { 'header': 2 }],               // custom button values
            [{ 'list': 'ordered' }, { 'list': 'bullet' }],
            [{ 'script': 'sub' }, { 'script': 'super' }],      // superscript/subscript
            [{ 'indent': '-1' }, { 'indent': '+1' }],          // outdent/indent
            [{ 'direction': 'rtl' }],                         // text direction

            [{ 'size': ['small', false, 'large', 'huge'] }],  // custom dropdown
            [{ 'header': [1, 2, 3, 4, 5, 6, false] }],

            [{ 'color': [] }, { 'background': [] }],          // dropdown with defaults from theme
            [{ 'font': [] }],
            [{ 'align': [] }],

            ['clean']                                    // remove formatting button

        ],
        handlers: {
            "placeholder": function (value) { 
                if (value) {
                    const cursorPosition = this.quill.getSelection().index;
                    this.quill.insertText(cursorPosition, value);
                    this.quill.setSelection(cursorPosition + value.length);
                }
            }
        }
      }
    }
  };

  constructor(private elem: ElementRef) {

  }

  onEditorCreated(quill) {
    this.editor = quill;
    console.log('quill is ready! this is current quill instance object', quill);
  }

  onContentChanged({ quill, html, text }) {
    console.log('quill content is changed!', quill, html, text);
  }
  ngAfterViewInit() {
    // Update your dropdown with labels
    let placeholderPickerItems = this.elem.nativeElement.querySelectorAll('.ql-placeholder .ql-picker-item');
    placeholderPickerItems.forEach(item => item.textContent = item.dataset.value);
    this.elem.nativeElement.querySelector('.ql-placeholder .ql-picker-label').innerHTML
      = 'Insert Data Field &nbsp; &nbsp; &nbsp;' + this.elem.nativeElement.querySelector('.ql-placeholder .ql-picker-label').innerHTML;
  }

Output:

Screenshot of Output

Hope this helps!

2 of 2
4

For more recent angular 8 projects, the configuration options are here: https://github.com/KillerCodeMonkey/ngx-quill#config

And this can be done in html via

<quill-editor [modules]="editorOptions" ></quill-editor>

and the js class

export class Component {
  editorOptions= {
      toolbar: [[{ 'list': 'bullet' }]]
  };
}
🌐
Stack Overflow
stackoverflow.com › questions › tagged › ngx-quill
Newest 'ngx-quill' Questions - Stack Overflow
I'm working on a rich text with ngx-quill and quill in angular 13 and trying to add a undo and redo functionality import Quill from 'quill'; import { QuillEditorComponent } from 'ngx-quill'; import '...
🌐
UNPKG
unpkg.com › browse › ngx-quill@4.6.3 › README.md
ngx-quill
Donations to the project are always ... initialisation, e.g. rtl direction - [Ionic v3 Demo](https://github.com/KillerCodeMonkey/ngx-quill-ionic-v3) ## Compatibility to Angular Versions <table> <thead> <tr> <th>Angular</th> <th>ngx-quill</th> </tr> </thead> <tbody> <tr> <td> v4 </td> ...
🌐
Npm
npm.io › package › ngx-quill-v2
Ngx-quill-v2 NPM | npm.io
November 3, 2019 - I have kept the link of all the existing examples from ngx-quill. In addition to the examples I have added a new example using table support.