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

json_to_sheet mutates header array #2139

Closed
SheetJSDev opened this issue Oct 11, 2020 · 5 comments
Closed

json_to_sheet mutates header array #2139

SheetJSDev opened this issue Oct 11, 2020 · 5 comments

Comments

@SheetJSDev
Copy link
Contributor

While I try to change header titles by passing array of titles to options like below it does not override the headers. Instead it writes new headers first and original data with old headers again from next cell.

I am experiencing the same problem.

In addition, sheets js is mutating the header array passed in, which is not something I would ever expect.

Example:

const header = ['field2', 'field3'];
const data = [{field1: 'foo', 'field2': 'bar', 'field3': 'baz'}]

const worksheet = XLSX.utils.json_to_sheet(data, {header});

console.log(header); // RESULTS:  ["field2", "field3", "field1"]

Originally posted by @paustint in #1487 (comment)

@SheetJSDev
Copy link
Contributor Author

@paustint Suppose there were two missing fields:

const data = [
  {f1: 1, f2: 2, f3: 3, f4: 4}
];
const header = ['f1', 'f2'];

When the sheet is written, both f3 and f4 will be written after f1 and f2. The order is dependent on the order of presentation within the data itself. For example:

const data = [
  {f1: 1, f4: 4},
  {f2: 2, f3: 3},
];

The order will start with f1 then f2. The next column will be f4 and then the next column will be f3. If you flip the order in the array, like

const data = [
  {f2: 2, f3: 3},
  {f1: 1, f4: 4},
];

the write order will be f1, f2, f3, f4.

We needed a way to communicate that ordering back to the caller. Since elements are never removed (they are only appended if data objects have headers that are missing), mutating the array preserves the intent and lets you chain into subsequent calls of sheet_add_json:

const header = ['f1', 'f2'];
const worksheet = XLSX.utils.json_to_sheet([
  {f2: 2, f3: 3},
], {header});
XLSX.utils.sheet_add_json(worksheet, [
  {f1: 1, f4: 4},
], {header, origin: -1, skipHeader: true});

@paustint
Copy link
Contributor

I understand. Many libraries will ignore extra headers if they are not included in the first row of data if a headers array not explicitly specified and I think that sheetsjs has the better approach of not requiring all rows to be the exact same shape.

I now understand the tradeoffs much better, thank you for taking the time to explain.

@SheetJSDev
Copy link
Contributor Author

Now that you understand this, maybe you can help improve the docs :) We'll accept a PR that clarifies the behavior.

@himanshusaini111
Copy link
Contributor

@SheetJSDev Hi, This issue is still open. So I raised a PR with suggested Changes

Now that you understand this, maybe you can help improve the docs :) We'll accept a PR that clarifies the behavior.

himanshusaini111 added a commit to himanshusaini111/sheetjs that referenced this issue Jan 6, 2021
moved the note below the table
@reviewher
Copy link
Contributor

af34ae4

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

No branches or pull requests

5 participants
@paustint @SheetJSDev @himanshusaini111 @reviewher and others