guigrpa / docx-templates

Template-based docx report creation
MIT License
912 stars 145 forks source link

Bug Report: option data with object keys as numbers does not work #388

Open maximdv34 opened 1 month ago

maximdv34 commented 1 month ago

Option data with object keys as numbers does not work

Code to reproduce:

const template = await fs.promises.readFile("certificates/FinalCertificateTemplate.docx");
const { fullDate, formattedTime } = await getFormatedDateTime();
const buffer = await createReport({
    template,
    data: { "1": fullDate, "2": formattedTime },
    cmdDelimiter: "#",
});

Template: FinalCertificateTemplate.docx Result: Screenshot 2024-10-04 095545 In the results file, keys 1 and 2 are not replaced.

If i do the same thing but with keys as strings, result will be correct

Code to reproduce:

const template = await fs.promises.readFile("certificates/FinalCertificateTemplate.docx");
const { fullDate, formattedTime } = await getFormatedDateTime();
const buffer = await createReport({
    template,
    data: { a: fullDate, b: formattedTime },
    cmdDelimiter: "#",
});

Template: FinalCertificateTemplate.docx Result: Screenshot 2024-10-04 100655 In the results file, keys a and b are replaced.

For JavaScript objects keys is always strings, so it must be no difference.

Information about my stack:

I'm using Next.js version 14.2.4, with pure Node.js version 20.11.0 as the back-end. All the certificate generation logic is in the back-end part

jjhbw commented 1 month ago

The commands in the template are effectively javascript syntax. If you put literal numbers in a command, e.g #12#it gets executed as code so the result will be the insertion of the literal 12.

The keys of the data object are unwrapped into the global namespace of the template commands. So data.someProperty becomes available as the global variable someProperty in the template's namespace, so you can refer to it from within template commands using e.g. #someProperty#. This does not work for numbers, because variable names cant be number literals in JS. E.g. 4 = 'abc' can't work.

In light of the above, I'd say what you want to do is impossible currently. However, given that commands are essentially javascript, docx-templates supports all kinds of creative hacks. So maybe you can find something to solve your problem.

jjhbw commented 1 month ago

In summary: data object properties need to be valid as javascript global variable names. Literal numbers are not.

maximdv34 commented 1 month ago

Thank you for quick response! I understood why it doesn't work, but there is no documentation about it, and there are no errors when I run the createReport function with an invalid data object.

I think you should make a choice:

Because now it is not possible to understand why it happens without your clarifications.