The Wayback Machine - https://web.archive.org/web/20201109073845/https://github.com/SheetJS/sheetjs/issues/2139
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

Open
SheetJSDev opened this issue Oct 11, 2020 · 3 comments
Open

`json_to_sheet` mutates header array #2139

SheetJSDev opened this issue Oct 11, 2020 · 3 comments

Comments

@SheetJSDev
Copy link
Contributor

@SheetJSDev SheetJSDev commented Oct 11, 2020

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

@SheetJSDev SheetJSDev commented Oct 11, 2020

@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

@paustint paustint commented Oct 11, 2020

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

@SheetJSDev SheetJSDev commented Oct 11, 2020

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

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

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.