open-xml-templating/docxtemplater

Docx text-box placed inside loop in template corrupts the generated docx

sa4420 opened this issue · 3 comments

Environment

  • Version of docxtemplater : 3.32.4
  • Runner : Node.JS

How to reproduce my problem :

My template is the following :
template.zip

With the following js file :

const fs = require('fs');
const Docxtemplater = require('docxtemplater');

const fixDocPrCorruption = require("docxtemplater/js/modules/fix-doc-pr-corruption.js");
const DocumentOptions = {
    delimiters: {
        start: '{{',
        end: '}}'
    },
    nullGetter(part) {
        if (!part.module) {
            return "";
        }
        if (part.module === "rawxml") {
            return "";
        }
        return "";
    },
    modules: [fixDocPrCorruption]
};

const data = {
  "lineitems": [
    {
      "IF_top_level_product": "true",
      "person_name1": "Allison",
      "person_name2": "Kate",
      "mrs_total": "$216,000.00",
      "discount": 10,
      "salesprice": "$240,000.00",
      "unitprice": "$120,000.00",
      "qty": 2,
      "mrs_total1": "$216,000.00",
      "discount1": 10,
      "salesprice1": "$240,000.00",
      "unitprice1": "$120,000.00",
      "qty1": 2,
      "product_name1": "GenWatt Propane 1500kW",
      "product_name2": "GenWatt Propane 2000kW"
    },
    {
      "IF_top_level_product": "true",
      "person_name1": "Allison",
      "person_name2": "Kate",
      "mrs_total": "$216,000.00",
      "discount": 10,
      "salesprice": "$240,000.00",
      "unitprice": "$120,000.00",
      "qty": 2,
      "mrs_total1": "$216,000.00",
      "discount1": 10,
      "salesprice1": "$240,000.00",
      "unitprice1": "$120,000.00",
      "qty1": 2,
      "product_name1": "GenWatt Propane 1500kW",
      "product_name2": "GenWatt Propane 2000kW"
    }
  ],
  "IF_Business_Essentials_Products": "true",
  "term": "06/02/2021",
  "Opportunity_Name": "National Power Generation - Malabar Coast, India",
  "state": "Karnataka",
  "Company_Name": "Keizer Ltd",
  "country": "India",
  "city": "Bangalore",
  "city1": "Hyderabad",
  "city2": "Kolkata",
  "city3": "Mumbai",
  "Clause": " test"
}

const OutputConfig = {
    'type': 'nodebuffer',
    'compression': 'DEFLATE',
    'compressionOptions': { 'level': 9 }
};

const content = fs
    .readFileSync(__dirname + "/template.zip", "binary");

const zip = new PizZip(content);
const doc = new Docxtemplater(zip)
doc.setOptions(DocumentOptions);
doc.setData(data);
doc.render();

const buf = doc.getZip().generate(OutputConfig);

fs.writeFileSync(__dirname+"/output.docx",buf);

I would expect it to :

  • Generated docx shouldn't be corrupted.

Template :
SampleOnlyTextBox.docx
Generated docx :
Generated.docx

Hello,

The file that you've uploaded is indeed corrupt.

however, the code that you sent did not work.

I had to change a few things, and the document that is generated (output.docx) was not corrupt for me

Here is the code with the updated files. It works now with node index.js and produces the output with no corruption.

full-sample.zip

Hi,
It seems that when we are adding 'fixDocPrCorruption' module, then we need to use only parameterized constructor to create instance of docxtemplater. If we use non-parameterized constructor and try to set options later using setOptions() method, it is throwing error. Anyway, that solves the issue. Thanks for the help.

Yes, the currently suggested way to make it work is the following :

Instead of this :

const doc = new Docxtemplater()
doc.loadZip(zip)
doc.setOptions(options)
doc.setData(data);
doc.render();

do simply this :

const doc = new Docxtemplater(zip, options);
doc.render(data);