diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..52cf4e6158 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Program", + "program": "${workspaceFolder}/demo/importDemo.js", + // "preLaunchTask": "tsc: build - tsconfig.json", + "outFiles": [ + "${workspaceFolder}/build/**/*.js" + ], + "sourceMaps": true, + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index f144f59202..901803d9af 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,6 @@ "editor.formatOnSave": false, "prettier.tabWidth": 4, "prettier.arrowParens": "always", - "prettier.bracketSpacing": true + "prettier.bracketSpacing": true, + "git.ignoreLimitWarning": true } diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000000..2488a642fd --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,24 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "type": "typescript", + "tsconfig": "tsconfig.json", + "option": "watch", + "problemMatcher": [ + "$tsc-watch" + ] + }, + { + "type": "npm", + "script": "ts-node", + "problemMatcher": [], + "group": { + "kind": "build", + "isDefault": true + } + } + ] +} \ No newline at end of file diff --git a/MyDocument.docx b/MyDocument.docx new file mode 100644 index 0000000000..3bc32bccfa Binary files /dev/null and b/MyDocument.docx differ diff --git a/demo/importDemo.js b/demo/importDemo.js new file mode 100644 index 0000000000..c40eb0a6ae --- /dev/null +++ b/demo/importDemo.js @@ -0,0 +1,13 @@ +"use strict"; +exports.__esModule = true; +var build_1 = require("../build"); +var fs = require("fs"); +var importDocx = new build_1.ImportDocx(); +fs.readFile("./src/import/template.dotx", function (err, data) { + if (err) { + console.log(err); + } + else { + importDocx.read(data); + } +}); diff --git a/demo/importDemo.ts b/demo/importDemo.ts new file mode 100644 index 0000000000..42fcf2a1ea --- /dev/null +++ b/demo/importDemo.ts @@ -0,0 +1,28 @@ +import { Document, Packer, Paragraph, ImportDocx } from "../build"; +import * as fs from "fs"; + +console.log(process.cwd()); + +let importDocx = new ImportDocx(); +fs.readFile("./src/importDocx/simple.dotx", (err, data) => { + if (err) { + console.log(err); + } + else { + importDocx.read(data).then(xmlComp => { + console.log(xmlComp); + const doc = new Document({templateHeader : xmlComp}); + // const doc = new Document(); + const paragraph = new Paragraph("Hello World"); + doc.addParagraph(paragraph); + + // console.log(JSON.stringify(xmlComp, null, 2)); + const packer = new Packer(); + + packer.toBuffer(doc).then((buffer) => { + fs.writeFileSync("MyDocument.docx", buffer); + }); + + }); + } +}); \ No newline at end of file diff --git a/package.json b/package.json index 330ad72bac..8508754bec 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "types": "./build/index.d.ts", "dependencies": { "@types/image-size": "0.0.29", - "@types/jszip": "^3.1.3", + "@types/jszip": "^3.1.4", "fast-xml-parser": "^3.3.6", "image-size": "^0.6.2", "jszip": "^3.1.5", diff --git a/src/file/core-properties/properties.ts b/src/file/core-properties/properties.ts index aa9d3aec51..a5a239635d 100644 --- a/src/file/core-properties/properties.ts +++ b/src/file/core-properties/properties.ts @@ -11,6 +11,8 @@ export interface IPropertiesOptions { lastModifiedBy?: string; revision?: string; externalStyles?: string; + + templateHeader? : XmlComponent; } export class CoreProperties extends XmlComponent { diff --git a/src/file/file.ts b/src/file/file.ts index 472baf28b5..2700c226b2 100644 --- a/src/file/file.ts +++ b/src/file/file.ts @@ -14,6 +14,7 @@ import { Styles } from "./styles"; import { ExternalStylesFactory } from "./styles/external-styles-factory"; import { DefaultStylesFactory } from "./styles/factory"; import { Table } from "./table"; +import { XmlComponent } from "./xml-components"; export class File { private readonly document: Document; @@ -71,7 +72,7 @@ export class File { ); this.media = new Media(); - const header = this.createHeader(); + const header = this.createHeader(options.templateHeader); const footer = this.createFooter(); this.fileRelationships = new Relationships(); @@ -169,8 +170,10 @@ export class File { this.footNotes.createFootNote(paragraph); } - public createHeader(): HeaderWrapper { - const header = new HeaderWrapper(this.media, this.currentRelationshipId++); + public createHeader(templateHeader? : XmlComponent): HeaderWrapper { + const header = new HeaderWrapper(this.media, this.currentRelationshipId++, templateHeader); + console.log('\n\n-------\n\n'); + console.log('header', JSON.stringify(header.Header, null, 2)); this.headerWrapper.push(header); this.docRelationships.createRelationship( header.Header.ReferenceId, diff --git a/src/file/header-wrapper.ts b/src/file/header-wrapper.ts index 79a216610a..1ba399aeca 100644 --- a/src/file/header-wrapper.ts +++ b/src/file/header-wrapper.ts @@ -5,12 +5,13 @@ import { ImageParagraph, Paragraph } from "./paragraph"; import { Relationships } from "./relationships"; import { Table } from "./table"; + export class HeaderWrapper { private readonly header: Header; private readonly relationships: Relationships; - constructor(private readonly media: Media, referenceId: number) { - this.header = new Header(referenceId); + constructor(private readonly media: Media, referenceId: number, initContent? : XmlComponent) { + this.header = new Header(referenceId, initContent); this.relationships = new Relationships(); } diff --git a/src/file/header/header.ts b/src/file/header/header.ts index be1708658f..5bf7dc9b66 100644 --- a/src/file/header/header.ts +++ b/src/file/header/header.ts @@ -7,10 +7,11 @@ import { HeaderAttributes } from "./header-attributes"; export class Header extends XmlComponent { private readonly refId: number; - constructor(referenceNumber: number) { - super("w:hdr"); + constructor(referenceNumber: number, initContent? : XmlComponent) { + super("w:hdr", initContent); this.refId = referenceNumber; + this.root.push( new HeaderAttributes({ wpc: "http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas", diff --git a/src/file/xml-components/xml-component.ts b/src/file/xml-components/xml-component.ts index 0ed604e9ee..92321b9ccb 100644 --- a/src/file/xml-components/xml-component.ts +++ b/src/file/xml-components/xml-component.ts @@ -3,11 +3,17 @@ import { IXmlableObject } from "./xmlable-object"; export { BaseXmlComponent }; export abstract class XmlComponent extends BaseXmlComponent { - protected root: Array; + public root: Array; - constructor(rootKey: string) { + constructor(rootKey: string, initContent? : XmlComponent) { super(rootKey); - this.root = new Array(); + this.root = initContent ? initContent.root : new Array(); + if (initContent) { + console.log('\n\n-------\n\n'); + console.log('new root', JSON.stringify(initContent, null,2)); + console.log('\n\n-------\n\n'); + } + } public prepForXml(): IXmlableObject { diff --git a/src/importDocx/importDocx.ts b/src/importDocx/importDocx.ts new file mode 100644 index 0000000000..9370771a68 --- /dev/null +++ b/src/importDocx/importDocx.ts @@ -0,0 +1,27 @@ +import * as JSZip from "jszip"; +import * as fastXmlParser from "fast-xml-parser"; +import { convertToXmlComponent, parseOptions, ImportedXmlComponent } from "file/xml-components"; + +export class ImportDocx { + + constructor() { + } + + read(data) : Promise { + return new Promise((resolve) => { + JSZip.loadAsync(data).then((zipContent) => { + let headerContent = zipContent['files']['word/header2.xml']; + + headerContent.async('text').then((xmlData : string) => { + console.log('\n\n-------\n\n'); + console.log('headerContent', JSON.stringify(xmlData, null, 2)); + console.log('\n\n-------\n\n'); + const jsonObj = fastXmlParser.parse(xmlData, parseOptions); + let xmlComp = convertToXmlComponent('w:hdr', jsonObj['w:hdr']) as ImportedXmlComponent; + resolve(xmlComp); + }) + }); + }) + } +} + diff --git a/src/importDocx/index.ts b/src/importDocx/index.ts new file mode 100644 index 0000000000..3827939939 --- /dev/null +++ b/src/importDocx/index.ts @@ -0,0 +1 @@ +export * from './importDocx'; \ No newline at end of file diff --git a/src/importDocx/simple.dotx b/src/importDocx/simple.dotx new file mode 100644 index 0000000000..cc25525149 Binary files /dev/null and b/src/importDocx/simple.dotx differ diff --git a/src/importDocx/template.dotx b/src/importDocx/template.dotx new file mode 100644 index 0000000000..0a2e2fd8ee Binary files /dev/null and b/src/importDocx/template.dotx differ diff --git a/src/index.ts b/src/index.ts index b6d3ecaf25..0116405d20 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,3 +3,5 @@ export { File as Document } from "./file"; export * from "./file"; export * from "./export"; +export * from "./importDocx"; +