diff --git a/docx-core/src/documents/elements/table_cell.rs b/docx-core/src/documents/elements/table_cell.rs index f7284bd..d91638f 100644 --- a/docx-core/src/documents/elements/table_cell.rs +++ b/docx-core/src/documents/elements/table_cell.rs @@ -17,6 +17,7 @@ pub struct TableCell { #[derive(Debug, Clone, PartialEq)] pub enum TableCellContent { Paragraph(Paragraph), + Table(Table), } impl Serialize for TableCellContent { @@ -31,6 +32,12 @@ impl Serialize for TableCellContent { t.serialize_field("data", s)?; t.end() } + TableCellContent::Table(ref s) => { + let mut t = serializer.serialize_struct("Table", 2)?; + t.serialize_field("type", "table")?; + t.serialize_field("data", s)?; + t.end() + } } } } @@ -48,6 +55,14 @@ impl TableCell { self } + pub fn add_table(mut self, t: Table) -> TableCell { + if t.has_numbering { + self.has_numbering = true + } + self.children.push(TableCellContent::Table(t)); + self + } + pub fn vertical_merge(mut self, t: VMergeType) -> TableCell { self.property = self.property.vertical_merge(t); self @@ -113,6 +128,13 @@ impl BuildXML for TableCell { for c in &self.children { match c { TableCellContent::Paragraph(p) => b = b.add_child(p), + TableCellContent::Table(t) => { + b = b.add_child(t); + // INFO: We need to add empty paragraph when parent cell includes only cell. + if self.children.len() == 1 { + b = b.add_child(&Paragraph::new()) + } + } } } b.close().build() diff --git a/docx-core/src/documents/mod.rs b/docx-core/src/documents/mod.rs index 88ee929..93598bc 100644 --- a/docx-core/src/documents/mod.rs +++ b/docx-core/src/documents/mod.rs @@ -326,6 +326,9 @@ impl Docx { } } } + TableCellContent::Table(_) => { + // TODO: correct comment + } } } } @@ -398,6 +401,9 @@ impl Docx { } } } + TableCellContent::Table(_) => { + // TODO: correct comment + } } } } @@ -509,6 +515,9 @@ impl Docx { } } } + TableCellContent::Table(_) => { + // TODO: support comment + } } } } @@ -570,6 +579,9 @@ impl Docx { } } } + TableCellContent::Table(_) => { + // TODO: support comment + } } } } diff --git a/docx-wasm/js/index.ts b/docx-wasm/js/index.ts index 9e891cd..4f58db5 100644 --- a/docx-wasm/js/index.ts +++ b/docx-wasm/js/index.ts @@ -437,9 +437,14 @@ export class Docx { buildCell(c: TableCell) { let cell = wasm.createTableCell(); - c.children.forEach((p) => { - const paragraph = this.buildParagraph(p); - cell = cell.add_paragraph(paragraph); + c.children.forEach((c) => { + if (c instanceof Paragraph) { + const paragraph = this.buildParagraph(c); + cell = cell.add_paragraph(paragraph); + } else if (c instanceof Table) { + const table = this.buildTable(c); + cell = cell.add_table(table); + } }); if (c.property.verticalMerge === "continue") { diff --git a/docx-wasm/js/table-cell.ts b/docx-wasm/js/table-cell.ts index 36e6824..6bc30da 100644 --- a/docx-wasm/js/table-cell.ts +++ b/docx-wasm/js/table-cell.ts @@ -1,4 +1,5 @@ import { Paragraph } from "./paragraph"; +import { Table } from "./table"; import { TableCellBorders, PositionKeys } from "./table-cell-borders"; import { BorderPosition, TableCellBorder } from "./table-cell-border"; import * as wasm from "./pkg"; @@ -58,7 +59,7 @@ export type CellProperty = { }; export class TableCell { - children: Paragraph[] = []; + children: (Paragraph | Table)[] = []; hasNumberings = false; property: CellProperty = { borders: new TableCellBorders(), @@ -72,6 +73,14 @@ export class TableCell { return this; } + addTable(t: Table) { + if (t.hasNumberings) { + this.hasNumberings = true; + } + this.children.push(t); + return this; + } + verticalMerge(t: VMergeType) { this.property.verticalMerge = t; return this; diff --git a/docx-wasm/package.json b/docx-wasm/package.json index 0f8009c..efcf8e7 100644 --- a/docx-wasm/package.json +++ b/docx-wasm/package.json @@ -1,6 +1,6 @@ { "name": "docx-wasm", - "version": "0.0.148", + "version": "0.0.149", "main": "dist/node/index.js", "browser": "dist/web/index.js", "author": "bokuweb ", diff --git a/docx-wasm/src/table_cell.rs b/docx-wasm/src/table_cell.rs index f56bf11..cf2b173 100644 --- a/docx-wasm/src/table_cell.rs +++ b/docx-wasm/src/table_cell.rs @@ -25,6 +25,13 @@ impl TableCell { self } + pub fn add_table(mut self, t: Table) -> TableCell { + self.0 + .children + .push(docx_rs::TableCellContent::Table(t.take())); + self + } + pub fn vertical_merge(mut self, t: docx_rs::VMergeType) -> TableCell { self.0.property = self.0.property.vertical_merge(t); self diff --git a/docx-wasm/test/__snapshots__/index.test.js.snap b/docx-wasm/test/__snapshots__/index.test.js.snap index f1f36cb..a36facc 100644 --- a/docx-wasm/test/__snapshots__/index.test.js.snap +++ b/docx-wasm/test/__snapshots__/index.test.js.snap @@ -10448,6 +10448,43 @@ exports[`writer should write lvlOverride with level 3`] = ` " `; +exports[`writer should write nested table 1`] = ` +" + + + + + + +" +`; + +exports[`writer should write nested table 2`] = ` +" + + + + + + + + + + + +Hello world!! + + +" +`; + +exports[`writer should write nested table 3`] = ` +" + + +" +`; + exports[`writer should write page margin 1`] = ` " @@ -10462,7 +10499,7 @@ exports[`writer should write page margin 1`] = ` exports[`writer should write page margin 2`] = ` " - Hello world!! + Hello world!! " diff --git a/docx-wasm/test/index.test.js b/docx-wasm/test/index.test.js index db8453a..48f9b47 100644 --- a/docx-wasm/test/index.test.js +++ b/docx-wasm/test/index.test.js @@ -85,6 +85,24 @@ describe("writer", () => { } }); + test("should write nested table", () => { + const p = new w.Paragraph().addRun(new w.Run().addText("Hello world!!")); + const childTable = new w.Table().addRow( + new w.TableRow().addCell(new w.TableCell().addParagraph(p)) + ); + const parentTable = new w.Table().addRow( + new w.TableRow().addCell(new w.TableCell().addTable(childTable)) + ); + const buffer = new w.Docx().addTable(parentTable).build(); + const z = new Zip(Buffer.from(buffer)); + for (const e of z.getEntries()) { + if (e.entryName.match(/document.xml|numbering.xml/)) { + expect(z.readAsText(e)).toMatchSnapshot(); + } + } + writeFileSync("../output/nested_table.docx", buffer); + }); + test("should write page margin", () => { const p = new w.Paragraph().addRun(new w.Run().addText("Hello world!!")); const buffer = new w.Docx() @@ -121,10 +139,7 @@ describe("writer", () => { test("should write doc vars", () => { const p = new w.Paragraph().addRun(new w.Run().addText("Hello world!!!!")); - const buffer = new w.Docx() - .addParagraph(p) - .addDocVar("foo", "bar") - .build(); + const buffer = new w.Docx().addParagraph(p).addDocVar("foo", "bar").build(); writeFileSync("../output/doc_vars.docx", buffer); const z = new Zip(Buffer.from(buffer)); for (const e of z.getEntries()) {