Merge pull request #181 from dolanmiu/feat/float-table

Created float positioning for tables
This commit is contained in:
Dolan
2018-10-23 21:40:33 +01:00
committed by GitHub
7 changed files with 269 additions and 0 deletions

32
demo/demo34.ts Normal file
View File

@ -0,0 +1,32 @@
// Example of how you would create a table with float positions
// Import from 'docx' rather than '../build' if you install from npm
import * as fs from "fs";
import {
Document,
Packer,
Paragraph,
RelativeHorizontalPosition,
RelativeVerticalPosition,
TableAnchorType,
WidthType,
} from "../build";
const doc = new Document();
const table = doc.createTable(2, 2).float({
horizontalAnchor: TableAnchorType.MARGIN,
verticalAnchor: TableAnchorType.MARGIN,
relativeHorizontalPosition: RelativeHorizontalPosition.RIGHT,
relativeVerticalPosition: RelativeVerticalPosition.BOTTOM,
});
table.setFixedWidthLayout();
table.setWidth(WidthType.DXA, 4535);
table.getCell(0, 0).addContent(new Paragraph("Hello"));
table.getRow(0).mergeCells(0, 1);
const packer = new Packer();
packer.toBuffer(doc).then((buffer) => {
fs.writeFileSync("My Document.docx", buffer);
});

View File

@ -1,2 +1,3 @@
export * from "./table"; export * from "./table";
export * from "./table-cell"; export * from "./table-cell";
export * from "./table-float-properties";

View File

@ -1,6 +1,7 @@
import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { WidthType } from "./table-cell"; import { WidthType } from "./table-cell";
import { TableCellMargin } from "./table-cell-margin"; import { TableCellMargin } from "./table-cell-margin";
import { TableFloatProperties } from "./table-float-properties";
export class TableProperties extends XmlComponent { export class TableProperties extends XmlComponent {
private readonly cellMargin: TableCellMargin; private readonly cellMargin: TableCellMargin;
@ -30,6 +31,11 @@ export class TableProperties extends XmlComponent {
public get CellMargin(): TableCellMargin { public get CellMargin(): TableCellMargin {
return this.cellMargin; return this.cellMargin;
} }
public setTableFloatProperties(tableFloatProperties: TableFloatProperties): TableProperties {
this.root.push(tableFloatProperties);
return this;
}
} }
interface ITableWidth { interface ITableWidth {

View File

@ -0,0 +1,44 @@
import { expect } from "chai";
import { Formatter } from "../../export/formatter";
import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType, TableFloatProperties } from "./table-float-properties";
describe("Table Float Properties", () => {
describe("#constructor", () => {
it("should construct a TableFloatProperties with all options", () => {
const tfp = new TableFloatProperties({
horizontalAnchor: TableAnchorType.MARGIN,
verticalAnchor: TableAnchorType.PAGE,
absoluteHorizontalPosition: 10,
relativeHorizontalPosition: RelativeHorizontalPosition.CENTER,
absoluteVerticalPosition: 20,
relativeVerticalPosition: RelativeVerticalPosition.BOTTOM,
bottomFromText: 30,
topFromText: 40,
leftFromText: 50,
rightFromText: 60,
});
const tree = new Formatter().format(tfp);
expect(tree).to.be.deep.equal(DEFAULT_TFP);
});
});
});
const DEFAULT_TFP = {
"w:tblpPr": [
{
_attr: {
"w:horzAnchor": "margin",
"w:vertAnchor": "page",
"w:tblpX": 10,
"w:tblpXSpec": "center",
"w:tblpY": 20,
"w:tblpYSpec": "bottom",
"w:bottomFromText": 30,
"w:topFromText": 40,
"w:leftFromText": 50,
"w:rightFromText": 60,
},
},
],
};

View File

@ -0,0 +1,134 @@
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
export enum TableAnchorType {
MARGIN = "margin",
PAGE = "page",
TEXT = "text",
}
export enum RelativeHorizontalPosition {
CENTER = "center",
INSIDE = "inside",
LEFT = "left",
OUTSIDE = "outside",
RIGHT = "right",
}
export enum RelativeVerticalPosition {
CENTER = "center",
INSIDE = "inside",
BOTTOM = "bottom",
OUTSIDE = "outside",
INLINE = "inline",
TOP = "top",
}
export interface ITableFloatOptions {
/**
* Specifies the horizontal anchor or the base object from which the horizontal positioning in the
* tblpX or tblpXSpec attribute should be determined.
* margin - relative to the vertical edge of the text margin before any text runs (left edge for left-to-right paragraphs)
* page - relative to the vertical edge of the page before any text runs (left edge for left-to-right paragraphs)
* text - relative to the vertical edge of the text margin for the column in which the anchor paragraph is located
* If omitted, the value is assumed to be page.
*/
horizontalAnchor?: TableAnchorType;
/**
* Specifies an absolute horizontal position for the table, relative to the horizontalAnchor.
* The value is in twentieths of a point. Note that the value can be negative, in which case the
* table is positioned before the anchor object in the direction of horizontal text flow.
* If relativeHorizontalPosition is also specified, then the absoluteHorizontalPosition attribute is ignored.
* If the attribute is omitted, the value is assumed to be zero.
*/
absoluteHorizontalPosition?: number;
/**
* Specifies a relative horizontal position for the table, relative to the horizontalAnchor attribute.
* This will supersede the absoluteHorizontalPosition attribute.
* Possible values are:
* center - the table should be horizontally centered with respect to the anchor
* inside - the table should be inside of the anchor
* left - the table should be left aligned with respect to the anchor
* outside - the table should be outside of the anchor
* right - the table should be right aligned with respect to the anchor
*/
relativeHorizontalPosition?: RelativeHorizontalPosition;
/**
* Specifies the vertical anchor or the base object from which the vertical positioning
* in the absoluteVerticalPosition attribute should be determined. Possible values are:
* margin - relative to the horizontal edge of the text margin before any text runs (top edge for top-to-bottom paragraphs)
* page - relative to the horizontal edge of the page before any text runs (top edge for top-to-bottom paragraphs)
* text - relative to the horizontal edge of the text margin for the column in which the anchor paragraph is located
* If omitted, the value is assumed to be page.
*/
verticalAnchor?: TableAnchorType;
/**
* Specifies an absolute vertical position for the table, relative to the verticalAnchor anchor.
* The value is in twentieths of a point. Note that the value can be negative, in which case the table is
* positioned before the anchor object in the direction of vertical text flow.
* If relativeVerticalPosition is also specified, then the absoluteVerticalPosition attribute is ignored.
* If the attribute is omitted, the value is assumed to be zero.
*/
absoluteVerticalPosition?: number;
/**
* Specifies a relative vertical position for the table, relative to the verticalAnchor attribute.
* This will supersede the absoluteVerticalPosition attribute. Possible values are:
* center - the table should be vertically centered with respect to the anchor
* inside - the table should be vertically aligned to the edge of the anchor and inside the anchor
* bottom - the table should be vertically aligned to the bottom edge of the anchor
* outside - the table should be vertically aligned to the edge of the anchor and outside the anchor
* inline - the table should be vertically aligned in line with the surrounding text (so as to not allow any text wrapping around it)
* top - the table should be vertically aligned to the top edge of the anchor
*/
relativeVerticalPosition?: RelativeVerticalPosition;
/**
* Specifies the minimun distance to be maintained between the table and the top of text in the paragraph
* below the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
*/
bottomFromText?: number;
/**
* Specifies the minimun distance to be maintained between the table and the bottom edge of text in the paragraph
* above the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
*/
topFromText?: number;
/**
* Specifies the minimun distance to be maintained between the table and the edge of text in the paragraph
* to the left of the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
*/
leftFromText?: number;
/**
* Specifies the minimun distance to be maintained between the table and the edge of text in the paragraph
* to the right of the table. The value is in twentieths of a point. If omitted, the value is assumed to be zero.
*/
rightFromText?: number;
}
export class TableFloatOptionsAttributes extends XmlAttributeComponent<ITableFloatOptions> {
protected xmlKeys = {
horizontalAnchor: "w:horzAnchor",
verticalAnchor: "w:vertAnchor",
absoluteHorizontalPosition: "w:tblpX",
relativeHorizontalPosition: "w:tblpXSpec",
absoluteVerticalPosition: "w:tblpY",
relativeVerticalPosition: "w:tblpYSpec",
bottomFromText: "w:bottomFromText",
topFromText: "w:topFromText",
leftFromText: "w:leftFromText",
rightFromText: "w:rightFromText",
};
}
export class TableFloatProperties extends XmlComponent {
constructor(options: ITableFloatOptions) {
super("w:tblpPr");
this.root.push(new TableFloatOptionsAttributes(options));
}
}

View File

@ -5,6 +5,7 @@ import { Formatter } from "../../export/formatter";
import { Paragraph } from "../paragraph"; import { Paragraph } from "../paragraph";
import { Table } from "./"; import { Table } from "./";
import { WidthType } from "./table-cell"; import { WidthType } from "./table-cell";
import { RelativeHorizontalPosition, RelativeVerticalPosition, TableAnchorType } from "./table-float-properties";
const DEFAULT_TABLE_PROPERTIES = { const DEFAULT_TABLE_PROPERTIES = {
"w:tblBorders": [ "w:tblBorders": [
@ -294,4 +295,49 @@ describe("Table", () => {
}); });
}); });
}); });
describe("#float", () => {
it("sets the table float properties", () => {
const table = new Table(1, 1).float({
horizontalAnchor: TableAnchorType.MARGIN,
verticalAnchor: TableAnchorType.PAGE,
absoluteHorizontalPosition: 10,
relativeHorizontalPosition: RelativeHorizontalPosition.CENTER,
absoluteVerticalPosition: 20,
relativeVerticalPosition: RelativeVerticalPosition.BOTTOM,
bottomFromText: 30,
topFromText: 40,
leftFromText: 50,
rightFromText: 60,
});
const tree = new Formatter().format(table);
expect(tree)
.to.have.property("w:tbl")
.which.is.an("array")
.with.has.length.at.least(1);
expect(tree["w:tbl"][0]).to.deep.equal({
"w:tblPr": [
DEFAULT_TABLE_PROPERTIES,
{
"w:tblpPr": [
{
_attr: {
"w:horzAnchor": "margin",
"w:vertAnchor": "page",
"w:tblpX": 10,
"w:tblpXSpec": "center",
"w:tblpY": 20,
"w:tblpYSpec": "bottom",
"w:bottomFromText": 30,
"w:topFromText": 40,
"w:leftFromText": 50,
"w:rightFromText": 60,
},
},
],
},
],
});
});
});
}); });

View File

@ -14,6 +14,7 @@ import { IXmlableObject, XmlComponent } from "file/xml-components";
import { Paragraph } from "../paragraph"; import { Paragraph } from "../paragraph";
import { TableGrid } from "./grid"; import { TableGrid } from "./grid";
import { TableProperties } from "./properties"; import { TableProperties } from "./properties";
import { ITableFloatOptions, TableFloatProperties } from "./table-float-properties";
export class Table extends XmlComponent { export class Table extends XmlComponent {
private readonly properties: TableProperties; private readonly properties: TableProperties;
@ -84,6 +85,11 @@ export class Table extends XmlComponent {
return this; return this;
} }
public float(tableFloatProperties: ITableFloatOptions): Table {
this.properties.setTableFloatProperties(new TableFloatProperties(tableFloatProperties));
return this;
}
public get Properties(): TableProperties { public get Properties(): TableProperties {
return this.properties; return this.properties;
} }