From 59fb7c113f532a102f916b1b640079998f3c12b7 Mon Sep 17 00:00:00 2001 From: bokuweb Date: Fri, 26 Nov 2021 00:06:16 +0900 Subject: [PATCH] impl: Add header writer with js (#371) --- docx-wasm/js/header.ts | 14 +++++++++ docx-wasm/js/index.ts | 15 ++++++++++ docx-wasm/js/section-property.ts | 7 +++++ docx-wasm/src/doc.rs | 5 ++++ docx-wasm/src/header.rs | 30 +++++++++++++++++++ docx-wasm/src/lib.rs | 2 ++ .../test/__snapshots__/index.test.js.snap | 19 ++++++++++++ docx-wasm/test/index.test.js | 14 +++++++++ 8 files changed, 106 insertions(+) create mode 100644 docx-wasm/js/header.ts create mode 100644 docx-wasm/src/header.rs diff --git a/docx-wasm/js/header.ts b/docx-wasm/js/header.ts new file mode 100644 index 0000000..193b10a --- /dev/null +++ b/docx-wasm/js/header.ts @@ -0,0 +1,14 @@ +import { Paragraph } from "./paragraph"; + +export class Header { + hasNumberings = false; + children: Paragraph[] = []; + + addParagraph(p: Paragraph) { + if (p.hasNumberings) { + this.hasNumberings = true; + } + this.children.push(p); + return this; + } +} diff --git a/docx-wasm/js/index.ts b/docx-wasm/js/index.ts index 62861d8..99e5d2a 100644 --- a/docx-wasm/js/index.ts +++ b/docx-wasm/js/index.ts @@ -20,6 +20,7 @@ import { DocProps } from "./doc-props"; import { Styles } from "./styles"; import { WebExtension } from "./webextension"; import { Footer } from "./footer"; +import { Header } from "./header"; import { SectionProperty, PageMargin, @@ -151,6 +152,11 @@ export class Docx { return this; } + header(f: Header) { + this.sectionProperty._header = f; + return this; + } + footer(f: Footer) { this.sectionProperty._footer = f; return this; @@ -849,6 +855,14 @@ export class Docx { docx = docx.add_doc_var(v.name, v.val); }); + if (this.sectionProperty._header) { + let header = wasm.createHeader(); + this.sectionProperty._header.children.forEach((c) => { + header = header.add_paragraph(this.buildParagraph(c)); + }); + docx = docx.header(header); + } + if (this.sectionProperty._footer) { let footer = wasm.createFooter(); this.sectionProperty._footer.children.forEach((c) => { @@ -1008,4 +1022,5 @@ export * from "./level"; export * from "./tab"; export * from "./json"; export * from "./webextension"; +export * from "./header"; export * from "./footer"; diff --git a/docx-wasm/js/section-property.ts b/docx-wasm/js/section-property.ts index 816bc37..3277fc8 100644 --- a/docx-wasm/js/section-property.ts +++ b/docx-wasm/js/section-property.ts @@ -1,5 +1,6 @@ import { DocGridType } from "."; import { Footer } from "./footer"; +import { Header } from "./header"; export type DocGrid = { gridType: DocGridType; @@ -17,6 +18,7 @@ export class SectionProperty { gridType: "lines", linePitch: 360, }; + _header: Header | null = null; _footer: Footer | null = null; pageSize(w: number, h: number) { @@ -40,6 +42,11 @@ export class SectionProperty { return this; } + header(header: Header) { + this._header = header; + return this; + } + footer(footer: Footer) { this._footer = footer; return this; diff --git a/docx-wasm/src/doc.rs b/docx-wasm/src/doc.rs index bf3dcc2..274ebda 100644 --- a/docx-wasm/src/doc.rs +++ b/docx-wasm/src/doc.rs @@ -73,6 +73,11 @@ impl Docx { self } + pub fn header(mut self, header: Header) -> Self { + self.0 = self.0.header(header.take()); + self + } + pub fn footer(mut self, footer: Footer) -> Self { self.0 = self.0.footer(footer.take()); self diff --git a/docx-wasm/src/header.rs b/docx-wasm/src/header.rs new file mode 100644 index 0000000..ff5c969 --- /dev/null +++ b/docx-wasm/src/header.rs @@ -0,0 +1,30 @@ +use super::*; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Debug)] +pub struct Header(docx_rs::Header); + +#[wasm_bindgen(js_name = createHeader)] +pub fn create_footer() -> Header { + Header(docx_rs::Header::new()) +} + +impl Header { + pub fn take(self) -> docx_rs::Header { + self.0 + } +} + +#[wasm_bindgen] +impl Header { + pub fn add_paragraph(mut self, p: Paragraph) -> Self { + self.0 = self.0.add_paragraph(p.take()); + self + } + + pub fn add_table(mut self, t: Table) -> Self { + self.0 = self.0.add_table(t.take()); + self + } +} diff --git a/docx-wasm/src/lib.rs b/docx-wasm/src/lib.rs index 3b3b4cf..9ffe2d6 100644 --- a/docx-wasm/src/lib.rs +++ b/docx-wasm/src/lib.rs @@ -4,6 +4,7 @@ mod comment; mod delete; mod doc; mod footer; +mod header; mod insert; mod level; mod level_override; @@ -26,6 +27,7 @@ pub use comment::*; pub use delete::*; pub use doc::*; pub use footer::*; +pub use header::*; pub use insert::*; pub use level::*; pub use level_override::*; diff --git a/docx-wasm/test/__snapshots__/index.test.js.snap b/docx-wasm/test/__snapshots__/index.test.js.snap index 709b536..ae02d76 100644 --- a/docx-wasm/test/__snapshots__/index.test.js.snap +++ b/docx-wasm/test/__snapshots__/index.test.js.snap @@ -23751,6 +23751,25 @@ exports[`writer should write footer for default section 3`] = ` Hello Footer" `; +exports[`writer should write header for default section 1`] = ` +" + + + + + + + +" +`; + +exports[`writer should write header for default section 2`] = ` +" + + World +" +`; + exports[`writer should write hello 1`] = ` " diff --git a/docx-wasm/test/index.test.js b/docx-wasm/test/index.test.js index 75c04d3..3d4c419 100644 --- a/docx-wasm/test/index.test.js +++ b/docx-wasm/test/index.test.js @@ -384,4 +384,18 @@ describe("writer", () => { } } }); + + test("should write header for default section", () => { + const p1 = new w.Paragraph().addRun(new w.Run().addText("Hello Header")); + const p2 = new w.Paragraph().addRun(new w.Run().addText("World ")); + const header = new w.Header().addParagraph(p1); + const buffer = new w.Docx().header(header).addParagraph(p2).build(); + writeFileSync("../output/header.docx", buffer); + const z = new Zip(Buffer.from(buffer)); + for (const e of z.getEntries()) { + if (e.entryName.match(/document.xml|footer1.xml/)) { + expect(z.readAsText(e)).toMatchSnapshot(); + } + } + }); });