Merge pull request #76 from formatically/master
Added DifferentFirstPageHeader and Page Number features
This commit is contained in:
23
demo/demo14.js
Normal file
23
demo/demo14.js
Normal 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!');
|
@ -10,4 +10,4 @@ doc.Footer.createParagraph("Footer text");
|
|||||||
var exporter = new docx.LocalPacker(doc);
|
var exporter = new docx.LocalPacker(doc);
|
||||||
exporter.pack('My Document');
|
exporter.pack('My Document');
|
||||||
|
|
||||||
console.log('Document created successfully at project root!');
|
console.log('Document created successfully at project root!');
|
@ -34,6 +34,7 @@ export class Compiler {
|
|||||||
const xmlRelationships = xml(this.formatter.format(this.file.DocumentRelationships));
|
const xmlRelationships = xml(this.formatter.format(this.file.DocumentRelationships));
|
||||||
const xmlFileRelationships = xml(this.formatter.format(this.file.FileRelationships));
|
const xmlFileRelationships = xml(this.formatter.format(this.file.FileRelationships));
|
||||||
const xmlHeader = xml(this.formatter.format(this.file.Header.Header));
|
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 xmlFooter = xml(this.formatter.format(this.file.Footer.Footer));
|
||||||
const xmlHeaderRelationships = xml(this.formatter.format(this.file.Header.Relationships));
|
const xmlHeaderRelationships = xml(this.formatter.format(this.file.Header.Relationships));
|
||||||
const xmlFooterRelationships = xml(this.formatter.format(this.file.Footer.Relationships));
|
const xmlFooterRelationships = xml(this.formatter.format(this.file.Footer.Relationships));
|
||||||
@ -64,6 +65,10 @@ export class Compiler {
|
|||||||
name: "word/header1.xml",
|
name: "word/header1.xml",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.archive.append(xmlHeader2, {
|
||||||
|
name: "word/header2.xml",
|
||||||
|
});
|
||||||
|
|
||||||
this.archive.append(xmlFooter, {
|
this.archive.append(xmlFooter, {
|
||||||
name: "word/footer1.xml",
|
name: "word/footer1.xml",
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,9 @@ export class ContentTypes extends XmlComponent {
|
|||||||
this.root.push(
|
this.root.push(
|
||||||
new Override("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml", "/word/document.xml"),
|
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/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.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-officedocument.wordprocessingml.styles+xml", "/word/styles.xml"));
|
||||||
this.root.push(new Override("application/vnd.openxmlformats-package.core-properties+xml", "/docProps/core.xml"));
|
this.root.push(new Override("application/vnd.openxmlformats-package.core-properties+xml", "/docProps/core.xml"));
|
||||||
|
@ -2,12 +2,12 @@ import { XmlComponent } from "file/xml-components";
|
|||||||
import { HeaderReferenceAttributes } from "./header-reference-attributes";
|
import { HeaderReferenceAttributes } from "./header-reference-attributes";
|
||||||
|
|
||||||
export class HeaderReference extends XmlComponent {
|
export class HeaderReference extends XmlComponent {
|
||||||
constructor() {
|
constructor(order: string, refID: number) {
|
||||||
super("w:headerReference");
|
super("w:headerReference");
|
||||||
this.root.push(
|
this.root.push(
|
||||||
new HeaderReferenceAttributes({
|
new HeaderReferenceAttributes({
|
||||||
type: "default",
|
type: order,
|
||||||
id: `rId${3}`,
|
id: `rId${refID}`,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import { PageMargin } from "./page-margin/page-margin";
|
|||||||
import { IPageMarginAttributes } from "./page-margin/page-margin-attributes";
|
import { IPageMarginAttributes } from "./page-margin/page-margin-attributes";
|
||||||
import { PageSize } from "./page-size/page-size";
|
import { PageSize } from "./page-size/page-size";
|
||||||
import { IPageSizeAttributes } from "./page-size/page-size-attributes";
|
import { IPageSizeAttributes } from "./page-size/page-size-attributes";
|
||||||
|
import { TitlePage } from "./title-page/title-page";
|
||||||
|
|
||||||
export type SectionPropertiesOptions = IPageSizeAttributes & IPageMarginAttributes & IColumnsAttributes & IDocGridAttributesProperties;
|
export type SectionPropertiesOptions = IPageSizeAttributes & IPageMarginAttributes & IColumnsAttributes & IDocGridAttributesProperties;
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ export class SectionProperties extends XmlComponent {
|
|||||||
space: 708,
|
space: 708,
|
||||||
linePitch: 360,
|
linePitch: 360,
|
||||||
orientation: "portrait",
|
orientation: "portrait",
|
||||||
|
differentFirstPageHeader: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mergedOptions = {
|
const mergedOptions = {
|
||||||
@ -51,7 +53,13 @@ export class SectionProperties extends XmlComponent {
|
|||||||
);
|
);
|
||||||
this.root.push(new Columns(mergedOptions.space));
|
this.root.push(new Columns(mergedOptions.space));
|
||||||
this.root.push(new DocumentGrid(mergedOptions.linePitch));
|
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());
|
this.root.push(new FooterReference());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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",
|
||||||
|
};
|
||||||
|
}
|
@ -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" } });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -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",
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ import { CoreProperties, IPropertiesOptions } from "./core-properties";
|
|||||||
import { Document } from "./document";
|
import { Document } from "./document";
|
||||||
import { SectionPropertiesOptions } from "./document/body/section-properties/section-properties";
|
import { SectionPropertiesOptions } from "./document/body/section-properties/section-properties";
|
||||||
import { FooterWrapper } from "./footer-wrapper";
|
import { FooterWrapper } from "./footer-wrapper";
|
||||||
import { HeaderWrapper } from "./header-wrapper";
|
import { FirstPageHeaderWrapper, HeaderWrapper } from "./header-wrapper";
|
||||||
import { Media } from "./media";
|
import { Media } from "./media";
|
||||||
import { Numbering } from "./numbering";
|
import { Numbering } from "./numbering";
|
||||||
import { Hyperlink, Paragraph, PictureRun } from "./paragraph";
|
import { Hyperlink, Paragraph, PictureRun } from "./paragraph";
|
||||||
@ -24,6 +24,9 @@ export class File {
|
|||||||
private readonly docRelationships: Relationships;
|
private readonly docRelationships: Relationships;
|
||||||
private readonly fileRelationships: Relationships;
|
private readonly fileRelationships: Relationships;
|
||||||
private readonly headerWrapper: HeaderWrapper;
|
private readonly headerWrapper: HeaderWrapper;
|
||||||
|
|
||||||
|
private readonly firstPageHeaderWrapper: FirstPageHeaderWrapper;
|
||||||
|
|
||||||
private readonly footerWrapper: FooterWrapper;
|
private readonly footerWrapper: FooterWrapper;
|
||||||
private readonly contentTypes: ContentTypes;
|
private readonly contentTypes: ContentTypes;
|
||||||
private readonly appProperties: AppProperties;
|
private readonly appProperties: AppProperties;
|
||||||
@ -65,13 +68,23 @@ export class File {
|
|||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
|
||||||
"header1.xml",
|
"header1.xml",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.docRelationships.createRelationship(
|
||||||
|
5,
|
||||||
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
|
||||||
|
"header2.xml",
|
||||||
|
);
|
||||||
|
|
||||||
this.docRelationships.createRelationship(
|
this.docRelationships.createRelationship(
|
||||||
4,
|
4,
|
||||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
|
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
|
||||||
"footer1.xml",
|
"footer1.xml",
|
||||||
);
|
);
|
||||||
this.media = new Media();
|
this.media = new Media();
|
||||||
|
|
||||||
this.headerWrapper = new HeaderWrapper(this.media);
|
this.headerWrapper = new HeaderWrapper(this.media);
|
||||||
|
this.firstPageHeaderWrapper = new FirstPageHeaderWrapper(this.media);
|
||||||
|
|
||||||
this.footerWrapper = new FooterWrapper(this.media);
|
this.footerWrapper = new FooterWrapper(this.media);
|
||||||
this.contentTypes = new ContentTypes();
|
this.contentTypes = new ContentTypes();
|
||||||
this.fileRelationships = new Relationships();
|
this.fileRelationships = new Relationships();
|
||||||
@ -173,6 +186,10 @@ export class File {
|
|||||||
return this.headerWrapper;
|
return this.headerWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get firstPageHeader(): FirstPageHeaderWrapper {
|
||||||
|
return this.firstPageHeaderWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
public get Footer(): FooterWrapper {
|
public get Footer(): FooterWrapper {
|
||||||
return this.footerWrapper;
|
return this.footerWrapper;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import { Paragraph } from "./paragraph";
|
|||||||
import { Relationships } from "./relationships";
|
import { Relationships } from "./relationships";
|
||||||
import { Table } from "./table";
|
import { Table } from "./table";
|
||||||
|
|
||||||
export class HeaderWrapper {
|
export class FirstPageHeaderWrapper {
|
||||||
private readonly header: Header;
|
private readonly header: Header;
|
||||||
private readonly relationships: Relationships;
|
private readonly relationships: Relationships;
|
||||||
|
|
||||||
@ -53,3 +53,59 @@ export class HeaderWrapper {
|
|||||||
return this.relationships;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
38
src/file/paragraph/run/page-number.ts
Normal file
38
src/file/paragraph/run/page-number.ts
Normal 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" }));
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
import { Break } from "./break";
|
import { Break } from "./break";
|
||||||
import { Caps, SmallCaps } from "./caps";
|
import { Caps, SmallCaps } from "./caps";
|
||||||
import { Bold, Color, DoubleStrike, Italics, Size, Strike } from "./formatting";
|
import { Bold, Color, DoubleStrike, Italics, Size, Strike } from "./formatting";
|
||||||
|
import { Begin, End, Page, Separate } from "./page-number";
|
||||||
import { RunProperties } from "./properties";
|
import { RunProperties } from "./properties";
|
||||||
import { RunFonts } from "./run-fonts";
|
import { RunFonts } from "./run-fonts";
|
||||||
import { SubScript, SuperScript } from "./script";
|
import { SubScript, SuperScript } from "./script";
|
||||||
@ -55,6 +56,14 @@ export class Run extends XmlComponent {
|
|||||||
return this;
|
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 {
|
public smallCaps(): Run {
|
||||||
this.properties.push(new SmallCaps());
|
this.properties.push(new SmallCaps());
|
||||||
return this;
|
return this;
|
||||||
|
Reference in New Issue
Block a user