open-xml-templating / docxtemplater

Generate docx, pptx, and xlsx from templates (Word, Powerpoint and Excel documents), from Node.js or the browser. Demo: https://www.docxtemplater.com/demo. #docx #office #generator #templating #report #json #generate #generation #template #create #pptx #docx #xlsx #react #vuejs #angularjs #browser #typescript #image #html #table #chart
https://www.docxtemplater.com
Other
3.03k stars 349 forks source link

Loop through array of objects #259

Closed ishu3101 closed 7 years ago

ishu3101 commented 7 years ago

I have the following data.

"person": 
    [
      {
        "age": "35",
        "interests": [
          "cooking", "photography"
          ]
      }
    ]

How do I loop through to get the following output.

Interests

* Cooking
* Photography
edi9999 commented 7 years ago

You can write:

{#persons}
{#interests}
* {.}
{/interests}
{/persons}

A dot inside a tag means : use the whole current scope as the replace value.

ishu3101 commented 7 years ago

But I'm getting NaN when I write what you suggested.

Also shouldn't it be person and not persons, as that is what we have called our properties in the above example.

edi9999 commented 7 years ago

Indeed, it should be person and not persons.

It works fine for me when I write the template, I don't get any NaN.

Can you send your input.docx, your data and your output.docx ?

ishu3101 commented 7 years ago

Here are the files.

person-input.docx person-output.docx

person.json

{
    "person": [
      {
        "name": "david",
        "age": "35",
        "interests": [
          "cooking", "photography"
          ]
      }
    ]
}
edi9999 commented 7 years ago

It works fine for me . Are you using docxtemplater version 3.0 ?

Here is my code :

var fs = require('fs');
var Docxtemplater = require('docxtemplater');
var JSZip = require('jszip');

//Load the docx file as a binary
var content = fs
    .readFileSync(__dirname + "/person-input.docx", "binary");

var zip = new JSZip(content);
var doc=new Docxtemplater().loadZip(zip)

//set the templateVariables
doc.setData({
    "person": [
      {
        "name": "david",
        "age": "35",
        "interests": [
          "cooking", "photography"
          ]
      }
    ]
});

//apply them (replace all occurences of {first_name} by Hipp, ...)
doc.render();

var buf = doc.getZip()
             .generate({type:"nodebuffer"});

fs.writeFileSync(__dirname+"/output.docx",buf);
ishu3101 commented 7 years ago

No, I was using v2.1.5. It works, when I upgrade to docxtemplater v3.0. However when I use angular parser, I still get NaN

ishu3101 commented 7 years ago

Updating my angular parser from

var angularParser = function(tag){
    expr = expressions.compile(tag);
    return {get:expr};
};

to this, fixes the issue.

var angularParser = function(tag){
    return {
        get: tag == '.' ? function(s){ return s;} : expressions.compile(tag)
    };
};
edi9999 commented 7 years ago

Yes, that was it, the angularParser doesn't know about the tag .