Skip to content

fix: inefficient merge check for large amount of merged cells within … #2691

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

aorsten
Copy link

@aorsten aorsten commented Feb 15, 2024

When there are a lot of merged cells within a worksheet, e.g. 30.000 merged cells (e.g. the same 2 cells are merged in every row in a 30.000 row table), parsing mergeCells is increasingly slow. This is due to the inefficient conflict check within _mergeCellsInternal(dimensions, ignoreStyle) in worksheet.js.

Summary

My motivation is to let these big files function, rather than load forever. I believe the massive check is unnecessary. Rather than check every other merged range, can't you just see if any of the cells in the new range are merged, and then throw an error?

I do not know the original motivation for the throw new Error('Cannot merge already merged cells'); error, and whether it always breaks the program, or if the error is caught somewhere. Hopefully the new implementation is much more efficient without breaking anything.

Test plan

See the issue #2689
I have attached a file there. Loading that file goes from 1.5 minutes in node JS to only seconds. In the browser that file just will not load.

Related to source code (for typings update)

Copy link

@markygab markygab left a comment

Choose a reason for hiding this comment

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

Hi there, you change will indeed make it much faster, but you've got a couple of errors that prevent it from running atm

// apply merge
const master = this.getCell(dimensions.top, dimensions.left);
// check cells aren't already merged
if (master.isMerged()) {

Choose a reason for hiding this comment

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

isMerged is not a function, its a getter so you need this.

Suggested change
if (master.isMerged()) {
if (master.isMerged) {

Copy link
Author

Choose a reason for hiding this comment

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

@markygab I'm sorry, I didn't notice your review until now, and I am super busy at work and home with something else. Are you or anyone else able to apply your suggestions and test them? I recall that I did test my functionality in my own application, and it seemed to work, but perhaps I just didn't notice there was a bug somewhere.

Copy link
Author

Choose a reason for hiding this comment

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

Or, if you need me to, I could use the github UI to apply suggestions, so you could review again. Let me know. :)

this.getCell(i, j).merge(master, ignoreStyle);
cell = this.getCell(i, j);
// check cells aren't already merged
if (cell.isMerged()) {

Choose a reason for hiding this comment

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

Same here

@3ximus
Copy link

3ximus commented Apr 17, 2025

I've applied the suggested comments on this PR: #2920 (preserving the author's commit)
So you could discard this one so you could apply the other one instead.
Cheers.

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.

3 participants