Merge pull request #1168 from askoufis/unequal-columns
Extend `Columns` API to allow specifying individual column widths/spacing
This commit is contained in:
31
demo/69-different-width-columns.ts
Normal file
31
demo/69-different-width-columns.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Sections with multiple columns
|
||||||
|
// Import from 'docx' rather than '../build' if you install from npm
|
||||||
|
import * as fs from "fs";
|
||||||
|
import { Column, Document, Packer, Paragraph } from "../build";
|
||||||
|
|
||||||
|
const doc = new Document({
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
properties: {
|
||||||
|
column: {
|
||||||
|
count: 2,
|
||||||
|
space: 720,
|
||||||
|
equalWidth: false,
|
||||||
|
children: [new Column({ width: 2880, space: 720 }), new Column({ width: 5760 })],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
new Paragraph(
|
||||||
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||||
|
),
|
||||||
|
new Paragraph(
|
||||||
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Packer.toBuffer(doc).then((buffer) => {
|
||||||
|
fs.writeFileSync("My Document.docx", buffer);
|
||||||
|
});
|
@ -0,0 +1,26 @@
|
|||||||
|
import { twipsMeasureValue } from "file/values";
|
||||||
|
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||||
|
|
||||||
|
export interface IColumnAttributes {
|
||||||
|
readonly width: number | string;
|
||||||
|
readonly space?: number | string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ColumnAttributes extends XmlAttributeComponent<IColumnAttributes> {
|
||||||
|
protected readonly xmlKeys = {
|
||||||
|
width: "w:w",
|
||||||
|
space: "w:space",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Column extends XmlComponent {
|
||||||
|
constructor({ width, space }: IColumnAttributes) {
|
||||||
|
super("w:col");
|
||||||
|
this.root.push(
|
||||||
|
new ColumnAttributes({
|
||||||
|
width: twipsMeasureValue(width),
|
||||||
|
space: space === undefined ? undefined : twipsMeasureValue(space),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
import { expect } from "chai";
|
||||||
|
|
||||||
|
import { Formatter } from "export/formatter";
|
||||||
|
|
||||||
|
import { Column, Columns } from ".";
|
||||||
|
|
||||||
|
describe("Columns", () => {
|
||||||
|
describe("#constructor()", () => {
|
||||||
|
it("should create columns of equal width if equalWidth is true", () => {
|
||||||
|
const columns = new Columns({ count: 3, space: 720 });
|
||||||
|
const tree = new Formatter().format(columns);
|
||||||
|
|
||||||
|
expect(tree["w:cols"]).to.deep.equal({ _attr: { "w:num": 3, "w:space": 720 } });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should ignore individual column attributes if equalWidth is true", () => {
|
||||||
|
const unequalColumns = [new Column({ width: 1000, space: 400 }), new Column({ width: 2000 })];
|
||||||
|
const columns = new Columns({ count: 3, space: 720, equalWidth: true, children: unequalColumns });
|
||||||
|
const tree = new Formatter().format(columns);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({ "w:cols": { _attr: { "w:num": 3, "w:space": 720, "w:equalWidth": true } } });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should have column children if equalWidth is false and individual columns are provided", () => {
|
||||||
|
const unequalColumns = [new Column({ width: 1000, space: 400 }), new Column({ width: 2000 })];
|
||||||
|
const columns = new Columns({ count: 3, space: 720, equalWidth: false, children: unequalColumns });
|
||||||
|
const tree = new Formatter().format(columns);
|
||||||
|
|
||||||
|
expect(tree).to.deep.equal({
|
||||||
|
"w:cols": [
|
||||||
|
{ _attr: { "w:num": 3, "w:space": 720, "w:equalWidth": false } },
|
||||||
|
{ "w:col": { _attr: { "w:space": 400, "w:w": 1000 } } },
|
||||||
|
{ "w:col": { _attr: { "w:w": 2000 } } },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,5 +1,6 @@
|
|||||||
import { decimalNumber, twipsMeasureValue } from "file/values";
|
import { decimalNumber, twipsMeasureValue } from "file/values";
|
||||||
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
|
||||||
|
import { Column } from "./column";
|
||||||
|
|
||||||
// <xsd:complexType name="CT_Columns">
|
// <xsd:complexType name="CT_Columns">
|
||||||
// <xsd:sequence minOccurs="0">
|
// <xsd:sequence minOccurs="0">
|
||||||
@ -15,6 +16,7 @@ export interface IColumnsAttributes {
|
|||||||
readonly count?: number;
|
readonly count?: number;
|
||||||
readonly separate?: boolean;
|
readonly separate?: boolean;
|
||||||
readonly equalWidth?: boolean;
|
readonly equalWidth?: boolean;
|
||||||
|
readonly children?: Column[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes> {
|
export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes> {
|
||||||
@ -27,7 +29,7 @@ export class ColumnsAttributes extends XmlAttributeComponent<IColumnsAttributes>
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Columns extends XmlComponent {
|
export class Columns extends XmlComponent {
|
||||||
constructor({ space, count, separate, equalWidth }: IColumnsAttributes) {
|
constructor({ space, count, separate, equalWidth, children }: IColumnsAttributes) {
|
||||||
super("w:cols");
|
super("w:cols");
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new ColumnsAttributes({
|
new ColumnsAttributes({
|
||||||
@ -37,5 +39,9 @@ export class Columns extends XmlComponent {
|
|||||||
equalWidth,
|
equalWidth,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!equalWidth && children) {
|
||||||
|
children.forEach((column) => this.addChildElement(column));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
export * from "./column";
|
||||||
export * from "./columns";
|
export * from "./columns";
|
||||||
export * from "./doc-grid";
|
export * from "./doc-grid";
|
||||||
// export * from "./header-reference";
|
// export * from "./header-reference";
|
||||||
|
@ -215,7 +215,7 @@ export class ImportDotx {
|
|||||||
}
|
}
|
||||||
const headers = headersXmlArray.map((item) => {
|
const headers = headersXmlArray.map((item) => {
|
||||||
if (item._attributes === undefined) {
|
if (item._attributes === undefined) {
|
||||||
throw Error("header referecne element has no attributes");
|
throw Error("header reference element has no attributes");
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: item._attributes["w:type"] as HeaderFooterReferenceType,
|
type: item._attributes["w:type"] as HeaderFooterReferenceType,
|
||||||
@ -235,7 +235,7 @@ export class ImportDotx {
|
|||||||
|
|
||||||
const footers = footersXmlArray.map((item) => {
|
const footers = footersXmlArray.map((item) => {
|
||||||
if (item._attributes === undefined) {
|
if (item._attributes === undefined) {
|
||||||
throw Error("footer referecne element has no attributes");
|
throw Error("footer reference element has no attributes");
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: item._attributes["w:type"] as HeaderFooterReferenceType,
|
type: item._attributes["w:type"] as HeaderFooterReferenceType,
|
||||||
|
Reference in New Issue
Block a user