Files
docx-js/src/export/packer/compiler.ts

110 lines
3.4 KiB
TypeScript
Raw Normal View History

2017-12-06 01:03:14 +00:00
import * as archiver from "archiver";
import * as express from "express";
2018-02-23 19:20:28 -05:00
import { Writable } from "stream";
2017-12-06 01:03:14 +00:00
import * as xml from "xml";
import { File } from "file";
2017-12-06 01:03:14 +00:00
import { Formatter } from "../formatter";
export class Compiler {
protected archive: archiver.Archiver;
private formatter: Formatter;
2017-12-15 02:15:44 +00:00
constructor(private file: File) {
2017-12-06 01:03:14 +00:00
this.formatter = new Formatter();
this.archive = archiver.create("zip", {});
this.archive.on("error", (err) => {
throw err;
});
}
2018-02-23 19:20:28 -05:00
public async compile(output: Writable | express.Response): Promise<void> {
2017-12-06 01:03:14 +00:00
this.archive.pipe(output);
2018-01-16 00:43:00 +00:00
const xmlDocument = xml(this.formatter.format(this.file.Document), true);
2017-12-15 02:15:44 +00:00
const xmlStyles = xml(this.formatter.format(this.file.Styles));
2018-02-04 01:43:03 +00:00
const xmlProperties = xml(this.formatter.format(this.file.CoreProperties), {
2017-12-06 01:03:14 +00:00
declaration: {
standalone: "yes",
encoding: "UTF-8",
},
});
2017-12-15 02:15:44 +00:00
const xmlNumbering = xml(this.formatter.format(this.file.Numbering));
2018-02-04 00:58:34 +00:00
const xmlRelationships = xml(this.formatter.format(this.file.DocumentRelationships));
const xmlFileRelationships = xml(this.formatter.format(this.file.FileRelationships));
2018-02-08 00:12:59 +00:00
const xmlContentTypes = xml(this.formatter.format(this.file.ContentTypes));
const xmlAppProperties = xml(this.formatter.format(this.file.AppProperties));
2017-12-06 01:03:14 +00:00
this.archive.append(xmlDocument, {
name: "word/document.xml",
});
this.archive.append(xmlStyles, {
name: "word/styles.xml",
});
this.archive.append(xmlProperties, {
name: "docProps/core.xml",
});
2018-02-08 00:12:59 +00:00
this.archive.append(xmlAppProperties, {
name: "docProps/app.xml",
});
2017-12-06 01:03:14 +00:00
this.archive.append(xmlNumbering, {
name: "word/numbering.xml",
});
// headers
for (let i = 0; i < this.file.Headers.length; i++) {
const element = this.file.Headers[i];
this.archive.append(xml(this.formatter.format(element.Header)), {
name: `word/header${i + 1}.xml`,
});
2018-05-18 09:21:27 -06:00
this.archive.append(xml(this.formatter.format(element.Relationships)), {
name: `word/_rels/header${i + 1}.xml.rels`,
});
}
2018-01-29 21:53:22 +00:00
// footers
for (let i = 0; i < this.file.Footers.length; i++) {
const element = this.file.Footers[i];
this.archive.append(xml(this.formatter.format(element.Footer)), {
name: `word/footer${i + 1}.xml`,
});
2018-01-10 00:29:17 +00:00
this.archive.append(xml(this.formatter.format(element.Relationships)), {
name: `word/_rels/footer${i + 1}.xml.rels`,
});
}
this.archive.append(xmlRelationships, {
name: "word/_rels/document.xml.rels",
});
2018-02-08 00:12:59 +00:00
this.archive.append(xmlContentTypes, {
name: "[Content_Types].xml",
});
2018-02-04 00:58:34 +00:00
this.archive.append(xmlFileRelationships, {
name: "_rels/.rels",
2018-02-03 20:56:20 +00:00
});
2017-12-15 02:15:44 +00:00
for (const data of this.file.Media.array) {
2017-12-06 01:03:14 +00:00
this.archive.append(data.stream, {
2018-01-22 00:53:22 +00:00
name: `word/media/${data.fileName}`,
2017-12-06 01:03:14 +00:00
});
}
this.archive.finalize();
return new Promise<void>((resolve) => {
output.on("close", () => {
resolve();
});
});
}
}