From 87648a742cd0efba737558c6fa23e8ba6c70f4fb Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Sat, 12 May 2018 20:04:54 -0400 Subject: [PATCH 1/8] Initial Commit --- demo/demo8.js | 23 +++++-- src/export/packer/compiler.ts | 12 ++++ src/file/content-types/content-types.ts | 2 + .../header-reference/header-reference.ts | 6 +- .../section-properties/section-properties.ts | 5 +- .../titlepage/titlepage-attributes.ts | 11 ++++ .../section-properties/titlepage/titlepage.ts | 13 ++++ src/file/file.ts | 21 +++++++ src/file/header-wrapper2.ts | 55 +++++++++++++++++ src/file/header2/header-attributes.ts | 53 ++++++++++++++++ src/file/header2/header.ts | 60 +++++++++++++++++++ src/file/header2/index.ts | 1 + src/file/paragraph/run/pagenumber.ts | 38 ++++++++++++ src/file/paragraph/run/run.ts | 9 +++ 14 files changed, 301 insertions(+), 8 deletions(-) create mode 100644 src/file/document/body/section-properties/titlepage/titlepage-attributes.ts create mode 100644 src/file/document/body/section-properties/titlepage/titlepage.ts create mode 100644 src/file/header-wrapper2.ts create mode 100644 src/file/header2/header-attributes.ts create mode 100644 src/file/header2/header.ts create mode 100644 src/file/header2/index.ts create mode 100644 src/file/paragraph/run/pagenumber.ts diff --git a/demo/demo8.js b/demo/demo8.js index e849ae3f11..cb447b299b 100644 --- a/demo/demo8.js +++ b/demo/demo8.js @@ -2,12 +2,27 @@ const docx = require('../build'); var doc = new docx.Document(); -doc.createParagraph("Hello World"); +doc.createParagraph("First Page").pageBreak() +doc.createParagraph("Second Page"); + + +var pageoneheader = new docx.Paragraph("Running head: My Title").right() +//var tab = new docx.TextRun().tab() +var pageNumber = new docx.TextRun().pageNumber() + +//pageoneheader.addRun(tab); +pageoneheader.addRun(pageNumber); +doc.Header2.addParagraph(pageoneheader); + +var pagetwoheader = new docx.Paragraph("My Title").maxRightTabStop(); + +//pagetwoheader.addRun(tab) +pagetwoheader.addRun(pageNumber) +doc.Header.addParagraph(pagetwoheader) +doc.Header = new docx.Paragraph("My Title") -doc.Header.createParagraph("Header text"); -doc.Footer.createParagraph("Footer text"); var exporter = new docx.LocalPacker(doc); -exporter.pack('My Document'); +exporter.pack('Testing'); console.log('Document created successfully at project root!'); diff --git a/src/export/packer/compiler.ts b/src/export/packer/compiler.ts index 44c7817249..58e97f5eed 100644 --- a/src/export/packer/compiler.ts +++ b/src/export/packer/compiler.ts @@ -34,12 +34,16 @@ 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.Header2.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)); const xmlContentTypes = xml(this.formatter.format(this.file.ContentTypes)); const xmlAppProperties = xml(this.formatter.format(this.file.AppProperties)); + this.archive.append(xmlDocument, { name: "word/document.xml", }); @@ -64,6 +68,14 @@ export class Compiler { name: "word/header1.xml", }); + + + this.archive.append(xmlHeader2, { + name: "word/header2.xml", + }); + + + this.archive.append(xmlFooter, { name: "word/footer1.xml", }); diff --git a/src/file/content-types/content-types.ts b/src/file/content-types/content-types.ts index 4ce020a918..64c9db3113 100644 --- a/src/file/content-types/content-types.ts +++ b/src/file/content-types/content-types.ts @@ -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")); diff --git a/src/file/document/body/section-properties/header-reference/header-reference.ts b/src/file/document/body/section-properties/header-reference/header-reference.ts index 3809047bef..53d75ede28 100644 --- a/src/file/document/body/section-properties/header-reference/header-reference.ts +++ b/src/file/document/body/section-properties/header-reference/header-reference.ts @@ -2,12 +2,12 @@ import { XmlComponent } from "file/xml-components"; import { HeaderReferenceAttributes } from "./header-reference-attributes"; export class HeaderReference extends XmlComponent { - constructor() { + constructor(order, ref_id) { super("w:headerReference"); this.root.push( new HeaderReferenceAttributes({ - type: "default", - id: `rId${3}`, + type: order, + id: `rId${ref_id}`, }), ); } diff --git a/src/file/document/body/section-properties/section-properties.ts b/src/file/document/body/section-properties/section-properties.ts index 27d3f0bd99..5c06ee8631 100644 --- a/src/file/document/body/section-properties/section-properties.ts +++ b/src/file/document/body/section-properties/section-properties.ts @@ -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 "./titlepage/titlepage"; export type SectionPropertiesOptions = IPageSizeAttributes & IPageMarginAttributes & IColumnsAttributes & IDocGridAttributesProperties; @@ -51,7 +52,9 @@ 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)); + this.root.push(new HeaderReference("first",5)); + this.root.push(new TitlePage()); this.root.push(new FooterReference()); } } diff --git a/src/file/document/body/section-properties/titlepage/titlepage-attributes.ts b/src/file/document/body/section-properties/titlepage/titlepage-attributes.ts new file mode 100644 index 0000000000..960064ec1f --- /dev/null +++ b/src/file/document/body/section-properties/titlepage/titlepage-attributes.ts @@ -0,0 +1,11 @@ +import { XmlAttributeComponent } from "file/xml-components"; + +export interface IHeaderReferenceAttributes { + value: string; +} + +export class TitlePageAttributes extends XmlAttributeComponent { + protected xmlKeys = { + value: "w:val", + }; +} \ No newline at end of file diff --git a/src/file/document/body/section-properties/titlepage/titlepage.ts b/src/file/document/body/section-properties/titlepage/titlepage.ts new file mode 100644 index 0000000000..361cc039fa --- /dev/null +++ b/src/file/document/body/section-properties/titlepage/titlepage.ts @@ -0,0 +1,13 @@ +import { XmlComponent } from "file/xml-components"; +import { TitlePageAttributes } from "./titlepage-attributes"; + +export class TitlePage extends XmlComponent { + constructor() { + super("w:titlePg"); + this.root.push( + new TitlePageAttributes({ + value: "1", + }), + ); + } +} \ No newline at end of file diff --git a/src/file/file.ts b/src/file/file.ts index 39a9e3d210..89e752e770 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -5,6 +5,9 @@ import { Document } from "./document"; import { SectionPropertiesOptions } from "./document/body/section-properties/section-properties"; import { FooterWrapper } from "./footer-wrapper"; import { HeaderWrapper } from "./header-wrapper"; + +import { HeaderWrapper2 } from "./header-wrapper2"; + import { Media } from "./media"; import { Numbering } from "./numbering"; import { Hyperlink, Paragraph, PictureRun } from "./paragraph"; @@ -22,6 +25,9 @@ export class File { private readonly docRelationships: Relationships; private readonly fileRelationships: Relationships; private readonly headerWrapper: HeaderWrapper; + + private readonly headerWrapper2: HeaderWrapper2; + private readonly footerWrapper: FooterWrapper; private readonly contentTypes: ContentTypes; private readonly appProperties: AppProperties; @@ -57,13 +63,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.headerWrapper2 = new HeaderWrapper2(this.media); + this.footerWrapper = new FooterWrapper(this.media); this.contentTypes = new ContentTypes(); this.fileRelationships = new Relationships(); @@ -155,6 +171,11 @@ export class File { return this.headerWrapper; } + public get Header2(): HeaderWrapper2 { + return this.headerWrapper2; + } + + public get Footer(): FooterWrapper { return this.footerWrapper; } diff --git a/src/file/header-wrapper2.ts b/src/file/header-wrapper2.ts new file mode 100644 index 0000000000..7663842727 --- /dev/null +++ b/src/file/header-wrapper2.ts @@ -0,0 +1,55 @@ +import { Header2 } from "./header2/header"; +import { IMediaData, Media } from "./media"; +import { Paragraph } from "./paragraph"; +import { Relationships } from "./relationships"; +import { Table } from "./table"; + +export class HeaderWrapper2 { + private readonly header: Header2; + private readonly relationships: Relationships; + + constructor(private readonly media: Media) { + this.header = new Header2(); + 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(): Header2 { + return this.header; + } + + public get Relationships(): Relationships { + return this.relationships; + } +} diff --git a/src/file/header2/header-attributes.ts b/src/file/header2/header-attributes.ts new file mode 100644 index 0000000000..e47271841c --- /dev/null +++ b/src/file/header2/header-attributes.ts @@ -0,0 +1,53 @@ +import { XmlAttributeComponent } from "file/xml-components"; + +export interface IHeaderAttributesProperties { + wpc?: string; + mc?: string; + o?: string; + r?: string; + m?: string; + v?: string; + wp14?: string; + wp?: string; + w10?: string; + w?: string; + w14?: string; + w15?: string; + wpg?: string; + wpi?: string; + wne?: string; + wps?: string; + cp?: string; + dc?: string; + dcterms?: string; + dcmitype?: string; + xsi?: string; + type?: string; +} + +export class HeaderAttributes extends XmlAttributeComponent { + protected xmlKeys = { + wpc: "xmlns:wpc", + mc: "xmlns:mc", + o: "xmlns:o", + r: "xmlns:r", + m: "xmlns:m", + v: "xmlns:v", + wp14: "xmlns:wp14", + wp: "xmlns:wp", + w10: "xmlns:w10", + w: "xmlns:w", + w14: "xmlns:w14", + w15: "xmlns:w15", + wpg: "xmlns:wpg", + wpi: "xmlns:wpi", + wne: "xmlns:wne", + wps: "xmlns:wps", + cp: "xmlns:cp", + dc: "xmlns:dc", + dcterms: "xmlns:dcterms", + dcmitype: "xmlns:dcmitype", + xsi: "xmlns:xsi", + type: "xsi:type", + }; +} diff --git a/src/file/header2/header.ts b/src/file/header2/header.ts new file mode 100644 index 0000000000..fb34ff13ac --- /dev/null +++ b/src/file/header2/header.ts @@ -0,0 +1,60 @@ +// http://officeopenxml.com/WPheaders.php +import { IMediaData } from "file/media"; +import { XmlComponent } from "file/xml-components"; +import { Paragraph, PictureRun } from "../paragraph"; +import { Table } from "../table"; +import { HeaderAttributes } from "./header-attributes"; + +export class Header2 extends XmlComponent { + constructor() { + super("w:hdr"); + this.root.push( + new HeaderAttributes({ + wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas", + mc: "http://schemas.openxmlformats.org/markup-compatibility/2006", + o: "urn:schemas-microsoft-com:office:office", + r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships", + m: "http://schemas.openxmlformats.org/officeDocument/2006/math", + v: "urn:schemas-microsoft-com:vml", + wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing", + wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", + w10: "urn:schemas-microsoft-com:office:word", + w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main", + w14: "http://schemas.microsoft.com/office/word/2010/wordml", + w15: "http://schemas.microsoft.com/office/word/2012/wordml", + wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup", + wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk", + wne: "http://schemas.microsoft.com/office/word/2006/wordml", + wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape", + }), + ); + } + + public addParagraph(paragraph: Paragraph): void { + this.root.push(paragraph); + } + + public createParagraph(text?: string): Paragraph { + const para = new Paragraph(text); + this.addParagraph(para); + return para; + } + + public addTable(table: Table): void { + this.root.push(table); + } + + public createTable(rows: number, cols: number): Table { + const table = new Table(rows, cols); + this.addTable(table); + return table; + } + + public addDrawing(imageData: IMediaData): void { + const paragraph = new Paragraph(); + const run = new PictureRun(imageData); + paragraph.addRun(run); + + this.root.push(paragraph); + } +} diff --git a/src/file/header2/index.ts b/src/file/header2/index.ts new file mode 100644 index 0000000000..49ac70fe21 --- /dev/null +++ b/src/file/header2/index.ts @@ -0,0 +1 @@ +export * from "./header"; diff --git a/src/file/paragraph/run/pagenumber.ts b/src/file/paragraph/run/pagenumber.ts new file mode 100644 index 0000000000..20dc8f061a --- /dev/null +++ b/src/file/paragraph/run/pagenumber.ts @@ -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" })); + } +} \ No newline at end of file diff --git a/src/file/paragraph/run/run.ts b/src/file/paragraph/run/run.ts index 243cea68d3..508aad9afa 100644 --- a/src/file/paragraph/run/run.ts +++ b/src/file/paragraph/run/run.ts @@ -8,6 +8,7 @@ import { SubScript, SuperScript } from "./script"; import { Style } from "./style"; import { Tab } from "./tab"; import { Underline } from "./underline"; +import { Begin, Page, End, Separate } from "./pagenumber"; import { XmlComponent } from "file/xml-components"; @@ -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; From 7968c1efcfbde4fe50e8067bee172c7665b33649 Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Sat, 12 May 2018 22:22:54 -0400 Subject: [PATCH 2/8] Removed header-wrapper-2 --- demo/demo8.js | 10 ++--- src/export/packer/compiler.ts | 2 +- src/file/file.ts | 13 +++--- src/file/header-wrapper.ts | 58 +++++++++++++++++++++++++- src/file/header-wrapper2.ts | 55 ------------------------ src/file/header2/header-attributes.ts | 53 ----------------------- src/file/header2/header.ts | 60 --------------------------- src/file/header2/index.ts | 1 - 8 files changed, 69 insertions(+), 183 deletions(-) delete mode 100644 src/file/header-wrapper2.ts delete mode 100644 src/file/header2/header-attributes.ts delete mode 100644 src/file/header2/header.ts delete mode 100644 src/file/header2/index.ts diff --git a/demo/demo8.js b/demo/demo8.js index cb447b299b..a12a4decd0 100644 --- a/demo/demo8.js +++ b/demo/demo8.js @@ -6,17 +6,17 @@ doc.createParagraph("First Page").pageBreak() doc.createParagraph("Second Page"); -var pageoneheader = new docx.Paragraph("Running head: My Title").right() -//var tab = new docx.TextRun().tab() +var pageoneheader = new docx.Paragraph("Running head: My Title").maxRightTabStop(); +var tab = new docx.TextRun().tab() var pageNumber = new docx.TextRun().pageNumber() -//pageoneheader.addRun(tab); +pageoneheader.addRun(tab); pageoneheader.addRun(pageNumber); -doc.Header2.addParagraph(pageoneheader); +doc.firstPageHeader.addParagraph(pageoneheader); var pagetwoheader = new docx.Paragraph("My Title").maxRightTabStop(); -//pagetwoheader.addRun(tab) +pagetwoheader.addRun(tab) pagetwoheader.addRun(pageNumber) doc.Header.addParagraph(pagetwoheader) doc.Header = new docx.Paragraph("My Title") diff --git a/src/export/packer/compiler.ts b/src/export/packer/compiler.ts index 58e97f5eed..f267b991bc 100644 --- a/src/export/packer/compiler.ts +++ b/src/export/packer/compiler.ts @@ -35,7 +35,7 @@ export class Compiler { 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.Header2.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)); diff --git a/src/file/file.ts b/src/file/file.ts index 89e752e770..1e4bc60717 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -4,9 +4,9 @@ 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 { HeaderWrapper, FirstPageHeaderWrapper } from "./header-wrapper"; -import { HeaderWrapper2 } from "./header-wrapper2"; +//import { HeaderWrapper2 } from "./header-wrapper2"; import { Media } from "./media"; import { Numbering } from "./numbering"; @@ -26,7 +26,7 @@ export class File { private readonly fileRelationships: Relationships; private readonly headerWrapper: HeaderWrapper; - private readonly headerWrapper2: HeaderWrapper2; + private readonly firstPageHeaderWrapper: FirstPageHeaderWrapper; private readonly footerWrapper: FooterWrapper; private readonly contentTypes: ContentTypes; @@ -78,7 +78,7 @@ export class File { this.media = new Media(); this.headerWrapper = new HeaderWrapper(this.media); - this.headerWrapper2 = new HeaderWrapper2(this.media); + this.firstPageHeaderWrapper = new FirstPageHeaderWrapper(this.media); this.footerWrapper = new FooterWrapper(this.media); this.contentTypes = new ContentTypes(); @@ -171,11 +171,10 @@ export class File { return this.headerWrapper; } - public get Header2(): HeaderWrapper2 { - return this.headerWrapper2; + public get firstPageHeader(): FirstPageHeaderWrapper { + return this.firstPageHeaderWrapper; } - public get Footer(): FooterWrapper { return this.footerWrapper; } diff --git a/src/file/header-wrapper.ts b/src/file/header-wrapper.ts index df15871bef..9382099c60 100644 --- a/src/file/header-wrapper.ts +++ b/src/file/header-wrapper.ts @@ -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; + } +} diff --git a/src/file/header-wrapper2.ts b/src/file/header-wrapper2.ts deleted file mode 100644 index 7663842727..0000000000 --- a/src/file/header-wrapper2.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Header2 } from "./header2/header"; -import { IMediaData, Media } from "./media"; -import { Paragraph } from "./paragraph"; -import { Relationships } from "./relationships"; -import { Table } from "./table"; - -export class HeaderWrapper2 { - private readonly header: Header2; - private readonly relationships: Relationships; - - constructor(private readonly media: Media) { - this.header = new Header2(); - 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(): Header2 { - return this.header; - } - - public get Relationships(): Relationships { - return this.relationships; - } -} diff --git a/src/file/header2/header-attributes.ts b/src/file/header2/header-attributes.ts deleted file mode 100644 index e47271841c..0000000000 --- a/src/file/header2/header-attributes.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { XmlAttributeComponent } from "file/xml-components"; - -export interface IHeaderAttributesProperties { - wpc?: string; - mc?: string; - o?: string; - r?: string; - m?: string; - v?: string; - wp14?: string; - wp?: string; - w10?: string; - w?: string; - w14?: string; - w15?: string; - wpg?: string; - wpi?: string; - wne?: string; - wps?: string; - cp?: string; - dc?: string; - dcterms?: string; - dcmitype?: string; - xsi?: string; - type?: string; -} - -export class HeaderAttributes extends XmlAttributeComponent { - protected xmlKeys = { - wpc: "xmlns:wpc", - mc: "xmlns:mc", - o: "xmlns:o", - r: "xmlns:r", - m: "xmlns:m", - v: "xmlns:v", - wp14: "xmlns:wp14", - wp: "xmlns:wp", - w10: "xmlns:w10", - w: "xmlns:w", - w14: "xmlns:w14", - w15: "xmlns:w15", - wpg: "xmlns:wpg", - wpi: "xmlns:wpi", - wne: "xmlns:wne", - wps: "xmlns:wps", - cp: "xmlns:cp", - dc: "xmlns:dc", - dcterms: "xmlns:dcterms", - dcmitype: "xmlns:dcmitype", - xsi: "xmlns:xsi", - type: "xsi:type", - }; -} diff --git a/src/file/header2/header.ts b/src/file/header2/header.ts deleted file mode 100644 index fb34ff13ac..0000000000 --- a/src/file/header2/header.ts +++ /dev/null @@ -1,60 +0,0 @@ -// http://officeopenxml.com/WPheaders.php -import { IMediaData } from "file/media"; -import { XmlComponent } from "file/xml-components"; -import { Paragraph, PictureRun } from "../paragraph"; -import { Table } from "../table"; -import { HeaderAttributes } from "./header-attributes"; - -export class Header2 extends XmlComponent { - constructor() { - super("w:hdr"); - this.root.push( - new HeaderAttributes({ - wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas", - mc: "http://schemas.openxmlformats.org/markup-compatibility/2006", - o: "urn:schemas-microsoft-com:office:office", - r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships", - m: "http://schemas.openxmlformats.org/officeDocument/2006/math", - v: "urn:schemas-microsoft-com:vml", - wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing", - wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", - w10: "urn:schemas-microsoft-com:office:word", - w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main", - w14: "http://schemas.microsoft.com/office/word/2010/wordml", - w15: "http://schemas.microsoft.com/office/word/2012/wordml", - wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup", - wpi: "http://schemas.microsoft.com/office/word/2010/wordprocessingInk", - wne: "http://schemas.microsoft.com/office/word/2006/wordml", - wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape", - }), - ); - } - - public addParagraph(paragraph: Paragraph): void { - this.root.push(paragraph); - } - - public createParagraph(text?: string): Paragraph { - const para = new Paragraph(text); - this.addParagraph(para); - return para; - } - - public addTable(table: Table): void { - this.root.push(table); - } - - public createTable(rows: number, cols: number): Table { - const table = new Table(rows, cols); - this.addTable(table); - return table; - } - - public addDrawing(imageData: IMediaData): void { - const paragraph = new Paragraph(); - const run = new PictureRun(imageData); - paragraph.addRun(run); - - this.root.push(paragraph); - } -} diff --git a/src/file/header2/index.ts b/src/file/header2/index.ts deleted file mode 100644 index 49ac70fe21..0000000000 --- a/src/file/header2/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./header"; From 6c2eb882bb0e23c136c4df0b9d20ba483ac4cd8b Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Thu, 17 May 2018 11:45:06 -0600 Subject: [PATCH 3/8] Added differentFirstPageHeader section property --- demo/demo8.js | 6 +++--- src/export/packer/compiler.ts | 4 ---- .../body/section-properties/section-properties.ts | 9 +++++++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/demo/demo8.js b/demo/demo8.js index a12a4decd0..90213955f2 100644 --- a/demo/demo8.js +++ b/demo/demo8.js @@ -1,15 +1,15 @@ const docx = require('../build'); -var doc = new docx.Document(); +var doc = new docx.Document(undefined,{differentFirstPageHeader:true}); doc.createParagraph("First Page").pageBreak() doc.createParagraph("Second Page"); - -var pageoneheader = new docx.Paragraph("Running head: My Title").maxRightTabStop(); var tab = new docx.TextRun().tab() var pageNumber = new docx.TextRun().pageNumber() +var pageoneheader = new docx.Paragraph("Running head: My Title").maxRightTabStop(); + pageoneheader.addRun(tab); pageoneheader.addRun(pageNumber); doc.firstPageHeader.addParagraph(pageoneheader); diff --git a/src/export/packer/compiler.ts b/src/export/packer/compiler.ts index f267b991bc..75357219bc 100644 --- a/src/export/packer/compiler.ts +++ b/src/export/packer/compiler.ts @@ -68,14 +68,10 @@ export class Compiler { name: "word/header1.xml", }); - - this.archive.append(xmlHeader2, { name: "word/header2.xml", }); - - this.archive.append(xmlFooter, { name: "word/footer1.xml", }); diff --git a/src/file/document/body/section-properties/section-properties.ts b/src/file/document/body/section-properties/section-properties.ts index 5c06ee8631..711d580962 100644 --- a/src/file/document/body/section-properties/section-properties.ts +++ b/src/file/document/body/section-properties/section-properties.ts @@ -31,6 +31,7 @@ export class SectionProperties extends XmlComponent { space: 708, linePitch: 360, orientation: "portrait", + differentFirstPageHeader: false, }; const mergedOptions = { @@ -53,8 +54,12 @@ export class SectionProperties extends XmlComponent { this.root.push(new Columns(mergedOptions.space)); this.root.push(new DocumentGrid(mergedOptions.linePitch)); this.root.push(new HeaderReference("default",3)); - this.root.push(new HeaderReference("first",5)); - this.root.push(new TitlePage()); + + if (mergedOptions.differentFirstPageHeader) { + this.root.push(new HeaderReference("first",5)); + this.root.push(new TitlePage()); + } + this.root.push(new FooterReference()); } } From 0fedfcf7098bf9f40436bdeb2b499b5b348758a1 Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Thu, 17 May 2018 11:54:13 -0600 Subject: [PATCH 4/8] Renamed titlepage to title-page --- src/file/document/body/section-properties/section-properties.ts | 2 +- .../title-page-attributes.ts} | 0 .../{titlepage/titlepage.ts => title-page/title-page.ts} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename src/file/document/body/section-properties/{titlepage/titlepage-attributes.ts => title-page/title-page-attributes.ts} (100%) rename src/file/document/body/section-properties/{titlepage/titlepage.ts => title-page/title-page.ts} (100%) diff --git a/src/file/document/body/section-properties/section-properties.ts b/src/file/document/body/section-properties/section-properties.ts index 711d580962..aea95a0d85 100644 --- a/src/file/document/body/section-properties/section-properties.ts +++ b/src/file/document/body/section-properties/section-properties.ts @@ -10,7 +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 "./titlepage/titlepage"; +import { TitlePage } from "./title-page/title-page"; export type SectionPropertiesOptions = IPageSizeAttributes & IPageMarginAttributes & IColumnsAttributes & IDocGridAttributesProperties; diff --git a/src/file/document/body/section-properties/titlepage/titlepage-attributes.ts b/src/file/document/body/section-properties/title-page/title-page-attributes.ts similarity index 100% rename from src/file/document/body/section-properties/titlepage/titlepage-attributes.ts rename to src/file/document/body/section-properties/title-page/title-page-attributes.ts diff --git a/src/file/document/body/section-properties/titlepage/titlepage.ts b/src/file/document/body/section-properties/title-page/title-page.ts similarity index 100% rename from src/file/document/body/section-properties/titlepage/titlepage.ts rename to src/file/document/body/section-properties/title-page/title-page.ts From 8d35dc1bb061563f3bf746beb80a03c13ff82a61 Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Thu, 17 May 2018 13:32:33 -0600 Subject: [PATCH 5/8] Added tests, renamed pagenumber to page-number --- .../title-page/title-page.spec.ts | 17 +++++++++++++++++ .../section-properties/title-page/title-page.ts | 2 +- .../run/{pagenumber.ts => page-number.ts} | 0 src/file/paragraph/run/run.ts | 2 +- 4 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 src/file/document/body/section-properties/title-page/title-page.spec.ts rename src/file/paragraph/run/{pagenumber.ts => page-number.ts} (100%) diff --git a/src/file/document/body/section-properties/title-page/title-page.spec.ts b/src/file/document/body/section-properties/title-page/title-page.spec.ts new file mode 100644 index 0000000000..75374a22db --- /dev/null +++ b/src/file/document/body/section-properties/title-page/title-page.spec.ts @@ -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" } }); + }); + }); +}); diff --git a/src/file/document/body/section-properties/title-page/title-page.ts b/src/file/document/body/section-properties/title-page/title-page.ts index 361cc039fa..743c6ee489 100644 --- a/src/file/document/body/section-properties/title-page/title-page.ts +++ b/src/file/document/body/section-properties/title-page/title-page.ts @@ -1,5 +1,5 @@ import { XmlComponent } from "file/xml-components"; -import { TitlePageAttributes } from "./titlepage-attributes"; +import { TitlePageAttributes } from "./title-page-attributes"; export class TitlePage extends XmlComponent { constructor() { diff --git a/src/file/paragraph/run/pagenumber.ts b/src/file/paragraph/run/page-number.ts similarity index 100% rename from src/file/paragraph/run/pagenumber.ts rename to src/file/paragraph/run/page-number.ts diff --git a/src/file/paragraph/run/run.ts b/src/file/paragraph/run/run.ts index 508aad9afa..3123f98cd2 100644 --- a/src/file/paragraph/run/run.ts +++ b/src/file/paragraph/run/run.ts @@ -8,7 +8,7 @@ import { SubScript, SuperScript } from "./script"; import { Style } from "./style"; import { Tab } from "./tab"; import { Underline } from "./underline"; -import { Begin, Page, End, Separate } from "./pagenumber"; +import { Begin, Page, End, Separate } from "./page-number"; import { XmlComponent } from "file/xml-components"; From c63a8982e4c045ce7d7cbd5a4586dafb56c59f2f Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Thu, 17 May 2018 19:44:37 -0600 Subject: [PATCH 6/8] Added demo14 to showcase differentFirstPageHeader and pagenumbers --- demo/demo14.js | 23 +++++++++++++++++++++++ demo/demo8.js | 27 ++++++--------------------- 2 files changed, 29 insertions(+), 21 deletions(-) create mode 100644 demo/demo14.js diff --git a/demo/demo14.js b/demo/demo14.js new file mode 100644 index 0000000000..0e3859eadf --- /dev/null +++ b/demo/demo14.js @@ -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!'); diff --git a/demo/demo8.js b/demo/demo8.js index 90213955f2..03ba944473 100644 --- a/demo/demo8.js +++ b/demo/demo8.js @@ -1,28 +1,13 @@ const docx = require('../build'); -var doc = new docx.Document(undefined,{differentFirstPageHeader:true}); +var doc = new docx.Document(); -doc.createParagraph("First Page").pageBreak() -doc.createParagraph("Second Page"); - -var tab = new docx.TextRun().tab() -var pageNumber = new docx.TextRun().pageNumber() - -var pageoneheader = new docx.Paragraph("Running head: My Title").maxRightTabStop(); - -pageoneheader.addRun(tab); -pageoneheader.addRun(pageNumber); -doc.firstPageHeader.addParagraph(pageoneheader); - -var pagetwoheader = new docx.Paragraph("My Title").maxRightTabStop(); - -pagetwoheader.addRun(tab) -pagetwoheader.addRun(pageNumber) -doc.Header.addParagraph(pagetwoheader) -doc.Header = new docx.Paragraph("My Title") +doc.createParagraph("Hello World"); +doc.Header.createParagraph("Header text"); +doc.Footer.createParagraph("Footer text"); var exporter = new docx.LocalPacker(doc); -exporter.pack('Testing'); +exporter.pack('My Document'); -console.log('Document created successfully at project root!'); +console.log('Document created successfully at project root!'); \ No newline at end of file From 7296c9e74489ac9cacbd609477bb6f9e619e134c Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Thu, 17 May 2018 19:51:01 -0600 Subject: [PATCH 7/8] Removed extra empty lines --- src/export/packer/compiler.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/export/packer/compiler.ts b/src/export/packer/compiler.ts index 75357219bc..d99ef1955a 100644 --- a/src/export/packer/compiler.ts +++ b/src/export/packer/compiler.ts @@ -34,16 +34,13 @@ 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)); const xmlContentTypes = xml(this.formatter.format(this.file.ContentTypes)); const xmlAppProperties = xml(this.formatter.format(this.file.AppProperties)); - this.archive.append(xmlDocument, { name: "word/document.xml", }); From 7584671312bb825705628abf490a52e700a197ff Mon Sep 17 00:00:00 2001 From: Tyler Bell Date: Fri, 18 May 2018 09:21:27 -0600 Subject: [PATCH 8/8] Fixed TSLint Errors --- src/export/packer/compiler.ts | 2 +- src/file/content-types/content-types.ts | 2 +- .../header-reference/header-reference.ts | 4 ++-- .../body/section-properties/section-properties.ts | 8 ++++---- .../title-page/title-page-attributes.ts | 2 +- .../body/section-properties/title-page/title-page.ts | 2 +- src/file/file.ts | 5 +---- src/file/paragraph/run/page-number.ts | 10 +++++----- src/file/paragraph/run/run.ts | 2 +- 9 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/export/packer/compiler.ts b/src/export/packer/compiler.ts index d99ef1955a..6ee1665074 100644 --- a/src/export/packer/compiler.ts +++ b/src/export/packer/compiler.ts @@ -68,7 +68,7 @@ export class Compiler { this.archive.append(xmlHeader2, { name: "word/header2.xml", }); - + this.archive.append(xmlFooter, { name: "word/footer1.xml", }); diff --git a/src/file/content-types/content-types.ts b/src/file/content-types/content-types.ts index 64c9db3113..9bb3837cb2 100644 --- a/src/file/content-types/content-types.ts +++ b/src/file/content-types/content-types.ts @@ -24,7 +24,7 @@ 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")); diff --git a/src/file/document/body/section-properties/header-reference/header-reference.ts b/src/file/document/body/section-properties/header-reference/header-reference.ts index 53d75ede28..cd9d8e7349 100644 --- a/src/file/document/body/section-properties/header-reference/header-reference.ts +++ b/src/file/document/body/section-properties/header-reference/header-reference.ts @@ -2,12 +2,12 @@ import { XmlComponent } from "file/xml-components"; import { HeaderReferenceAttributes } from "./header-reference-attributes"; export class HeaderReference extends XmlComponent { - constructor(order, ref_id) { + constructor(order: string, refID: number) { super("w:headerReference"); this.root.push( new HeaderReferenceAttributes({ type: order, - id: `rId${ref_id}`, + id: `rId${refID}`, }), ); } diff --git a/src/file/document/body/section-properties/section-properties.ts b/src/file/document/body/section-properties/section-properties.ts index aea95a0d85..4cd6e35656 100644 --- a/src/file/document/body/section-properties/section-properties.ts +++ b/src/file/document/body/section-properties/section-properties.ts @@ -53,13 +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("default",3)); - + this.root.push(new HeaderReference("default", 3)); + if (mergedOptions.differentFirstPageHeader) { - this.root.push(new HeaderReference("first",5)); + this.root.push(new HeaderReference("first", 5)); this.root.push(new TitlePage()); } - + this.root.push(new FooterReference()); } } diff --git a/src/file/document/body/section-properties/title-page/title-page-attributes.ts b/src/file/document/body/section-properties/title-page/title-page-attributes.ts index 960064ec1f..9022cccf3d 100644 --- a/src/file/document/body/section-properties/title-page/title-page-attributes.ts +++ b/src/file/document/body/section-properties/title-page/title-page-attributes.ts @@ -8,4 +8,4 @@ export class TitlePageAttributes extends XmlAttributeComponent { +class FidCharAttrs extends XmlAttributeComponent<{ type: "begin" | "end" | "separate" }> { protected xmlKeys = { type: "w:fldCharType" }; } @@ -11,7 +11,7 @@ class TextAttributes extends XmlAttributeComponent<{ space: "default" | "preserv export class Begin extends XmlComponent { constructor() { super("w:fldChar"); - this.root.push(new fidCharAttrs({ type: "begin" })); + this.root.push(new FidCharAttrs({ type: "begin" })); } } @@ -26,13 +26,13 @@ export class Page extends XmlComponent { export class Separate extends XmlComponent { constructor() { super("w:fldChar"); - this.root.push(new fidCharAttrs({ type: "separate" })); + this.root.push(new FidCharAttrs({ type: "separate" })); } } export class End extends XmlComponent { constructor() { super("w:fldChar"); - this.root.push(new fidCharAttrs({ type: "end" })); + this.root.push(new FidCharAttrs({ type: "end" })); } -} \ No newline at end of file +} diff --git a/src/file/paragraph/run/run.ts b/src/file/paragraph/run/run.ts index 3123f98cd2..b913e49df4 100644 --- a/src/file/paragraph/run/run.ts +++ b/src/file/paragraph/run/run.ts @@ -2,13 +2,13 @@ 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"; import { Style } from "./style"; import { Tab } from "./tab"; import { Underline } from "./underline"; -import { Begin, Page, End, Separate } from "./page-number"; import { XmlComponent } from "file/xml-components";