Add next gen compiler using JSZip
This commit is contained in:
16
demo/demo13.js
Normal file
16
demo/demo13.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
const docx = require('../build');
|
||||||
|
|
||||||
|
var doc = new docx.Document();
|
||||||
|
|
||||||
|
var paragraph = new docx.Paragraph("Hello World");
|
||||||
|
var institutionText = new docx.TextRun("University College London").bold();
|
||||||
|
var dateText = new docx.TextRun("5th Dec 2015").tab().bold();
|
||||||
|
paragraph.addRun(institutionText);
|
||||||
|
paragraph.addRun(dateText);
|
||||||
|
|
||||||
|
doc.addParagraph(paragraph);
|
||||||
|
|
||||||
|
var exporter = new docx.LocalPacker(doc);
|
||||||
|
exporter.packPdf('My Document');
|
||||||
|
|
||||||
|
console.log('Document created successfully at project root!');
|
@ -43,9 +43,11 @@
|
|||||||
"@types/archiver": "^2.1.0",
|
"@types/archiver": "^2.1.0",
|
||||||
"@types/express": "^4.0.35",
|
"@types/express": "^4.0.35",
|
||||||
"@types/image-size": "0.0.29",
|
"@types/image-size": "0.0.29",
|
||||||
|
"@types/jszip": "^3.1.3",
|
||||||
"@types/request-promise": "^4.1.41",
|
"@types/request-promise": "^4.1.41",
|
||||||
"archiver": "^2.1.1",
|
"archiver": "^2.1.1",
|
||||||
"image-size": "^0.6.2",
|
"image-size": "^0.6.2",
|
||||||
|
"jszip": "^3.1.5",
|
||||||
"request": "^2.83.0",
|
"request": "^2.83.0",
|
||||||
"request-promise": "^4.2.2",
|
"request-promise": "^4.2.2",
|
||||||
"xml": "^1.0.1"
|
"xml": "^1.0.1"
|
||||||
|
@ -3,12 +3,11 @@ import * as os from "os";
|
|||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
import { File } from "../../file";
|
import { File } from "../../file";
|
||||||
import { Compiler } from "./compiler";
|
import { Compiler } from "./next-compiler";
|
||||||
import { IPacker } from "./packer";
|
import { IPacker } from "./packer";
|
||||||
import { PdfConvertWrapper } from "./pdf-convert-wrapper";
|
import { PdfConvertWrapper } from "./pdf-convert-wrapper";
|
||||||
|
|
||||||
export class LocalPacker implements IPacker {
|
export class LocalPacker implements IPacker {
|
||||||
private stream: fs.WriteStream;
|
|
||||||
private readonly pdfConverter: PdfConvertWrapper;
|
private readonly pdfConverter: PdfConvertWrapper;
|
||||||
private readonly packer: Compiler;
|
private readonly packer: Compiler;
|
||||||
|
|
||||||
@ -20,8 +19,8 @@ export class LocalPacker implements IPacker {
|
|||||||
public async pack(filePath: string): Promise<void> {
|
public async pack(filePath: string): Promise<void> {
|
||||||
filePath = filePath.replace(/.docx$/, "");
|
filePath = filePath.replace(/.docx$/, "");
|
||||||
|
|
||||||
this.stream = fs.createWriteStream(`${filePath}.docx`);
|
const zipData = await this.packer.compile().generateAsync({ type: "base64" }) as string;
|
||||||
await this.packer.compile(this.stream);
|
await this.writeToFile(`${filePath}.docx`, zipData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async packPdf(filePath: string): Promise<void> {
|
public async packPdf(filePath: string): Promise<void> {
|
||||||
@ -29,19 +28,27 @@ export class LocalPacker implements IPacker {
|
|||||||
|
|
||||||
const fileName = path.basename(filePath, path.extname(filePath));
|
const fileName = path.basename(filePath, path.extname(filePath));
|
||||||
const tempPath = path.join(os.tmpdir(), `${fileName}.docx`);
|
const tempPath = path.join(os.tmpdir(), `${fileName}.docx`);
|
||||||
this.stream = fs.createWriteStream(tempPath);
|
|
||||||
await this.packer.compile(this.stream);
|
const zipData = await this.packer.compile().generateAsync({ type: "base64" }) as string;
|
||||||
|
await this.writeToFile(tempPath, zipData);
|
||||||
|
|
||||||
const text = await this.pdfConverter.convert(tempPath);
|
const text = await this.pdfConverter.convert(tempPath);
|
||||||
// const writeFile = util.promisify(fs.writeFile); --use this in future, in 3 years time. Only in node 8
|
// const writeFile = util.promisify(fs.writeFile); --use this in future, in 3 years time. Only in node 8
|
||||||
// return writeFile(`${filePath}.pdf`, text);
|
// return writeFile(`${filePath}.pdf`, text);
|
||||||
return new Promise<void>((resolve, reject) => {
|
|
||||||
fs.writeFile(`${filePath}.pdf`, text, (err) => {
|
await this.writeToFile(`${filePath}.pdf`, text);
|
||||||
if (err) {
|
}
|
||||||
reject(err);
|
|
||||||
return;
|
private writeToFile(filePath: string, data: string): Promise<void> {
|
||||||
}
|
const file = fs.createWriteStream(filePath);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
file.write(data, "base64");
|
||||||
|
file.end();
|
||||||
|
file.on("finish", () => {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
|
file.on("error", reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
117
src/export/packer/next-compiler.ts
Normal file
117
src/export/packer/next-compiler.ts
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
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 {
|
||||||
|
private formatter: Formatter;
|
||||||
|
|
||||||
|
constructor(private file: File) {
|
||||||
|
this.formatter = new Formatter();
|
||||||
|
}
|
||||||
|
|
||||||
|
public compile(): JSZip {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for (const data of file.Media.array) {
|
||||||
|
// this.archive.append(data.stream, {
|
||||||
|
// name: `word/media/${data.fileName}`,
|
||||||
|
// });
|
||||||
|
|
||||||
|
// zip.file(`word/media/${data.fileName}`, )
|
||||||
|
// }
|
||||||
|
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user