docx-templates icon indicating copy to clipboard operation
docx-templates copied to clipboard

New line character inside a variable does not work

Open lattam opened this issue 3 years ago • 15 comments

Hello, I'm trying to replace a variable that contains newline character \n. But this line break is not rendered in the output file, it's just ignored.

address.docx

const content = fs.readFileSync('/tmp/address.docx');

const wordBuffer = await createReport({
  template: content,
  cmdDelimiter: ['{{ ', ' }}'],
  data: { address: 'City\nCountry'},
  // processLineBreaks: true,
});

fs.writeFileSync('/tmp/test.docx', wordBuffer);

Expected output

City
Country

Actual output

CityCountry

I even tried to specify processLineBreaks: true (though it should be a default value) but without any change.

Thanks for help!

lattam avatar Jul 29 '20 12:07 lattam

@lattam for your report! Neat repro case as well.

Weirdly, I wasn't able to reproduce this (see commit https://github.com/guigrpa/docx-templates/commit/4743cba35fcfc9892f8327720bad071b537b1bc9). The rendered document turned out exactly as expected...

Which version of docx-templates and MS Word are you using?

jjhbw avatar Aug 05 '20 16:08 jjhbw

As I couldn't reproduce this problem, i'll close this issue for now. Feel free to reopen if it persists. Please make sure you're running a fully updated version of MS Word (or equivalent) and are using the latest version of the library.

jjhbw avatar Aug 18 '20 12:08 jjhbw

I am also seeing this same issue.

"docx-templates": "^4.5.0",

cv-debug-clean.docx

(async() => {
  const fs = require('fs');
  const { createReport } = require('docx-templates');
  const template = fs.readFileSync('./cv-debug-clean.docx');

  const headline = "I am a line\n\nAnd so am I!";

  const buffer = await createReport({
    template,
    data: {
      headline: headline,
    },
    processLineBreaks: true
  });

  fs.writeFileSync('cv.docx', buffer);

})();

Word for Mac version 16.41

Screenshot 2020-09-18 at 16 39 40

nickdunn avatar Sep 18 '20 15:09 nickdunn

When I upload the doc to Office 365 online and view in Word I see the same thing:

Screenshot 2020-09-18 at 16 45 36

When I upload to Google Docs I only see the second line:

Screenshot 2020-09-18 at 16 44 07

And when I use a free doc viewer online it shows the correct lines:

Screenshot 2020-09-18 at 16 44 32

nickdunn avatar Sep 18 '20 15:09 nickdunn

I have tried with v4.0.0 and v4.5.0, same result.

nickdunn avatar Sep 18 '20 15:09 nickdunn

That is super weird. I get the below result when running a test case based on your example (see https://github.com/guigrpa/docx-templates/commit/153afe7c5b98bb38ec78f3239fb328b5fcb3318f).

The resulting Word file seems correct... Maybe its because i'm using MS Word for Mac 16.16.26 instead of 16.41 or something, or maybe our runtime envs are different. Which compiler toolchain / runtime environment are you using? (i.e. angular, webpack, browserify, which version, etc.).

I'll flag this as a bug for now because even if the issue is caused by something outside of the library we'll probably want to prevent it somehow.

Screenshot 2020-09-21 at 16 31 12

jjhbw avatar Sep 21 '20 14:09 jjhbw

Really weird, today this is no longer happening and line breaks are coming through as expected. No change to package, Node or Word versions. Same test case as above. Genuinely no idea what happened — but I can't recreate it!

For reference I'm using this in Node directly (v12.14.1).

Same result (working) both writing to a file and returning via a buffer from an Express endpoint (res.end(new Buffer(buffer));).

I think maybe this can be closed again and I'll re-open if I hit the issue again and can narrow it down further.

Sorry to have potentially raised a false alarm.

nickdunn avatar Sep 22 '20 00:09 nickdunn

Hmmm super strange. No i dont think it was a false alarm. I get the same view as you when opening in Google drive. To me it seems like some viewers interpret the linebreak differently or not at all...

I'll keep it open for a while so i can study it some more when i find the time.

jjhbw avatar Sep 22 '20 07:09 jjhbw

AFAIK our implementation is up to 'spec' on this front (http://officeopenxml.com/WPtextSpecialContent-break.php), and I can't imagine there's some non-determinism at play in this library...

My working theory is that it is caused by heterogeneity in the MS Word reader landscape. MS Word (versions?), google drive, etc. aren't created equal, regretfully...

@nickdunn if you find a new example, please let me know. Thanks for your report!

jjhbw avatar Sep 22 '20 07:09 jjhbw

@jjhbw i replaced <w:br/> with </w:t></w:r><w:r><w:br/><w:t xml:space="preserve"> in processTempalte and it works correct in LibreOffice and Ms office 2007, but breaks next line formatting 2020-11-06_13-32

With <w:br/> correct work only in ms office 2007.

grinat avatar Nov 06 '20 10:11 grinat

I faced the same issue. LibreOffice completely ignored line breaks and Google drive lost some of the text. As a workaround I did this:

{{ FOR line in user.description.split("\n") }}
{{INS $line }}
{{ END-FOR line }}

With settings: cmdDelimiter: ['{{', '}}'] processLineBreaks: false

jvikstedt avatar Dec 09 '20 13:12 jvikstedt

As a complement, I noticed that \r are replaced by a space, and \n are replaced by nothing when opening in libre office 7.1.2.2. @jjhbw would you mind checking if that solution from a similar PHP lib is working ? https://github.com/PHPOffice/PHPWord/issues/838#issuecomment-334104306

(edit:) The referenced issue proposes to fix the bug like this:

You need to replace \n with </w:t><w:br/><w:t> the replacement string is without the \n

jalik avatar Apr 06 '21 05:04 jalik

the same issue here. New lines don't work. Using latest [email protected], macOS Big Sur 11.2.3, Node.js v15.12.0

intenser avatar Apr 08 '21 10:04 intenser

Fix for this issue is mentioned in #68

kracas avatar Aug 11 '21 13:08 kracas

Sadly it still doesn't work in LibreOffice 7.1.5.2 (Arch Linux) with latest [email protected], nodejs v16.5.0. LibreOffice's wrapper unoconv is widely used to convert docx to PDF automatically in docker containers and API wrapers like gotenberg.

fcpunk avatar Aug 26 '21 23:08 fcpunk

I have merged #182 into master. You can now add set the processLineBreaksAsNewText option to true to use the new line break injection behaviour. If no issues arise, we can probably make this the default behaviour in 5.x as it seems to improve compatibility with LibreOffice and Google Docs.

I can't push a new release to NPM now, because @guigrpa and I are working out some NPM permissions issues. Pulling the latest master commit into your package.json from GitHub is an alternative until the release is pushed.

jjhbw avatar Feb 23 '23 17:02 jjhbw

The NPM permissions issue has been resolved. I just published v4.10.0 and v4.11.0 to npm. Thanks all for your patience.

jjhbw avatar Mar 02 '23 14:03 jjhbw