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/express": "^4.0.35",
|
||||
"@types/image-size": "0.0.29",
|
||||
"@types/jszip": "^3.1.3",
|
||||
"@types/request-promise": "^4.1.41",
|
||||
"archiver": "^2.1.1",
|
||||
"image-size": "^0.6.2",
|
||||
"jszip": "^3.1.5",
|
||||
"request": "^2.83.0",
|
||||
"request-promise": "^4.2.2",
|
||||
"xml": "^1.0.1"
|
||||
|
@ -3,12 +3,11 @@ import * as os from "os";
|
||||
import * as path from "path";
|
||||
|
||||
import { File } from "../../file";
|
||||
import { Compiler } from "./compiler";
|
||||
import { Compiler } from "./next-compiler";
|
||||
import { IPacker } from "./packer";
|
||||
import { PdfConvertWrapper } from "./pdf-convert-wrapper";
|
||||
|
||||
export class LocalPacker implements IPacker {
|
||||
private stream: fs.WriteStream;
|
||||
private readonly pdfConverter: PdfConvertWrapper;
|
||||
private readonly packer: Compiler;
|
||||
|
||||
@ -20,8 +19,8 @@ export class LocalPacker implements IPacker {
|
||||
public async pack(filePath: string): Promise<void> {
|
||||
filePath = filePath.replace(/.docx$/, "");
|
||||
|
||||
this.stream = fs.createWriteStream(`${filePath}.docx`);
|
||||
await this.packer.compile(this.stream);
|
||||
const zipData = await this.packer.compile().generateAsync({ type: "base64" }) as string;
|
||||
await this.writeToFile(`${filePath}.docx`, zipData);
|
||||
}
|
||||
|
||||
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 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 writeFile = util.promisify(fs.writeFile); --use this in future, in 3 years time. Only in node 8
|
||||
// return writeFile(`${filePath}.pdf`, text);
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
fs.writeFile(`${filePath}.pdf`, text, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
|
||||
await this.writeToFile(`${filePath}.pdf`, text);
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
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