Skip to content

[ZEPPELIN-6699] React remote CSV export omits the UTF-8 BOM that the Angular and classic paths write - #5466

Open
xhaktm00 wants to merge 1 commit into
apache:masterfrom
xhaktm00:ZEPPELIN-6699
Open

[ZEPPELIN-6699] React remote CSV export omits the UTF-8 BOM that the Angular and classic paths write#5466
xhaktm00 wants to merge 1 commit into
apache:masterfrom
xhaktm00:ZEPPELIN-6699

Conversation

@xhaktm00

@xhaktm00 xhaktm00 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

What is this PR for?

The React remote builds its CSV export by hand and hands the string straight to a Blob with no UTF-8 BOM, so Excel reads it in the system code page and garbles non-ASCII data. The classic path prepends one through saveAsService, and the Angular path gets one from XLSX.writeFile(), so only this export was missing it. ZEPPELIN-672 added the BOM for exactly this reason.

- const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
+ const BOM = '\uFEFF';
+ const blob = new Blob([BOM, content], { type: 'text/plain;charset=utf-8' });

The xlsx branch is left alone, since that format carries its own encoding.

What type of PR is it?

Bug Fix

Todos

  • Prepend the BOM in the React remote CSV export
  • Add a regression test asserting the saved bytes

What is the Jira issue?

How should this be tested?

New spec exportFile.spec.ts mocks file-saver and inspects the bytes handed to saveAs, since Blob.text() decodes and drops a leading BOM.

cd zeppelin-web-angular/projects/zeppelin-react && npm test

Result: Tests 1 failed | 67 passed (68). The one failure is HTMLRenderer.spec.tsx > highlights a code block, which fails the same way on origin/master without this change. Running the new spec alone passes:

npx vitest run src/utils/exportFile.spec.ts   → Tests 2 passed (2)

Reverting only the production change makes it fail with expected [ 110, 97, 109 ] to deeply equal [ 239, 187, 191 ], so it does catch the defect.

Manual: run a paragraph whose table result contains non-ASCII text, open the published paragraph with ?react=true, and choose "Export all data as csv". The file now starts with EF BB BF and opens in Excel with the text intact.

Screenshots (if appropriate)

N/A

Questions:

  • Does the license files need to update? No
  • Is there breaking changes for older versions? No — the BOM only makes the React export match what the other two paths already write
  • Does this needs documentation? No

Note: the issue scopes this to CSV and TSV, but the React remote has no TSV path, since exportFile() only takes 'csv' | 'xlsx'. I'll file that parity gap separately; the BOM sits on the shared branch, so a TSV path added there inherits it.

The React remote builds its CSV by hand and hands the string straight to a
Blob, with no BOM, so Excel reads it in the system code page and garbles
non-ASCII data. The classic path prepends one through saveAsService, and the
Angular path gets one from XLSX.writeFile(), so only this export was missing it.

ZEPPELIN-672 added the BOM for exactly this reason. The xlsx branch is left
alone since that format carries its own encoding.

@voidmatcha voidmatcha left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

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

Successfully merging this pull request may close these issues.

2 participants