2018-04-24 21:12:09 +01:00
|
|
|
import * as JSZip from "jszip";
|
|
|
|
import * as xml from "xml";
|
|
|
|
|
|
|
|
import { File } from "file";
|
|
|
|
import { Formatter } from "../formatter";
|
|
|
|
|
|
|
|
interface IXmlifyedFile {
|
|
|
|
data: string;
|
|
|
|
path: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface IXmlifyedFileMapping {
|
|
|
|
Document: IXmlifyedFile;
|
|
|
|
Styles: IXmlifyedFile;
|
|
|
|
Properties: IXmlifyedFile;
|
|
|
|
Numbering: IXmlifyedFile;
|
|
|
|
Relationships: IXmlifyedFile;
|
|
|
|
FileRelationships: IXmlifyedFile;
|
|
|
|
Header: IXmlifyedFile;
|
|
|
|
Footer: IXmlifyedFile;
|
|
|
|
HeaderRelationships: IXmlifyedFile;
|
|
|
|
FooterRelationships: IXmlifyedFile;
|
|
|
|
ContentTypes: IXmlifyedFile;
|
|
|
|
AppProperties: IXmlifyedFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Compiler {
|
2018-08-10 01:40:29 +01:00
|
|
|
private readonly formatter: Formatter;
|
2018-04-24 21:12:09 +01:00
|
|
|
|
2018-08-10 01:40:29 +01:00
|
|
|
constructor(private readonly file: File) {
|
2018-04-24 21:12:09 +01:00
|
|
|
this.formatter = new Formatter();
|
|
|
|
}
|
|
|
|
|
2018-04-24 22:35:31 +01:00
|
|
|
public async compile(): Promise<JSZip> {
|
2018-04-24 21:12:09 +01:00
|
|
|
const zip = new JSZip();
|
|
|
|
|
|
|
|
const xmlifiedFileMapping = this.xmlifyFile(this.file);
|
|
|
|
|
|
|
|
for (const key in xmlifiedFileMapping) {
|
|
|
|
if (!xmlifiedFileMapping[key]) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const xmlifiedFile = xmlifiedFileMapping[key];
|
|
|
|
|
|
|
|
zip.file(xmlifiedFile.path, xmlifiedFile.data);
|
|
|
|
}
|
|
|
|
|
2018-08-10 01:40:29 +01:00
|
|
|
for (const data of this.file.Media.Array) {
|
|
|
|
const mediaData = data.stream;
|
2018-04-24 22:35:31 +01:00
|
|
|
zip.file(`word/media/${data.fileName}`, mediaData);
|
|
|
|
}
|
2018-04-24 21:12:09 +01:00
|
|
|
|
|
|
|
return zip;
|
|
|
|
}
|
|
|
|
|
|
|
|
private xmlifyFile(file: File): IXmlifyedFileMapping {
|
|
|
|
return {
|
|
|
|
Document: {
|
|
|
|
data: xml(this.formatter.format(file.Document), true),
|
|
|
|
path: "word/document.xml",
|
|
|
|
},
|
|
|
|
Styles: {
|
|
|
|
data: xml(this.formatter.format(file.Styles)),
|
|
|
|
path: "word/styles.xml",
|
|
|
|
},
|
|
|
|
Properties: {
|
|
|
|
data: xml(this.formatter.format(file.CoreProperties), {
|
|
|
|
declaration: {
|
|
|
|
standalone: "yes",
|
|
|
|
encoding: "UTF-8",
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
path: "docProps/core.xml",
|
|
|
|
},
|
|
|
|
Numbering: {
|
|
|
|
data: xml(this.formatter.format(file.Numbering)),
|
|
|
|
path: "word/numbering.xml",
|
|
|
|
},
|
|
|
|
Relationships: {
|
|
|
|
data: xml(this.formatter.format(file.DocumentRelationships)),
|
|
|
|
path: "word/_rels/document.xml.rels",
|
|
|
|
},
|
|
|
|
FileRelationships: {
|
|
|
|
data: xml(this.formatter.format(file.FileRelationships)),
|
|
|
|
path: "_rels/.rels",
|
|
|
|
},
|
|
|
|
Header: {
|
|
|
|
data: xml(this.formatter.format(file.Header.Header)),
|
|
|
|
path: "word/header1.xml",
|
|
|
|
},
|
|
|
|
Footer: {
|
|
|
|
data: xml(this.formatter.format(file.Footer.Footer)),
|
|
|
|
path: "word/footer1.xml",
|
|
|
|
},
|
|
|
|
HeaderRelationships: {
|
|
|
|
data: xml(this.formatter.format(file.Header.Relationships)),
|
|
|
|
path: "word/_rels/header1.xml.rels",
|
|
|
|
},
|
|
|
|
FooterRelationships: {
|
|
|
|
data: xml(this.formatter.format(file.Footer.Relationships)),
|
|
|
|
path: "word/_rels/footer1.xml.rels",
|
|
|
|
},
|
|
|
|
ContentTypes: {
|
|
|
|
data: xml(this.formatter.format(file.ContentTypes)),
|
|
|
|
path: "[Content_Types].xml",
|
|
|
|
},
|
|
|
|
AppProperties: {
|
|
|
|
data: xml(this.formatter.format(file.AppProperties)),
|
|
|
|
path: "docProps/app.xml",
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|