extend table and table cell support for cell merge, span, borders ... (#6)

* extend table and table cell support for cell merge, span, borders ...

* added tests for table cell borders and table cell width, renamed some variables, added jsdoc
This commit is contained in:
h4buli
2018-05-04 15:56:28 +02:00
committed by GitHub
parent 21bb8f9016
commit 753287d9d1
4 changed files with 402 additions and 0 deletions

View File

@ -1 +1,2 @@
export * from "./table";
export * from './table-cell';

View File

@ -0,0 +1,181 @@
import { expect } from "chai";
import { TableCellBorders, BorderStyle, TableCellWidth, WidthType } from "./table-cell";
import { Formatter } from "../../export/formatter";
describe("TableCellBorders", () => {
describe("#prepForXml", () => {
it("should not add empty borders element if there are no borders defined", () => {
const tb = new TableCellBorders();
const tree = new Formatter().format(tb);
expect(tree).to.deep.equal("");
});
});
describe("#addingBorders", () => {
it("should add top border", () => {
const tb = new TableCellBorders();
tb.addTopBorder(BorderStyle.DOTTED, 1, "FF00FF");
const tree = new Formatter().format(tb);
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:top": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "dotted",
},
},
],
},
],
});
});
it("should add start(left) border", () => {
const tb = new TableCellBorders();
tb.addStartBorder(BorderStyle.SINGLE, 2, "FF00FF");
const tree = new Formatter().format(tb);
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:start": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
},
],
},
],
});
});
it("should add bottom border", () => {
const tb = new TableCellBorders();
tb.addBottomBorder(BorderStyle.DOUBLE, 1, "FF00FF");
const tree = new Formatter().format(tb);
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:bottom": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "double",
},
},
],
},
],
});
});
it("should add end(right) border", () => {
const tb = new TableCellBorders();
tb.addEndBorder(BorderStyle.THICK, 3, "FF00FF");
const tree = new Formatter().format(tb);
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:end": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
},
],
},
],
});
});
it("should add multiple borders", () => {
const tb = new TableCellBorders();
tb.addTopBorder(BorderStyle.DOTTED, 1, "FF00FF");
tb.addEndBorder(BorderStyle.THICK, 3, "FF00FF");
tb.addBottomBorder(BorderStyle.DOUBLE, 1, "FF00FF");
tb.addStartBorder(BorderStyle.SINGLE, 2, "FF00FF");
const tree = new Formatter().format(tb);
expect(tree).to.deep.equal({
"w:tcBorders": [
{
"w:top": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "dotted",
},
},
],
},
{
"w:end": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 3,
"w:val": "thick",
},
},
],
},
{
"w:bottom": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 1,
"w:val": "double",
},
},
],
},
{
"w:start": [
{
_attr: {
"w:color": "FF00FF",
"w:sz": 2,
"w:val": "single",
},
},
],
},
],
});
});
});
});
describe("TableCellWidth", () => {
describe("#constructor", () => {
it("should create object", () => {
const tcWidth = new TableCellWidth(100, WidthType.DXA);
const tree = new Formatter().format(tcWidth);
expect(tree).to.deep.equal({
"w:tcW": [
{
"_attr": {
"w:type": "dxa",
"w:w": 100
}
}
]
});
});
});
});

View File

@ -0,0 +1,197 @@
import { XmlComponent, XmlAttributeComponent, IXmlableObject } from "file/xml-components";
export enum BorderStyle {
SINGLE = "single",
DASH_DOT_STROKED = "dashDotStroked",
DASHED = "dashed",
DASH_SMALL_GAP = "dashSmallGap",
DOT_DASH = "dotDash",
DOT_DOT_DASH = "dotDotDash",
DOTTED = "dotted",
DOUBLE = "double",
DOUBLE_WAVE = "doubleWave",
INSET = "inset",
NIL = "nil",
NONE = "none",
OUTSET = "outset",
THICK = "thick",
THICK_THIN_LARGE_GAP = "thickThinLargeGap",
THICK_THIN_MEDIUM_GAP = "thickThinMediumGap",
THICK_THIN_SMALL_GAP = "thickThinSmallGap",
THIN_THICK_LARGE_GAP = "thinThickLargeGap",
THIN_THICK_MEDIUM_GAP = "thinThickMediumGap",
THIN_THICK_SMALL_GAP = "thinThickSmallGap",
THIN_THICK_THIN_LARGE_GAP = "thinThickThinLargeGap",
THIN_THICK_THIN_MEDIUM_GAP = "thinThickThinMediumGap",
THIN_THICK_THIN_SMALL_GAP = "thinThickThinSmallGap",
THREE_D_EMBOSS = "threeDEmboss",
THREE_D_ENGRAVE = "threeDEngrave",
TRIPLE = "triple",
WAVE = "wave",
}
interface ICellBorder {
style: BorderStyle;
size: number;
color: string;
}
class CellBorderAttributes extends XmlAttributeComponent<ICellBorder> {
protected xmlKeys = { style: "w:val", size: "w:sz", color: "w:color" };
}
class BaseTableCellBorder extends XmlComponent {
setProperties(style: BorderStyle, size: number, color: string) {
let attrs = new CellBorderAttributes({
style: style,
size: size,
color: color,
});
this.root.push(attrs);
}
}
export class TableCellBorders extends XmlComponent {
constructor() {
super("w:tcBorders");
}
public prepForXml(): IXmlableObject {
return this.root.length > 0 ? super.prepForXml() : "";
}
addTopBorder(style: BorderStyle, size: number, color: string) {
const top = new BaseTableCellBorder("w:top");
top.setProperties(style, size, color);
this.root.push(top);
}
addStartBorder(style: BorderStyle, size: number, color: string) {
const start = new BaseTableCellBorder("w:start");
start.setProperties(style, size, color);
this.root.push(start);
}
addBottomBorder(style: BorderStyle, size: number, color: string) {
const bottom = new BaseTableCellBorder("w:bottom");
bottom.setProperties(style, size, color);
this.root.push(bottom);
}
addEndBorder(style: BorderStyle, size: number, color: string) {
const end = new BaseTableCellBorder("w:end");
end.setProperties(style, size, color);
this.root.push(end);
}
}
/**
* Attributes fot the GridSpan element.
*/
class GridSpanAttributes extends XmlAttributeComponent<{ val: number }> {
protected xmlKeys = { val: "w:val" };
}
/**
* GridSpan element. Should be used in a table cell. Pass the number of columns that this cell need to span.
*/
export class GridSpan extends XmlComponent {
constructor(value: number) {
super("w:gridSpan");
this.root.push(
new GridSpanAttributes({
val: value,
}),
);
}
}
/**
* Vertical merge types.
*/
export enum VMergeType {
/**
* Cell that is merged with upper one.
*/
CONTINUE = "continue",
/**
* Cell that is starting the vertical merge.
*/
RESTART = "restart",
}
class VMergeAttributes extends XmlAttributeComponent<{ val: VMergeType }> {
protected xmlKeys = { val: "w:val" };
}
/**
* Vertical merge element. Should be used in a table cell.
*/
export class VMerge extends XmlComponent {
constructor(value: VMergeType) {
super("w:vMerge");
this.root.push(
new VMergeAttributes({
val: value,
}),
);
}
}
export enum VerticalAlign {
BOTTOM = "bottom",
CENTER = "center",
TOP = "top",
}
class VAlignAttributes extends XmlAttributeComponent<{ val: VerticalAlign }> {
protected xmlKeys = { val: "w:val" };
}
/**
* Vertical align element.
*/
export class VAlign extends XmlComponent {
constructor(value: VerticalAlign) {
super("w:vAlign");
this.root.push(
new VAlignAttributes({
val: value,
}),
);
}
}
export enum WidthType {
/** Auto. */
AUTO = "auto",
/** Value is in twentieths of a point */
DXA = "dxa",
/** No (empty) value. */
NIL = "nil",
/** Value is in percentage. */
PERCENTAGE = "pct",
}
class TableCellWidthAttributes extends XmlAttributeComponent<{ type: WidthType; width: string | number }> {
protected xmlKeys = { width: "w:w", type: "w:type" };
}
/**
* Table cell width element.
*/
export class TableCellWidth extends XmlComponent {
constructor(value: string | number, type: WidthType) {
super("w:tcW");
this.root.push(
new TableCellWidthAttributes({
width: value,
type: type,
}),
);
}
}

View File

@ -2,6 +2,7 @@ import { IXmlableObject, XmlComponent } from "file/xml-components";
import { Paragraph } from "../paragraph";
import { TableGrid } from "./grid";
import { TableProperties, WidthTypes } from "./properties";
import { TableCellBorders, GridSpan, VMerge, VMergeType, VerticalAlign, VAlign, TableCellWidth, WidthType } from "file/table/table-cell";
export class Table extends XmlComponent {
private readonly properties: TableProperties;
@ -123,7 +124,29 @@ export class TableCell extends XmlComponent {
}
export class TableCellProperties extends XmlComponent {
private cellBorder: TableCellBorders;
constructor() {
super("w:tcPr");
this.cellBorder = new TableCellBorders();
this.root.push(this.cellBorder);
}
get borders() {
return this.cellBorder;
}
addGridSpan(cellSpan: number) {
this.root.push(new GridSpan(cellSpan));
}
addVerticalMerge(type: VMergeType) {
this.root.push(new VMerge(type));
}
setVerticalAlign(vAlignType: VerticalAlign) {
this.root.push(new VAlign(vAlignType));
}
setWidth(width: string | number, type: WidthType) {
this.root.push(new TableCellWidth(width, type));
}
}