1

We have data that looks like this:

[
  {
    firstName: 'Susan',
    lastName: 'Storm'
    meta: [
      {
        age: 30,
        email: '[email protected]'
      }
    ]
  },
  {
    firstName: 'Peter',
    lastName: 'Parker'
    meta: [
      {
        hairColor: 'Brown',
        costumeColor: 'Red'
      }
    ]
  }
]

We are trying to build an MS Word document with a table that includes the following columns:

First Name, Last Name, Age OR Hair Color, Email OR Costume Color
Susan, Storm, 30, [email protected]
Peter, Parker, Brown, Red

We have tried using multi-level loops with both the Vertical Table module and the built-in looping feature.

Any suggestions on how to achieve this in a Word document using Docxtemplater?

2 Answers 2

1

I've wrestled with this exact issue before. The trick is to flatten your data structure first since Docxtemplater doesn't handle nested loops well in tables. Try restructuring your data like this:

const flattenedData = originalData.map(person => ({
  ...person,
  age: person.meta[0].age,
  email: person.meta[0].email
}));

Then in your Word table template:

----------------------------------------------
| First Name | Last Name | Age     | Email       |
----------------------------------------------
{#flattenedData}
| {firstName} | {lastName} | {age} | {email} |
{/flattenedData}
----------------------------------------------

Make sure you:

Select the entire table row in Word (including the end-of-row marker) before applying the loop

Install the docxtemplater-table-module for proper row duplication

Remove any nested loop tags from your template

This worked for me when I had to deal with those pesky nested objects in client reports. If your meta array has multiple items, you'll need to flatten differently - let me know if that's the case!

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the suggestion Nooky 07. The challenge that I have is that the meta objects could have properties added or removed. This would require me the edit the template every time the data changes.
I've updated the question to display this exception
0

(Creator of docxtemplater.com here)

Indeed, with the table module (paid module), you can use both horizontal loops {#xx} {/xx} together with vertical loops {:vt# loop} and {:vt/}.

I've just added a section about this in the docs :

https://docxtemplater.com/modules/table/#combining-vertical-and-horizontal-tables

In your case, you would have to transform your data, you could do some from the template itself using an angular filter.

You will need to install angular expressions first which is what we use so that we can create filters such as separateKeys (defined below).

npm install --save angular-expressions

Here would be a fully working example :

const expressionParser = require("docxtemplater/expressions.js");
const doc = new Docxtemplater(zip, {
  paragraphLoop: true,
  linebreaks: true,
  parser: expressionParser.configure({
    filters: {
      separateKeys(input) {
        const keys = Object.keys(input[0]);
        // keys wil be ["firstName", "lastName" ]
        const res = {
          vloop: keys,
          values: input.map(function (line) {
            return {
              vloop: keys.map(function (key) {
                return line[key];
              }),
            };
          }),
        };
        return res;
      },
    },
  }),
});

doc.render({
  users: [
    {
      firstName: "Susan",
      lastName: "Storm",
      meta: [
        {
          age: 30,
          email: "[email protected]",
        },
      ],
    },
    {
      firstName: "Peter",
      lastName: "Parker",
      meta: [
        {
          hairColor: "Brown",
          costumeColor: "Red",
        },
      ],
    },
  ],
});

In your template, you would then write (each line is in a table cell, in a table with just one column).

{#users | separateKeys}
(START OF TABLE)
{:vt#vloop}{.}
{-w:tr values}{.}{/}{:vt/}
(END OF TABLE)
{/}

You can download the docx template here :

https://docxtemplater.com/vertical-loop-new-table.docx

In order to properly handle "meta" you would most likely simply have to change the "separateKeys" filter function, or maybe restructure the data first

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.