From a0e00b8eff8c211e75d4433ea9000a38a5c249aa Mon Sep 17 00:00:00 2001 From: Igor Bulovski Date: Fri, 23 Mar 2018 12:18:31 +0100 Subject: [PATCH] (styles): add support to provide external styles (as complete file content) --- package.json | 1 + src/export/packer/compiler.spec.ts | 65 ++++++++++++++++++++++++++++++ src/export/packer/compiler.ts | 11 ++++- src/file/file.ts | 9 +++++ 4 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/export/packer/compiler.spec.ts diff --git a/package.json b/package.json index eab1220339..e381d6b8ab 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "awesome-typescript-loader": "^3.4.1", "chai": "^3.5.0", "glob": "^7.1.2", + "jszip": "^3.1.5", "mocha": "^3.2.0", "mocha-webpack": "^1.0.1", "prettier": "^1.10.2", diff --git a/src/export/packer/compiler.spec.ts b/src/export/packer/compiler.spec.ts new file mode 100644 index 0000000000..dcdbb2afc6 --- /dev/null +++ b/src/export/packer/compiler.spec.ts @@ -0,0 +1,65 @@ +/* tslint:disable:typedef space-before-function-paren */ +import * as fs from "fs"; +import * as os from 'os'; +import { expect } from "chai"; + +import { File, Paragraph } from "../../file"; +import {Compiler} from './compiler'; +import * as jszip from 'jszip'; + +async function getDocxXmlFileContent(filePath: string, xmlFileName: string): Promise { + let zipFile = fs.readFileSync(filePath); + const zipData = await jszip.loadAsync(zipFile).then(zip => zip); + return zipData.files[xmlFileName].async('text'); +} + +describe("compiler", () => { + let compiler: Compiler; + let file: File; + let externalStyles: string; + + beforeEach(() => { + file = new File({ + creator: "Dolan Miu", + revision: "1", + lastModifiedBy: "Dolan Miu", + }); + const paragraph = new Paragraph("test text"); + const heading = new Paragraph("Hello world").heading1(); + file.addParagraph(new Paragraph("title").title()); + file.addParagraph(heading); + file.addParagraph(new Paragraph("heading 2").heading2()); + file.addParagraph(paragraph); + + file.Styles.createParagraphStyle("testStyle").basedOn("Normal").bold(); + + externalStyles = "Some external styles"; + file.setExternalStyles(externalStyles); + + compiler = new Compiler(file); + }); + + describe("#compile()", () => { + + it("should use document styles when they are no external styles provided", async function() { + file.setExternalStyles(''); + const filePath = `${os.tmpdir()}/test-compile.zip`; + let stream = fs.createWriteStream(filePath); + + await compiler.compile(stream); + + const styles = await getDocxXmlFileContent(filePath, 'word/styles.xml') + expect(styles).not.to.equal(externalStyles); + }); + + it("should use provided external styles", async function() { + const filePath = `${os.tmpdir()}/test-compile.zip`; + let stream = fs.createWriteStream(filePath); + + await compiler.compile(stream); + + const styles = await getDocxXmlFileContent(filePath, 'word/styles.xml') + expect(styles).to.equal(externalStyles); + }); + }); +}); diff --git a/src/export/packer/compiler.ts b/src/export/packer/compiler.ts index 44c7817249..935c0a354b 100644 --- a/src/export/packer/compiler.ts +++ b/src/export/packer/compiler.ts @@ -23,7 +23,7 @@ export class Compiler { this.archive.pipe(output); const xmlDocument = xml(this.formatter.format(this.file.Document), true); - const xmlStyles = xml(this.formatter.format(this.file.Styles)); + const xmlStyles = this.resolveStyles(); const xmlProperties = xml(this.formatter.format(this.file.CoreProperties), { declaration: { standalone: "yes", @@ -102,4 +102,13 @@ export class Compiler { }); }); } + + private resolveStyles(): string { + if (this.file.ExternalStyles) { + return this.file.ExternalStyles; + } else { + return xml(this.formatter.format(this.file.Styles)); + } + + } } diff --git a/src/file/file.ts b/src/file/file.ts index 81cc8405fb..f3aab5d24f 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -25,6 +25,8 @@ export class File { private readonly footerWrapper: FooterWrapper; private readonly contentTypes: ContentTypes; private readonly appProperties: AppProperties; + private externalStyles: string; + constructor(options?: IPropertiesOptions, sectionPropertiesOptions?: SectionPropertiesOptions) { this.document = new Document(sectionPropertiesOptions); @@ -111,6 +113,10 @@ export class File { this.document.createDrawing(mediaData); } + public setExternalStyles(styles: string): void { + this.externalStyles = styles; + } + public get Document(): Document { return this.document; } @@ -154,4 +160,7 @@ export class File { public get AppProperties(): AppProperties { return this.appProperties; } + public get ExternalStyles(): string { + return this.externalStyles; + } }