exceljs / exceljs

Excel Workbook Manager

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue with writing newlines

zhm opened this issue · comments

I'm having an issue writing \n to cells. It's stripping them from the file. I'm using version 0.4.2.

When I monkey patch exceljs to use the entities module, it works correctly.

This is not a permanent fix, just demonstrating how to patch it.

var utils = require('exceljs/lib/utils/utils');
utils.xmlEncode = require('entities').encodeXML;

Looking at the xmlEncode function it does look like it's wrong, it's not allowing \n (0x0A) through.

This was actually one of the things that was fixed in 0.4.2 - a2d2ce6 - check that you're actually using the right version.

I too have this problem. Using 0.4.6.

I'm using v0.4.3 and was having a problem with new lines \r\n not appearing using code below:

problem - line breaks don't appear in Excel

{
    richText: [...names, {
	font,
	text: `\r\n${tags.join(', ')}`
    }]
}

Line breaks would only appear if I opened in Numbers on macOS. Line breaks would not appear in Excel Viewer, Excel Online, or Excel on Windows 10.

By adding a space before \r\n it now works!

workaround

{
    richText: [...names, {
	font,
	text: ` \r\n${tags.join(', ')}`
    }]
}

@mrmusa Where is your workaround code located? Is that within the library or your own code?

I have added a space before the \n characters and there is no change. All newlines are still being stripped. For some reason, sometimes the newlines will stay. Most of the time they don't. I've tried modifying the ExcelJS.js file directly, but that doesn't seem to have changed a thing.

@mrmusa I'm using v0.4.11 but can switch to v0.4.3 if that's how you got it to reliably work

@shivavelingker - Yes that's the only version I've used. I haven't upgraded due to some changes here which cause exceljs to fail my build. I don't have anytime to look into it so I'm sticking with the version that works. Did upgrading help?

v0.4.11 didn't work for me and neither did v0.4.3 (I'm not sure if your changes were to the docs or to your own code, so I didn't modify anything). I've just downgraded to v0.2.38 until this issue gets resolved, if ever. It seems to be working well for me.

Considering that it's an MS product, could it be that it's specifically wanting \r\n rather than plain \n? Maybe worth someone who's having this problem testing a .replace(/\n/g,"\r\n") on things?

I'm also having an issue with this. I'm specifically passing in \r\n and it's not separating values by a new line when opened in Excel.

From what I can tell, the PR mentioned above doesn't actually let new lines through. When I stream the data to create a workbook, I'm manually pushing CR+LF when parsing arrays, something like this:

r.map(c => Array.isArray(c.value) ? c.value.reduce((acc, value, index) => acc + (index > 0 ? '\r\n' : '') + value, '') : c.value);

Which would give something like:
Val 1\r\nVal2\r\n...

When I get to the xmlEncode function referenced here, I can see in the debugger that there is in fact a line break in text:

image

However, it's hitting the 'default' case of that switch, so it's just replacing it with an empty string.

I've tried updating that code to handle line breaks (adding a case checking '\n'), but it seems like no matter what characters I replace the line break with, it's still getting stripped out somewhere else, or maybe isn't in the right format. I'm not 100% sure what the format would be, but I assume some kind of XML. Looking at other spreadsheets I have that have correct line breaks in them, when saved as XML, I'm assuming some kind of XML line feed, like 
 or 
. I've also tried pushing XML codes for new lines instead of the \r\n but that does not seem to work either.

Would love any kind of guidance on this.

What's weird is that I did that PR, and using it here lets them through, hence my wondering if it could be character encoding somewhere...

Ugh - looking at it, the \x0D is getting through (carriage return), but \x0A is getting hit by that default - how about trying to change that one line to -

return text.replace(/[<>&'"\x7F\x00-\x08\x0B-\x0C\x0E-\x1F]/g, function (c) {

If that doesn't in fact fix it, then might be worth standardising the output and replacing any \n with \r in that switch, and making sure we don't accidentally change \r\n into \r\r...

(Just to note, I actually looked at the XML specs, hence changing the ranges, wasn't looking at the actual character codes).

That does allow the new line to get through, but it appears to still be getting stripped out somewhere unfortunately.

Are you able to actually see the new lines in the resulting Excel file? Do you happen to have any examples of the code you're using to test? And/or an output Excel file?

@Rycochet I tried that myself a couple weeks ago, but it didn't work for me. Nor did having a separate case for new lines work either. Even if I took out the text replacement for the entire range \x0A-\x1F the new line would still get stripped, which is why this is quite befuddling.

Ok, I think I've got a solution working for new lines.

@Rycochet, can you PR the change you posted above, that lets the new line through? Nvm, I PR'd it.

With that change, I had to do two other things:

  1. When constructing the WorkbookWriter, I needed to use the useSharedStrings and useStyles properties:

this.workbook = new Excel.stream.xlsx.WorkbookWriter({ useSharedStrings: true, useStyles: true });

  1. When creating the workbook columns, I had to set the wrapText style property to true:

{ header: columnName, key: columnKey, width: 10, style: { alignment: { wrapText: true } } }

Just pushed 0.4.13 which should fix this

I'm on 0.5.1 and this issue isn't fixed...
Edit -- okay, you really do still have to use style: { alignment: { wrapText: true } } when creating the column

That will work...

@guyonroche @Rycochet @holly-weisser
This is still an issue for the browser version where streaming is not supported.
I am using version 4.1.1 and if I add '\n' or '\r\n' in the text, I am getting this error while opening the generated Excel file:
"We found a problem with some content in .xlsx. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes."
If I click yes, then the file is recovered correctly and line breaks are showing correctly. But this is not acceptable for users...

@guyonroche @Rycochet @holly-weisser
sorry, to be more precise, the issue I reported above is happening in the worksheet addTable method when a column name contains '\n' or '\r\n'.

@guyonroche @Rycochet @holly-weisser sorry, to be more precise, the issue I reported above is happening in the worksheet addTable method when a column name contains '\n' or '\r\n'.

I have the same problem too