diff --git a/demo/85-template-document.ts b/demo/85-template-document.ts new file mode 100644 index 0000000000..d219170491 --- /dev/null +++ b/demo/85-template-document.ts @@ -0,0 +1,8 @@ +// Simple template example +// Import from 'docx' rather than '../build' if you install from npm +import * as fs from "fs"; +import { fromDocx } from "../build"; + +fromDocx(fs.readFileSync("demo/template.docx")).then((doc) => { + fs.writeFileSync("My Document.docx", doc); +}); diff --git a/demo/template.docx b/demo/template.docx new file mode 100644 index 0000000000..fd05df5947 Binary files /dev/null and b/demo/template.docx differ diff --git a/src/index.ts b/src/index.ts index 3d76a0f70f..7162ae5a1f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,3 +5,4 @@ export * from "./file"; export * from "./export"; export * from "./import-dotx"; export * from "./util"; +export * from "./templater"; diff --git a/src/templater/from-docx.ts b/src/templater/from-docx.ts new file mode 100644 index 0000000000..cec1a84877 --- /dev/null +++ b/src/templater/from-docx.ts @@ -0,0 +1,42 @@ +import * as JSZip from "jszip"; +import { xml2js, ElementCompact, js2xml } from "xml-js"; + +// eslint-disable-next-line functional/prefer-readonly-type +type InputDataType = Buffer | string | number[] | Uint8Array | ArrayBuffer | Blob | NodeJS.ReadableStream; + +export const fromDocx = async (data: InputDataType): Promise => { + const zipContent = await JSZip.loadAsync(data); + + const map = new Map(); + + for (const [key, value] of Object.entries(zipContent.files)) { + const json = toJson(await value.async("text")); + map.set(key, json); + } + + const zip = new JSZip(); + + for (const [key, value] of map) { + const output = toXml(value); + + zip.file(key, output); + } + + const zipData = await zip.generateAsync({ + type: "nodebuffer", + mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + compression: "DEFLATE", + }); + + return zipData; +}; + +const toJson = (xmlData: string): ElementCompact => { + const xmlObj = xml2js(xmlData, { compact: false }) as ElementCompact; + return xmlObj; +}; + +const toXml = (jsonObj: ElementCompact): string => { + const output = js2xml(jsonObj); + return output; +}; diff --git a/src/templater/index.ts b/src/templater/index.ts new file mode 100644 index 0000000000..466cb3eda7 --- /dev/null +++ b/src/templater/index.ts @@ -0,0 +1 @@ +export * from "./from-docx";