Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use @Raw tags in XLSX and PPTX files #622

Closed
vdechef opened this issue Sep 26, 2021 · 12 comments
Closed

Use @Raw tags in XLSX and PPTX files #622

vdechef opened this issue Sep 26, 2021 · 12 comments

Comments

@vdechef
Copy link

vdechef commented Sep 26, 2021

I was wondering if it would be possible to use raw tag in xlsx and ppts templates ?

I need to change a text color, based on an hexadecimal color value defined in my data : I can create a template that works for docx files, but I cannot figure a way to do this in pptx and xlsx files.

What I do for docx is using data like this:

let data = [
    {
        myText: "A red text",
        myColor: "FF0000"
    },
    {
        myText: "A green text",
        myColor: "00FF00"
    },
]

and template like this (I added carriage return to ease comprehension):

{@’
    <w:p>
        <w:pPr><w:jc w:val="center" /></w:pPr>
        <w:r><w:rPr><w:b w:val="true"/><w:color w:val="’ + myColor + ’"/></w:rPr>
            <w:t>’ + myText + ’</w:t>
        </w:r>
    </w:p>
’}{/}
@edi9999
Copy link
Member

edi9999 commented Sep 27, 2021

For docx, I would recommend you to do the transformation with an angular filter, to make things easier to read.

Like this :

expressions.filters.coloredText = function(text, color) {
     return `<w:p>
        <w:pPr><w:jc w:val="center" /></w:pPr>
        <w:r><w:rPr><w:b w:val="true"/><w:color w:val="’${color}"/></w:rPr>
            <w:t>${text}</w:t>
        </w:r>
    </w:p>`
}

And in your template, simply write : { myText | coloredText:myColor }

For pptx, you have to change the tags, because <w:p> is only for docx.

For pptx, the equivalent would be :

<a:p>
  <a:r>
    <a:rPr lang="en-US" altLang="de-DE" dirty="0" err="1">
      <a:solidFill>
        <a:srgbClr val="${color}"/>
      </a:solidFill>
    </a:rPr>
    <a:t>${text}</a:t>
  </a:r>
  <a:endParaRPr lang="en-US" altLang="de-DE" dirty="0" err="1">
    <a:solidFill>
      <a:srgbClr val="FF0000"/>
    </a:solidFill>
    <a:latin typeface="Calibri Light"/>
  </a:endParaRPr>
</a:p>

@edi9999
Copy link
Member

edi9999 commented Sep 27, 2021

For xlsx, this is currently not possible.

So what you would want is the same, to be able to style an xlsx cell ?

The equivalent in XLSX would be to use the following :

<si>
  <r>
    <rPr>
      <sz val="10"/>
      <color rgb="${color}"/>
      <rFont val="Arial"/>
      <charset val="1"/>
    </rPr>
    <t>${text}</t>
  </r>
</si>

@edi9999
Copy link
Member

edi9999 commented Sep 27, 2021

Good news, I've just released version 3.7.0 of the xlsx module :)

You now can use the raw xml tag.

@edi9999 edi9999 closed this as completed Sep 27, 2021
@vdechef
Copy link
Author

vdechef commented Sep 27, 2021

Thank, I will try the XLSX module tomorrow.

I tested raw tags in pptx, but there is problem with paragraphs : The tag "’<a:p><a:r><a:rPr><a:solidFill><a:srgbClr val="’ + myColor + ’"/></a:solidFill></a:rPr><a:t>"’ + myText + ‘"</a:t></a:r></a:p>’" is not inside a paragraph, putting raw tags inside an inline loop is disallowed.

I added the template in a table, or in a text zone, but I still get this result. The only way to avoid the error is to put the tag in a text zone, without any loop on the slide, and without any other text: this does not cause the error, but the text is not rendered ...

@edi9999
Copy link
Member

edi9999 commented Sep 27, 2021

Most likely if you have this error, it means that you have some text before or after the tag (maybe it can just be whitespace), no characters are allowed near the {@raw} tag.

I know that the file in the tests works well : https://github.com/open-xml-templating/docxtemplater/blob/master/examples/raw-xml-example.pptx?raw=true

If your file doesn't have any whitespace or other characters around, maybe there is a bug, in that case it would be helpful for me to see what your file is.

@vdechef
Copy link
Author

vdechef commented Sep 28, 2021

Here are 2 templates to illustrate what I tried :

  • this one generates no error, but nothing is displayed once generated (I just copied the xml from your example above) : demo_template_noerror_empty.pptx
  • this one is what I would like to achieve, but it generates an error because the raw tag is inside a table : demo_template_error.pptx

@edi9999
Copy link
Member

edi9999 commented Sep 28, 2021

I see, the issue is actually in docxtemplater's code.

Since the beginning, the expansion of the {@rawXML} tag for pptx is expanding to the full shape : <p:sp>.
I think it would make more sense to use <a:p>, but I'm not sure how many users use the {@rawXML} tag with the current behavior.

This is where it is configured :

https://github.com/open-xml-templating/docxtemplater/blob/master/es6/file-type-config.js#L57

@edi9999
Copy link
Member

edi9999 commented Sep 28, 2021

With the current behavior of expanding up to the full shape, it makes it possible to insert tables, shapes, which would no more be possible if using "a:p" for the expansion.

I don't know whether it would be best to keep the two possibilities, and how the syntax would be.

Maybe double @ : "{@@raw}" for "a:p" expansion, and single "@" for "p:sp" expansion : "{@raw}"

@edi9999 edi9999 reopened this Sep 28, 2021
@edi9999
Copy link
Member

edi9999 commented Sep 28, 2021

In the meantime, you can change this manually by using following code :

const doc = new Docxtemplater(inputZip, {
    modules: [
        {
            optionsTransformer(options, docxtemplater) {
                docxtemplater.fileTypeConfig.tagRawXml = 'a:p';
                return options;
            }
        }
    ],
});

@vdechef
Copy link
Author

vdechef commented Sep 28, 2021

Thanks, I will use this workaround

@edi9999
Copy link
Member

edi9999 commented Sep 28, 2021

@vdechef for the workaround to work well without breaking things for docx /xlsx, you have to write a condition like this :

const doc = new Docxtemplater(inputZip, {
    modules: [
        {
            optionsTransformer(options, docxtemplater) {
                if (docxtemplater.fileType === 'pptx') {
                       docxtemplater.fileTypeConfig.tagRawXml = 'a:p';
                }
                return options;
            }
        }
    ],
});

@edi9999
Copy link
Member

edi9999 commented Nov 7, 2021

I'm closing this since I won't be changing this in docxtemplater 3, there's a way to change it with the optionsTransformer option.

Maybe this is something that will change in docxtemplater 4, I'm not sure about that yet.

@edi9999 edi9999 closed this as completed Nov 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants