Background color for document

This commit is contained in:
Dolan
2020-10-27 01:54:40 +00:00
parent 214afab711
commit ed52ef358b
14 changed files with 203 additions and 14 deletions

View File

@ -0,0 +1,33 @@
// Change background colour of whole document
// Import from 'docx' rather than '../build' if you install from npm
import * as fs from "fs";
import { Document, Packer, Paragraph, TextRun } from "../build";
const doc = new Document({
background: {
color: "C45911",
},
});
doc.addSection({
properties: {},
children: [
new Paragraph({
children: [
new TextRun("Hello World"),
new TextRun({
text: "Foo Bar",
bold: true,
}),
new TextRun({
text: "\tGithub is the best",
bold: true,
}),
],
}),
],
});
Packer.toBuffer(doc).then((buffer) => {
fs.writeFileSync("My Document.docx", buffer);
});

View File

@ -30,6 +30,24 @@ const doc = new docx.Document({
* keywords * keywords
* lastModifiedBy * lastModifiedBy
* revision * revision
* externalStyles
* styles
* numbering
* footnotes
* hyperlinks
* background
### Change background color of Document
Set the hax value in the document like so:
```ts
const doc = new docx.Document({
background: {
color: "C45911",
},
});
```
You can mix and match whatever properties you want, or provide no properties. You can mix and match whatever properties you want, or provide no properties.

View File

@ -1,4 +1,5 @@
import { XmlComponent } from "file/xml-components"; import { XmlComponent } from "file/xml-components";
import { IDocumentBackgroundOptions } from "../document";
import { DocumentAttributes } from "../document/document-attributes"; import { DocumentAttributes } from "../document/document-attributes";
import { INumberingOptions } from "../numbering"; import { INumberingOptions } from "../numbering";
@ -32,6 +33,7 @@ export interface IPropertiesOptions {
readonly hyperlinks?: { readonly hyperlinks?: {
readonly [key: string]: IInternalHyperlinkDefinition | IExternalHyperlinkDefinition; readonly [key: string]: IInternalHyperlinkDefinition | IExternalHyperlinkDefinition;
}; };
readonly background?: IDocumentBackgroundOptions;
} }
export class CoreProperties extends XmlComponent { export class CoreProperties extends XmlComponent {

View File

@ -0,0 +1,53 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { DocumentBackground } from "./document-background";
describe("DocumentBackground", () => {
describe("#constructor()", () => {
it("should create a DocumentBackground with no options and set color to auto", () => {
const documentBackground = new DocumentBackground({});
const tree = new Formatter().format(documentBackground);
expect(tree).to.deep.equal({
"w:background": {
_attr: {
"w:color": "auto",
},
},
});
});
it("should create a DocumentBackground with no options and set color to value", () => {
const documentBackground = new DocumentBackground({ color: "ffffff" });
const tree = new Formatter().format(documentBackground);
expect(tree).to.deep.equal({
"w:background": {
_attr: {
"w:color": "ffffff",
},
},
});
});
it("should create a DocumentBackground with no options and set other values", () => {
const documentBackground = new DocumentBackground({
color: "ffffff",
themeColor: "test",
themeShade: "test",
themeTint: "test",
});
const tree = new Formatter().format(documentBackground);
expect(tree).to.deep.equal({
"w:background": {
_attr: {
"w:color": "ffffff",
"w:themeColor": "test",
"w:themeShade": "test",
"w:themeTint": "test",
},
},
});
});
});
});

View File

@ -0,0 +1,39 @@
// http://officeopenxml.com/WPdocument.php
// http://www.datypic.com/sc/ooxml/e-w_background-1.html
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
export class DocumentBackgroundAttributes extends XmlAttributeComponent<{
readonly color: string;
readonly themeColor?: string;
readonly themeShade?: string;
readonly themeTint?: string;
}> {
protected readonly xmlKeys = {
color: "w:color",
themeColor: "w:themeColor",
themeShade: "w:themeShade",
themeTint: "w:themeTint",
};
}
export interface IDocumentBackgroundOptions {
readonly color?: string;
readonly themeColor?: string;
readonly themeShade?: string;
readonly themeTint?: string;
}
export class DocumentBackground extends XmlComponent {
constructor(options: IDocumentBackgroundOptions) {
super("w:background");
this.root.push(
new DocumentBackgroundAttributes({
color: options.color ? options.color : "auto",
themeColor: options.themeColor,
themeShade: options.themeShade,
themeTint: options.themeTint,
}),
);
}
}

View File

@ -0,0 +1 @@
export * from "./document-background";

View File

@ -8,7 +8,7 @@ describe("Document", () => {
let document: Document; let document: Document;
beforeEach(() => { beforeEach(() => {
document = new Document(); document = new Document({ background: {} });
}); });
describe("#constructor()", () => { describe("#constructor()", () => {
@ -38,6 +38,13 @@ describe("Document", () => {
"mc:Ignorable": "w14 w15 wp14", "mc:Ignorable": "w14 w15 wp14",
}, },
}, },
{
"w:background": {
_attr: {
"w:color": "auto",
},
},
},
{ "w:body": {} }, { "w:body": {} },
], ],
}); });

View File

@ -5,11 +5,16 @@ import { Table } from "../table";
import { TableOfContents } from "../table-of-contents"; import { TableOfContents } from "../table-of-contents";
import { Body } from "./body"; import { Body } from "./body";
import { DocumentAttributes } from "./document-attributes"; import { DocumentAttributes } from "./document-attributes";
import { DocumentBackground, IDocumentBackgroundOptions } from "./document-background";
interface IDocumentOptions {
readonly background: IDocumentBackgroundOptions;
}
export class Document extends XmlComponent { export class Document extends XmlComponent {
private readonly body: Body; private readonly body: Body;
constructor() { constructor(options: IDocumentOptions) {
super("w:document"); super("w:document");
this.root.push( this.root.push(
new DocumentAttributes({ new DocumentAttributes({
@ -33,6 +38,7 @@ export class Document extends XmlComponent {
}), }),
); );
this.body = new Body(); this.body = new Body();
this.root.push(new DocumentBackground(options.background));
this.root.push(this.body); this.root.push(this.body);
} }

View File

@ -1,3 +1,4 @@
export * from "./document"; export * from "./document";
export * from "./document-attributes"; export * from "./document-attributes";
export * from "./body"; export * from "./body";
export * from "./document-background";

View File

@ -85,7 +85,7 @@ export class File {
this.appProperties = new AppProperties(); this.appProperties = new AppProperties();
this.footNotes = new FootNotes(); this.footNotes = new FootNotes();
this.contentTypes = new ContentTypes(); this.contentTypes = new ContentTypes();
this.document = new Document(); this.document = new Document({ background: options.background || {} });
this.settings = new Settings(); this.settings = new Settings();
this.media = fileProperties.template && fileProperties.template.media ? fileProperties.template.media : new Media(); this.media = fileProperties.template && fileProperties.template.media ? fileProperties.template.media : new Media();

View File

@ -0,0 +1,17 @@
import { expect } from "chai";
import { Formatter } from "export/formatter";
import { DisplayBackgroundShape } from "./display-background-shape";
describe("DisplayBackgroundShape", () => {
describe("#constructor()", () => {
it("should create", () => {
const displayBackgroundShape = new DisplayBackgroundShape();
const tree = new Formatter().format(displayBackgroundShape);
expect(tree).to.deep.equal({
"w:displayBackgroundShape": {},
});
});
});
});

View File

@ -0,0 +1,9 @@
// http://officeopenxml.com/WPdocument.php
// http://www.datypic.com/sc/ooxml/e-w_background-1.html
import { XmlComponent } from "file/xml-components";
export class DisplayBackgroundShape extends XmlComponent {
constructor() {
super("w:displayBackgroundShape");
}
}

View File

@ -15,8 +15,7 @@ describe("Settings", () => {
expect(keys[0]).to.be.equal("w:settings"); expect(keys[0]).to.be.equal("w:settings");
keys = Object.keys(tree["w:settings"]); keys = Object.keys(tree["w:settings"]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(2);
expect(keys[0]).to.be.equal("_attr");
}); });
}); });
describe("#addUpdateFields", () => { describe("#addUpdateFields", () => {
@ -28,16 +27,16 @@ describe("Settings", () => {
expect(keys[0]).to.be.equal("w:settings"); expect(keys[0]).to.be.equal("w:settings");
const rootArray = tree["w:settings"]; const rootArray = tree["w:settings"];
expect(rootArray).is.an.instanceof(Array); expect(rootArray).is.an.instanceof(Array);
expect(rootArray).has.length(2); expect(rootArray).has.length(3);
keys = Object.keys(rootArray[0]); keys = Object.keys(rootArray[0]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("_attr"); expect(keys[0]).to.be.equal("_attr");
keys = Object.keys(rootArray[1]); keys = Object.keys(rootArray[2]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("w:updateFields"); expect(keys[0]).to.be.equal("w:updateFields");
const updateFields = rootArray[1]["w:updateFields"]; const updateFields = rootArray[2]["w:updateFields"];
keys = Object.keys(updateFields); keys = Object.keys(updateFields);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
@ -68,12 +67,12 @@ describe("Settings", () => {
expect(keys[0]).to.be.equal("w:settings"); expect(keys[0]).to.be.equal("w:settings");
const rootArray = tree["w:settings"]; const rootArray = tree["w:settings"];
expect(rootArray).is.an.instanceof(Array); expect(rootArray).is.an.instanceof(Array);
expect(rootArray).has.length(2); expect(rootArray).has.length(3);
keys = Object.keys(rootArray[0]); keys = Object.keys(rootArray[0]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("_attr"); expect(keys[0]).to.be.equal("_attr");
keys = Object.keys(rootArray[1]); keys = Object.keys(rootArray[2]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("w:compat"); expect(keys[0]).to.be.equal("w:compat");
@ -89,12 +88,12 @@ describe("Settings", () => {
expect(keys[0]).to.be.equal("w:settings"); expect(keys[0]).to.be.equal("w:settings");
const rootArray = tree["w:settings"]; const rootArray = tree["w:settings"];
expect(rootArray).is.an.instanceof(Array); expect(rootArray).is.an.instanceof(Array);
expect(rootArray).has.length(2); expect(rootArray).has.length(3);
keys = Object.keys(rootArray[0]); keys = Object.keys(rootArray[0]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("_attr"); expect(keys[0]).to.be.equal("_attr");
keys = Object.keys(rootArray[1]); keys = Object.keys(rootArray[2]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("w:trackRevisions"); expect(keys[0]).to.be.equal("w:trackRevisions");
@ -111,12 +110,12 @@ describe("Settings", () => {
expect(keys[0]).to.be.equal("w:settings"); expect(keys[0]).to.be.equal("w:settings");
const rootArray = tree["w:settings"]; const rootArray = tree["w:settings"];
expect(rootArray).is.an.instanceof(Array); expect(rootArray).is.an.instanceof(Array);
expect(rootArray).has.length(2); expect(rootArray).has.length(3);
keys = Object.keys(rootArray[0]); keys = Object.keys(rootArray[0]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("_attr"); expect(keys[0]).to.be.equal("_attr");
keys = Object.keys(rootArray[1]); keys = Object.keys(rootArray[2]);
expect(keys).is.an.instanceof(Array); expect(keys).is.an.instanceof(Array);
expect(keys).has.length(1); expect(keys).has.length(1);
expect(keys[0]).to.be.equal("w:trackRevisions"); expect(keys[0]).to.be.equal("w:trackRevisions");

View File

@ -1,5 +1,6 @@
import { XmlAttributeComponent, XmlComponent } from "file/xml-components"; import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
import { Compatibility } from "./compatibility"; import { Compatibility } from "./compatibility";
import { DisplayBackgroundShape } from "./display-background-shape";
import { TrackRevisions } from "./track-revisions"; import { TrackRevisions } from "./track-revisions";
import { UpdateFields } from "./update-fields"; import { UpdateFields } from "./update-fields";
@ -72,8 +73,11 @@ export class Settings extends XmlComponent {
Ignorable: "w14 w15 wp14", Ignorable: "w14 w15 wp14",
}), }),
); );
this.compatibility = new Compatibility(); this.compatibility = new Compatibility();
this.trackRevisions = new TrackRevisions(); this.trackRevisions = new TrackRevisions();
this.root.push(new DisplayBackgroundShape());
} }
public addUpdateFields(): void { public addUpdateFields(): void {