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

Insert New line character (\n) in word document #144

Closed
atrerice opened this issue Jun 24, 2015 · 22 comments
Closed

Insert New line character (\n) in word document #144

atrerice opened this issue Jun 24, 2015 · 22 comments
Labels

Comments

@atrerice
Copy link

I logged the value of the string which shows the new line char but when the document generates in Word, the paragraphs are combined.

@edi9999
Copy link
Member

edi9999 commented Jun 25, 2015

To see how to insert new line, look at #26

@edi9999
Copy link
Member

edi9999 commented Jun 25, 2015

There's also #92 #73 and #56

@edi9999 edi9999 closed this as completed Jun 25, 2015
@atrerice
Copy link
Author

None of these apply, I get the document but the paragraphs become one long string. It worked on an earlier version of my code so

@edi9999
Copy link
Member

edi9999 commented Jun 25, 2015

Your question is very unclear. What exactly doesn't work ?

Can you give a script with it's template, output and your expected output ?

@edi9999 edi9999 reopened this Jun 25, 2015
@atrerice
Copy link
Author

I have string values that have '\n' breaks. When the string is generated in the .docx it becomes one long string with no breaks. I tried replacing the '\n' with '<w:br/>' and placing '<w:p><w:r><w:t>' in the beginng of the paragraph and '</w:t></w:r></w:p>' at the end. This did not work either, still one long string.

My template has:
{#exceptions}
{num}. {exception}
{/exceptions}

My source:
var docx = require('docxtemplater');
var worddoc = {
docpath: 'path to folder',
docname: 'name.docx'
};
var docs = {
createDoc: function(req, res) {
var exceptions = [];
var doc = new docx(worddoc.docpath);
doc.setData = {
exceptions: req.body.exceptions
}
doc.render();
var buf = doc.getZip().generate({ type: 'nodebuffer' });
try {
fs.writeFileSync(worddoc.docpath + worddoc.docname, buf);
}
catch(exception) {
console.log(exception);
}
}
The string value is "this is one line.\nThis is another." It comes through as one line.

@edi9999
Copy link
Member

edi9999 commented Jun 25, 2015

It's actually expected to work this way, \n is not replaced by a new line, everything is escaped by default (it is also the case for things like < , > and others)

Here's the solution to this : Found here: #92 (comment)

Thank you, got it working, for anyone else struggling with this here is what I did:

pre = '<w:p><w:r><w:t>';
post = '</w:t></w:r></w:p>';
lineBreak = '<w:br/>';
test = pre + 'testing line 1' + lineBreak + 'testing line 2' + post;

then in your template, just put {@test} instead of the usual {test}

@edi9999 edi9999 changed the title New line character not being preserved in word document Insert New line character (\n) in word document Jun 25, 2015
@atrerice
Copy link
Author

This works on single variable like {@test} but I am using a loop. How would I use the @ symbol in my loop on the template?

@edi9999
Copy link
Member

edi9999 commented Jun 25, 2015

{#exceptions}
{@exception}
{/exceptions}

@edi9999
Copy link
Member

edi9999 commented Jun 25, 2015

Where

you have as json:

pre = '<w:p><w:r><w:t>';
post = '</w:t></w:r></w:p>';
lineBreak = '<w:br/>';

{exceptions:[
  {exception:pre + 'testing line 1' + lineBreak + 'testing line 2' + post},
  {exception:pre + 'testing line 3' + lineBreak + 'testing line 4' + post},
]}

@edi9999 edi9999 closed this as completed Jun 25, 2015
@atrerice
Copy link
Author

Thank you. This works.

@jetherton
Copy link

@edi9999 I followed the solution you give for replacing the \n with <w:br/> and using {@field_name}

I'm writing an app that will parse user created templates, so I don't know at build time what the inputs will be. When I have multiple fields such as:

{#page} 
   {@address}
   {@name} Total Owed: ${@total}
   {@line_items}
{/page}

I get this error:

[TemplateError: Raw tag should be the only text in paragraph]
  name: 'TemplateError',
  message: 'Raw tag should be the only text in paragraph',
  stack: 'Error: Raw tag should be the only text in paragraph
  at Error.XTTemplateError....

What I'm ideally looking for is an easy way to let the user add new lines from any field at any time. Is that possible? Do I just need to tell users to put fields with \n on their own paragraph?

Thanks and docxtemplater is a great.

@edi9999
Copy link
Member

edi9999 commented Apr 29, 2017

When your template contains

User Is {@user}

It means that the paragraph is :

<w:p>User Is {@user}</w:p>

The {@user} means replace the whole paragraph, so this means everything else before or after the tag in that paragraph will be wiped. I prefer to give a real error than just deleting the text silently.

One solution to that is to use the paid word run module, which can replace only the tag that you use : https://modules.docxtemplater.com/modules/word-run/

Or you can also build your paragraph content yourself, eg add "User is" to the user data.

@jetherton
Copy link

It seems like changing DocUtils.charMap to

DocUtils.charMap = {
	"&": "&amp;",
	"'": "&apos;",
	"<": "&lt;",
	">": "&gt;",
	"\n":"<w:br/>"
};

Does what I need. I know nothing about the docx .xml format, but this worked in my simple test cases. But I can't help but imagine you didn't do this for a reason. Is there something obvious I'm missing.

@edi9999
Copy link
Member

edi9999 commented May 1, 2017

That's interesting indeed... However, it has a few problems :

The first one is that it may work in some word versions, but the open xml spec says that <w:br/> must be in the <w:r>, but not in the <w:t>.

Secondly, it will work for docx but not pptx

Thirdly, this map is for decoding xml characters, this shouldn't be done here.

Lastly this would be a breaking change because for now we just ignore \n and this could be adding unwanted new lines.

@simonaberry
Copy link

I tried the pre/post/linebreak suggestion - but couldn't get it to work inside a table that is generated within a loop. So in the end I used :

JS
obj.lines = inputText.split('\n').map(function (lineItem) { return : { line : lineItem} } );

and in the template :

{#lines}{line}
{/lines}

This solution seems obvious and simple - is there a gotcha that I am missing ?

@edi9999
Copy link
Member

edi9999 commented Jun 26, 2017

You can even simplify it a little bit with :

JS
obj.lines = inputText.split('\n')

and in the template :

{#lines}{.}
{/lines}

@edi9999
Copy link
Member

edi9999 commented Nov 9, 2017

For docxtemplater v4, we will automatically add newlines when the text contains \n (see #340 point 8.)

@edi9999
Copy link
Member

edi9999 commented Aug 30, 2018

You can do this starting from docxtemplater 3.8.0 :

doc.setOptions({linebreaks:true});
doc.setData({text: "My text,\nmultiline"});
doc.render();

https://docxtemplater.readthedocs.io/en/latest/configuration.html#linebreaks

@mimedo
Copy link

mimedo commented Apr 2, 2020

Hey @edi9999

How does the template look like?

I have in my JSON:

{
   "description":  "This is first line.\n This is second line"
}

And in my code:

// Set options
doc.setOptions({linebreaks: true});
doc.setData({
  description: employee.description + ',\nmultiline'
});

And in template:

{description}

But it doesn't work. Output is:
This is first line. This is second line, multiline

I saw https://docxtemplater.readthedocs.io/en/latest/configuration.html#linebreaks it here.

@edi9999
Copy link
Member

edi9999 commented Apr 2, 2020

That is strange, can you open a new issue and send me the template that you use ?

@mimedo
Copy link

mimedo commented Apr 2, 2020

That is strange, can you open a new issue(#509) and send me the template that you use ?

Yes, I opened the issue I'll send you the template on your email: contact@javascript-ninja.fr

@edi9999
Copy link
Member

edi9999 commented Apr 2, 2020

Ok, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants