Merge pull request #76 from formatically/master

Added DifferentFirstPageHeader and Page Number features
This commit is contained in:
Dolan
2018-05-19 12:30:39 +01:00
committed by GitHub
13 changed files with 206 additions and 7 deletions

23
demo/demo14.js Normal file
View File

@ -0,0 +1,23 @@
const docx = require('../build');
var doc = new docx.Document(undefined,{differentFirstPageHeader:true});
doc.createParagraph("First Page").pageBreak()
doc.createParagraph("Second Page");
var pageNumber = new docx.TextRun().pageNumber()
var pageoneheader = new docx.Paragraph("First Page Header ").right();
pageoneheader.addRun(pageNumber);
doc.firstPageHeader.addParagraph(pageoneheader);
var pagetwoheader = new docx.Paragraph("My Title ").right();
pagetwoheader.addRun(pageNumber)
doc.Header.addParagraph(pagetwoheader)
var exporter = new docx.LocalPacker(doc);
exporter.pack('My Document');
console.log('Document created successfully at project root!');

View File

@ -10,4 +10,4 @@ doc.Footer.createParagraph("Footer text");
var exporter = new docx.LocalPacker(doc);
exporter.pack('My Document');
console.log('Document created successfully at project root!');
console.log('Document created successfully at project root!');

View File

@ -34,6 +34,7 @@ export class Compiler {
const xmlRelationships = xml(this.formatter.format(this.file.DocumentRelationships));
const xmlFileRelationships = xml(this.formatter.format(this.file.FileRelationships));
const xmlHeader = xml(this.formatter.format(this.file.Header.Header));
const xmlHeader2 = xml(this.formatter.format(this.file.firstPageHeader.Header));
const xmlFooter = xml(this.formatter.format(this.file.Footer.Footer));
const xmlHeaderRelationships = xml(this.formatter.format(this.file.Header.Relationships));
const xmlFooterRelationships = xml(this.formatter.format(this.file.Footer.Relationships));
@ -64,6 +65,10 @@ export class Compiler {
name: "word/header1.xml",
});
this.archive.append(xmlHeader2, {
name: "word/header2.xml",
});
this.archive.append(xmlFooter, {
name: "word/footer1.xml",
});

View File

@ -24,7 +24,9 @@ export class ContentTypes extends XmlComponent {
this.root.push(
new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", "/word/document.xml"),
);
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", "/word/header1.xml"));
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml", "/word/header2.xml"));
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml", "/word/footer1.xml"));
this.root.push(new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml", "/word/styles.xml"));
this.root.push(new Override("application/vnd.openxmlformats-package.core-properties+xml", "/docProps/core.xml"));

View File

@ -2,12 +2,12 @@ import { XmlComponent } from "file/xml-components";
import { HeaderReferenceAttributes } from "./header-reference-attributes";
export class HeaderReference extends XmlComponent {
constructor() {
constructor(order: string, refID: number) {
super("w:headerReference");
this.root.push(
new HeaderReferenceAttributes({
type: "default",
id: `rId${3}`,
type: order,
id: `rId${refID}`,
}),
);
}

View File

@ -10,6 +10,7 @@ import { PageMargin } from "./page-margin/page-margin";
import { IPageMarginAttributes } from "./page-margin/page-margin-attributes";
import { PageSize } from "./page-size/page-size";
import { IPageSizeAttributes } from "./page-size/page-size-attributes";
import { TitlePage } from "./title-page/title-page";
export type SectionPropertiesOptions = IPageSizeAttributes & IPageMarginAttributes & IColumnsAttributes & IDocGridAttributesProperties;
@ -30,6 +31,7 @@ export class SectionProperties extends XmlComponent {
space: 708,
linePitch: 360,
orientation: "portrait",
differentFirstPageHeader: false,
};
const mergedOptions = {
@ -51,7 +53,13 @@ export class SectionProperties extends XmlComponent {
);
this.root.push(new Columns(mergedOptions.space));
this.root.push(new DocumentGrid(mergedOptions.linePitch));
this.root.push(new HeaderReference());
this.root.push(new HeaderReference("default", 3));
if (mergedOptions.differentFirstPageHeader) {
this.root.push(new HeaderReference("first", 5));
this.root.push(new TitlePage());
}
this.root.push(new FooterReference());
}
}

View File

@ -0,0 +1,11 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IHeaderReferenceAttributes {
value: string;
}
export class TitlePageAttributes extends XmlAttributeComponent<IHeaderReferenceAttributes> {
protected xmlKeys = {
value: "w:val",
};
}

View File

@ -0,0 +1,17 @@
import { expect } from "chai";
import { Formatter } from "../../../../../export/formatter";
import { TitlePage } from "./title-page";
describe("PageSize", () => {
describe("#constructor()", () => {
it("should create title page property for different first page header", () => {
const properties = new TitlePage();
const tree = new Formatter().format(properties);
expect(Object.keys(tree)).to.deep.equal(["w:titlePg"]);
expect(tree["w:titlePg"]).to.be.an.instanceof(Array);
expect(tree["w:titlePg"][0]).to.deep.equal({ _attr: { "w:val": "1" } });
});
});
});

View File

@ -0,0 +1,13 @@
import { XmlComponent } from "file/xml-components";
import { TitlePageAttributes } from "./title-page-attributes";
export class TitlePage extends XmlComponent {
constructor() {
super("w:titlePg");
this.root.push(
new TitlePageAttributes({
value: "1",
}),
);
}
}

View File

@ -5,7 +5,7 @@ import { CoreProperties, IPropertiesOptions } from "./core-properties";
import { Document } from "./document";
import { SectionPropertiesOptions } from "./document/body/section-properties/section-properties";
import { FooterWrapper } from "./footer-wrapper";
import { HeaderWrapper } from "./header-wrapper";
import { FirstPageHeaderWrapper, HeaderWrapper } from "./header-wrapper";
import { Media } from "./media";
import { Numbering } from "./numbering";
import { Hyperlink, Paragraph, PictureRun } from "./paragraph";
@ -24,6 +24,9 @@ export class File {
private readonly docRelationships: Relationships;
private readonly fileRelationships: Relationships;
private readonly headerWrapper: HeaderWrapper;
private readonly firstPageHeaderWrapper: FirstPageHeaderWrapper;
private readonly footerWrapper: FooterWrapper;
private readonly contentTypes: ContentTypes;
private readonly appProperties: AppProperties;
@ -65,13 +68,23 @@ export class File {
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
"header1.xml",
);
this.docRelationships.createRelationship(
5,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
"header2.xml",
);
this.docRelationships.createRelationship(
4,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
"footer1.xml",
);
this.media = new Media();
this.headerWrapper = new HeaderWrapper(this.media);
this.firstPageHeaderWrapper = new FirstPageHeaderWrapper(this.media);
this.footerWrapper = new FooterWrapper(this.media);
this.contentTypes = new ContentTypes();
this.fileRelationships = new Relationships();
@ -173,6 +186,10 @@ export class File {
return this.headerWrapper;
}
public get firstPageHeader(): FirstPageHeaderWrapper {
return this.firstPageHeaderWrapper;
}
public get Footer(): FooterWrapper {
return this.footerWrapper;
}

View File

@ -4,7 +4,7 @@ import { Paragraph } from "./paragraph";
import { Relationships } from "./relationships";
import { Table } from "./table";
export class HeaderWrapper {
export class FirstPageHeaderWrapper {
private readonly header: Header;
private readonly relationships: Relationships;
@ -53,3 +53,59 @@ export class HeaderWrapper {
return this.relationships;
}
}
export class HeaderWrapper {
private readonly header: Header;
private readonly header2: Header;
private readonly relationships: Relationships;
constructor(private readonly media: Media) {
this.header = new Header();
this.header2 = new Header();
this.relationships = new Relationships();
}
public addParagraph(paragraph: Paragraph): void {
this.header.addParagraph(paragraph);
}
public createParagraph(text?: string): Paragraph {
const para = new Paragraph(text);
this.addParagraph(para);
return para;
}
public addTable(table: Table): void {
this.header.addTable(table);
}
public createTable(rows: number, cols: number): Table {
return this.header.createTable(rows, cols);
}
public addDrawing(imageData: IMediaData): void {
this.header.addDrawing(imageData);
}
public createImage(image: string): void {
const mediaData = this.media.addMedia(image, this.relationships.RelationshipCount);
this.relationships.createRelationship(
mediaData.referenceId,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
`media/${mediaData.fileName}`,
);
this.addDrawing(mediaData);
}
public get Header(): Header {
return this.header;
}
public get Header2(): Header {
return this.header2;
}
public get Relationships(): Relationships {
return this.relationships;
}
}

View File

@ -0,0 +1,38 @@
import { XmlAttributeComponent, XmlComponent } from "file/xml-components";
class FidCharAttrs extends XmlAttributeComponent<{ type: "begin" | "end" | "separate" }> {
protected xmlKeys = { type: "w:fldCharType" };
}
class TextAttributes extends XmlAttributeComponent<{ space: "default" | "preserve" }> {
protected xmlKeys = { space: "xml:space" };
}
export class Begin extends XmlComponent {
constructor() {
super("w:fldChar");
this.root.push(new FidCharAttrs({ type: "begin" }));
}
}
export class Page extends XmlComponent {
constructor() {
super("w:instrText");
this.root.push(new TextAttributes({ space: "preserve" }));
this.root.push("PAGE");
}
}
export class Separate extends XmlComponent {
constructor() {
super("w:fldChar");
this.root.push(new FidCharAttrs({ type: "separate" }));
}
}
export class End extends XmlComponent {
constructor() {
super("w:fldChar");
this.root.push(new FidCharAttrs({ type: "end" }));
}
}

View File

@ -2,6 +2,7 @@
import { Break } from "./break";
import { Caps, SmallCaps } from "./caps";
import { Bold, Color, DoubleStrike, Italics, Size, Strike } from "./formatting";
import { Begin, End, Page, Separate } from "./page-number";
import { RunProperties } from "./properties";
import { RunFonts } from "./run-fonts";
import { SubScript, SuperScript } from "./script";
@ -55,6 +56,14 @@ export class Run extends XmlComponent {
return this;
}
public pageNumber(): Run {
this.root.push(new Begin());
this.root.push(new Page());
this.root.push(new Separate());
this.root.push(new End());
return this;
}
public smallCaps(): Run {
this.properties.push(new SmallCaps());
return this;