Closed pdecat closed 3 years ago
thank you for the PR and sorry that it took longer to review it. we were considering the docxRaw but so far it looks that "everything" can be done just with normal templating, even your example can be done this way.
tried to reproduce a bit what you are doing and this is the result so far, it seems it is possible to continue modifying to match your styles and content
something to consider when working with the table is the table styles, especially for the bold text, sometimes the table styles can contain rules that go into conflict with the styles of the text. so the easy way to fix that is to disable bold text from the table styles rules. in my example i've already did that and everything works as expected, if the result of the condition is bold text it remains the same.
do you have some other valid scenarios that justify introducing this helper? if yes, let us know to continue evaluating the need for a raw helper.
Hi @bjrmatos, adding docxRaw is justified as ~opening that generated file in Libreoffice is broken:~
Sorry, I spoke too fast before importing your sample.
Let me explain what we are doing with docxRaw
: we are generating the whole tables from raw JSON and formatting the table content at the Javascript onBefore
function level depending on field names and values as it provides much more flexibility.
For tables with dynamic column, we are even comparing values between cells to add colored arrows indicating the trend (up/same/down).
Here's an example of our current progress where the color is only applied to the arrow, but not to the amount:
The template is kept simple:
{{#docxTable rows=myrows columns=mycols}}{{docxRaw this}}{{/docxTable}}
The data provides the advanced formatting:
{"rows":[["Virtual Machine","€5,000.00","<w:r><w:t>€5,100.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€5,200.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€5,100.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"00FF00\"/></w:rPr><w:t> ▼</w:t></w:r>","<w:r><w:t>€5,200.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€5,300.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>"],["Database","€2,000.00","<w:r><w:t>€1,900.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"00FF00\"/></w:rPr><w:t> ▼</w:t></w:r>","<w:r><w:t>€2,000.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€1,900.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"00FF00\"/></w:rPr><w:t> ▼</w:t></w:r>","<w:r><w:t>€2,000.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€2,100.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>"],["Storage","€500.00","<w:r><w:t>€505.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€520.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€505.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"00FF00\"/></w:rPr><w:t> ▼</w:t></w:r>","<w:r><w:t>€520.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€540.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>"],["Others","€20.00","<w:r><w:t>€20.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"CCCCCC\"/></w:rPr><w:t> ▶</w:t></w:r>","<w:r><w:t>€30.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€20.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"00FF00\"/></w:rPr><w:t> ▼</w:t></w:r>","<w:r><w:t>€30.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€30.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"CCCCCC\"/></w:rPr><w:t> ▶</w:t></w:r>"],["Total","€8,550.00","<w:r><w:t>€8,450.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"00FF00\"/></w:rPr><w:t> ▼</w:t></w:r>","<w:r><w:t>€8,980.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€8,450.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"00FF00\"/></w:rPr><w:t> ▼</w:t></w:r>","<w:r><w:t>€8,980.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>","<w:r><w:t>€9,300.00</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii=\"FreeSans\" w:hAnsi=\"FreeSans\"/><w:color w:val=\"FF0000\"/></w:rPr><w:t> ▲</w:t></w:r>"]],"cols":["Service","2020/02","2020/03","2020/04","2020/05","2020/06","2020/07"]}
Note: the great advantage of formatting data in Javascript instead of the docx template is that I can have unit tests for all kind of things.
we had some discussion internally and we decided to accept this PR, we think it makes sense to support this to support advanced users like you. however, we will like some changes, i'm going to specify the changes as reviews
I've updated code for compatibility with nodejs 8.9 used in CI which does not support named capture groups:
Error: Error while executing docx recipe. Invalid regular expression: /xml=(?<xml>[^{}\s]+)/: Invalid group
https://travis-ci.org/github/jsreport/jsreport-docx/builds/742646597#L341
See https://node.green/#ES2018-features--RegExp-named-capture-groups and https://github.com/nodejs/node/issues/19760
The docxRaw
helper no longer restricts what parent elements can be replaced.
thank you for all your work here! we still have some ideas to make the logic simpler, but we don't see a reason to delay the merging. so we are merging the PR and plan to refactor the code a bit more by ourselves sometime later.
Thanks @bjrmatos!
This is a tentative PR to add a
docxRaw
helper that allows to insert arbitrary XML anywhere in the docx document.At first, I tried to simply use the
{{{
/}}}
triple brackets to avoid escaping in the Handlebars templating engine, but it puts the XML in aw:t
literal text tag and some docx editors does not support that well, e.g. Word Online displays a broken table and Libreoffice drops the run altogether.Still WIP with regards to the following but submitted now to get early feedback if possible:
docxRaw
Related thread: https://forum.jsreport.net/topic/1790/docxraw-helper/4
As an example, this allows to generate tables like this:
From the following template:
And the following data: