Merge pull request #56 from dolanmiu/feat/header

Feat/header
This commit is contained in:
Dolan
2018-01-29 03:00:07 +00:00
committed by GitHub
22 changed files with 191 additions and 51 deletions

13
.vscode/settings.json vendored
View File

@ -1,16 +1,9 @@
{
"cSpell.words": [
"clippy",
"docx",
"dolan",
"miu",
"officegen",
"typedoc"
],
"cSpell.words": ["clippy", "docx", "dolan", "miu", "officegen", "typedoc"],
"prettier.trailingComma": "all",
"prettier.printWidth": 140,
"editor.formatOnSave": true,
"editor.formatOnSave": false,
"prettier.tabWidth": 4,
"prettier.arrowParens": "always",
"prettier.bracketSpacing": true,
"prettier.bracketSpacing": true
}

12
demo/demo8.js Normal file
View File

@ -0,0 +1,12 @@
const docx = require('../build');
var doc = new docx.File();
doc.createParagraph("Hello World");
doc.Header.createParagraph("Header text");
var exporter = new docx.LocalPacker(doc);
exporter.pack('My Document');
console.log('Document created succesfully at project root!');

View File

@ -42,6 +42,7 @@ export class Compiler {
});
const xmlNumbering = xml(this.formatter.format(this.file.Numbering));
const xmlRelationships = xml(this.formatter.format(this.file.Relationships));
const xmlHeader = xml(this.formatter.format(this.file.Header));
this.archive.append(xmlDocument, {
name: "word/document.xml",
@ -59,6 +60,10 @@ export class Compiler {
name: "word/numbering.xml",
});
this.archive.append(xmlHeader, {
name: "word/header1.xml",
});
this.archive.append(xmlRelationships, {
name: "word/_rels/document.xml.rels",
});

View File

@ -5,10 +5,9 @@ import { Compiler } from "./compiler";
import { IPacker } from "./packer";
export class ExpressPacker implements IPacker {
private res: express.Response;
private packer: Compiler;
private readonly packer: Compiler;
constructor(file: File, res: express.Response) {
constructor(file: File, private readonly res: express.Response) {
this.packer = new Compiler(file);
this.res = res;

View File

@ -9,8 +9,8 @@ import { PdfConvertWrapper } from "./pdf-convert-wrapper";
export class LocalPacker implements IPacker {
private stream: fs.WriteStream;
private pdfConverter: PdfConvertWrapper;
private packer: Compiler;
private readonly pdfConverter: PdfConvertWrapper;
private readonly packer: Compiler;
constructor(file: File) {
this.pdfConverter = new PdfConvertWrapper();

View File

@ -0,0 +1,13 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IHeaderReferenceAttributes {
type: string;
id: string;
}
export class HeaderReferenceAttributes extends XmlAttributeComponent<IHeaderReferenceAttributes> {
protected xmlKeys = {
type: "w:type",
id: "r:id",
};
}

View File

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

View File

@ -1,13 +1,14 @@
// http://officeopenxml.com/WPsection.php
import { IColumnsAttributes } from "file/document/body/section-properties/columns/columns-attributes";
import { IPageMarginAttributes } from "file/document/body/section-properties/page-margin/page-margin-attributes";
import { IPageSizeAttributes } from "file/document/body/section-properties/page-size/page-size-attributes";
import { XmlComponent } from "file/xml-components";
import { Columns } from "./columns/columns";
import { IColumnsAttributes } from "./columns/columns-attributes";
import { DocumentGrid } from "./doc-grid/doc-grid";
import { IDocGridAttributesProperties } from "./doc-grid/doc-grid-attributes";
import { HeaderReference } from "./header-reference/header-reference";
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";
export type SectionPropertiesOptions = IPageSizeAttributes & IPageMarginAttributes & IColumnsAttributes & IDocGridAttributesProperties;
@ -49,5 +50,6 @@ export class SectionProperties extends XmlComponent {
);
this.root.push(new Columns(mergedOptions.space));
this.root.push(new DocumentGrid(mergedOptions.linePitch));
this.root.push(new HeaderReference());
}
}

View File

@ -8,7 +8,7 @@ import { SectionPropertiesOptions } from "./body/section-properties/section-prop
import { DocumentAttributes } from "./document-attributes";
export class Document extends XmlComponent {
private body: Body;
private readonly body: Body;
constructor(sectionPropertiesOptions?: SectionPropertiesOptions) {
super("w:document");

View File

@ -1,21 +1,23 @@
import { Relationships } from "file/relationships";
import { Document } from "./document";
import { SectionPropertiesOptions } from "./document/body/section-properties/section-properties";
import { Header } from "./header/header";
import { Media } from "./media";
import { Numbering } from "./numbering";
import { Paragraph } from "./paragraph";
import { IPropertiesOptions, Properties } from "./properties";
import { Relationships } from "./relationships";
import { Styles } from "./styles";
import { DefaultStylesFactory } from "./styles/factory";
import { Table } from "./table";
export class File {
private document: Document;
private styles: Styles;
private properties: Properties;
private numbering: Numbering;
private media: Media;
private relationships: Relationships;
private readonly document: Document;
private readonly styles: Styles;
private readonly properties: Properties;
private readonly numbering: Numbering;
private readonly media: Media;
private readonly relationships: Relationships;
private readonly header: Header;
constructor(options?: IPropertiesOptions, sectionPropertiesOptions?: SectionPropertiesOptions) {
this.document = new Document(sectionPropertiesOptions);
@ -32,8 +34,9 @@ export class File {
this.properties = new Properties(options);
this.numbering = new Numbering();
this.media = new Media();
this.relationships = new Relationships();
this.media = new Media();
this.header = new Header();
}
public addParagraph(paragraph: Paragraph): void {
@ -41,7 +44,7 @@ export class File {
}
public createParagraph(text?: string): Paragraph {
return this.document.createParagraph();
return this.document.createParagraph(text);
}
public addTable(table: Table): void {
@ -53,7 +56,7 @@ export class File {
}
public createImage(image: string): void {
const mediaData = this.media.addMedia(image);
const mediaData = this.media.addMedia(image, this.relationships.RelationshipCount);
this.relationships.createRelationship(
mediaData.referenceId,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
@ -85,4 +88,8 @@ export class File {
public get Relationships(): Relationships {
return this.relationships;
}
public get Header(): Header {
return this.header;
}
}

View File

@ -0,0 +1,31 @@
import { XmlAttributeComponent } from "file/xml-components";
export interface IHeaderAttributesProperties {
o?: string;
r?: string;
v?: string;
w?: string;
w10?: string;
wp?: string;
wps?: string;
wpg?: string;
mc?: string;
wp14?: string;
w14?: string;
}
export class HeaderAttributes extends XmlAttributeComponent<IHeaderAttributesProperties> {
protected xmlKeys = {
o: "xmlns:o",
r: "xmlns:r",
v: "xmlns:v",
w: "xmlns:w",
w10: "xmlns:w10",
wp: "xmlns:wp",
wps: "xmlns:wps",
wpg: "xmlns:wpg",
mc: "xmlns:mc",
wp14: "xmlns:wp14",
w14: "xmlns:w14",
};
}

61
src/file/header/header.ts Normal file
View File

@ -0,0 +1,61 @@
// 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 Header extends XmlComponent {
constructor() {
super("w:hdr");
this.root.push(
new HeaderAttributes({
o: "urn:schemas-microsoft-com:office:office",
r: "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
v: "urn:schemas-microsoft-com:vml",
w: "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
w10: "urn:schemas-microsoft-com:office:word",
wp: "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
wps: "http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
wpg: "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
mc: "http://schemas.openxmlformats.org/markup-compatibility/2006",
wp14: "http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
w14: "http://schemas.microsoft.com/office/word/2010/wordml",
}),
);
}
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);
}
public createDrawing(imageData: IMediaData): void {
this.addDrawing(imageData);
return;
}
}

View File

@ -5,7 +5,7 @@ import * as path from "path";
import { IMediaData } from "./data";
export class Media {
private map: Map<string, IMediaData>;
private readonly map: Map<string, IMediaData>;
constructor() {
this.map = new Map<string, IMediaData>();
@ -21,12 +21,12 @@ export class Media {
return data;
}
public addMedia(filePath: string): IMediaData {
public addMedia(filePath: string, relationshipsCount: number): IMediaData {
const key = path.basename(filePath);
const dimensions = sizeOf(filePath);
const imageData = {
referenceId: this.map.size + 3,
referenceId: this.map.size + relationshipsCount,
stream: fs.createReadStream(filePath),
path: filePath,
fileName: key,

View File

@ -61,8 +61,8 @@ class LevelJc extends XmlComponent {
}
export class LevelBase extends XmlComponent {
private paragraphProperties: ParagraphProperties;
private runProperties: RunProperties;
private readonly paragraphProperties: ParagraphProperties;
private readonly runProperties: RunProperties;
constructor(level: number, start?: number, numberFormat?: string, levelText?: string, lvlJc?: string) {
super("w:lvl");

View File

@ -46,16 +46,14 @@ class LevelOverrideAttributes extends XmlAttributeComponent<{ ilvl: number }> {
}
export class LevelOverride extends XmlComponent {
private levelNum: number;
private lvl?: LevelForOverride;
constructor(levelNum: number, start?: number) {
constructor(private readonly levelNum: number, start?: number) {
super("w:lvlOverride");
this.root.push(new LevelOverrideAttributes({ ilvl: levelNum }));
if (start !== undefined) {
this.root.push(new StartOverride(start));
}
this.levelNum = levelNum;
}
get level(): LevelForOverride {

View File

@ -8,7 +8,8 @@ export type RelationshipType =
| "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
| "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"
| "http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings"
| "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering";
| "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering"
| "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header";
export class Relationship extends XmlComponent {
constructor(id: string, type: RelationshipType, target: string) {

View File

@ -13,6 +13,7 @@ export class Relationships extends XmlComponent {
this.createRelationship(1, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles", "styles.xml");
this.createRelationship(2, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering", "numbering.xml");
this.createRelationship(3, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header", "header1.xml");
}
public addRelationship(relationship: Relationship): void {
@ -25,4 +26,8 @@ export class Relationships extends XmlComponent {
return relationship;
}
public get RelationshipCount(): number {
return this.root.length - 1;
}
}

View File

@ -3,8 +3,8 @@ import { ParagraphPropertiesDefaults } from "./paragraph-properties";
import { RunPropertiesDefaults } from "./run-properties";
export class DocumentDefaults extends XmlComponent {
private runPropertiesDefaults: RunPropertiesDefaults;
private paragraphPropertiesDefaults: ParagraphPropertiesDefaults;
private readonly runPropertiesDefaults: RunPropertiesDefaults;
private readonly paragraphPropertiesDefaults: ParagraphPropertiesDefaults;
constructor() {
super("w:docDefaults");

View File

@ -4,7 +4,7 @@ import { RunProperties } from "../../paragraph/run/properties";
import { RunFonts } from "../../paragraph/run/run-fonts";
export class RunPropertiesDefaults extends XmlComponent {
private properties: RunProperties;
private readonly properties: RunProperties;
constructor() {
super("w:rPrDefault");

View File

@ -36,8 +36,8 @@ export class Style extends XmlComponent {
}
export class ParagraphStyle extends Style {
private paragraphProperties: paragraph.ParagraphProperties;
private runProperties: RunProperties;
private readonly paragraphProperties: paragraph.ParagraphProperties;
private readonly runProperties: RunProperties;
constructor(styleId: string, name?: string) {
super({ type: "paragraph", styleId: styleId }, name);

View File

@ -5,9 +5,9 @@ import { TableGrid } from "./grid";
import { TableProperties, WidthTypes } from "./properties";
export class Table extends XmlComponent {
private properties: TableProperties;
private rows: TableRow[];
private grid: TableGrid;
private readonly properties: TableProperties;
private readonly rows: TableRow[];
private readonly grid: TableGrid;
constructor(rows: number, cols: number) {
super("w:tbl");
@ -63,14 +63,12 @@ export class Table extends XmlComponent {
}
export class TableRow extends XmlComponent {
private properties: TableRowProperties;
private cells: TableCell[];
private readonly properties: TableRowProperties;
constructor(cells: TableCell[]) {
constructor(private readonly cells: TableCell[]) {
super("w:tr");
this.properties = new TableRowProperties();
this.root.push(this.properties);
this.cells = cells;
cells.forEach((c) => this.root.push(c));
}
@ -86,7 +84,7 @@ export class TableRowProperties extends XmlComponent {
}
export class TableCell extends XmlComponent {
private properties: TableCellProperties;
private readonly properties: TableCellProperties;
constructor() {
super("w:tc");

View File

@ -8,6 +8,7 @@
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />
<Default Extension="xml" ContentType="application/xml" />
<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml" />
<Override PartName="/word/header1.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml"/>
<Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml" />
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml" />
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" />