qrilka / xlsx

Simple and incomplete Excel file parser/writer
MIT License
128 stars 62 forks source link

Leaking merge information across worksheets #142

Open vst opened 2 years ago

vst commented 2 years ago

When using Codec.Xlsx.Formatted.formatWorkbook, it seems that the merge information is accumulating as new worksheets are added.

In the below example:

  1. fcm1 has a formatted cell at (1,1) with colspan being 2, and
  2. fcm2 has a formatted cell at (20,1) with colspan being 2.
let xlsx = XF.formatWorkbook [("Sheet 1", fcm1), ("Sheet 2", fcm2)] X.minimalStyleSheet

Looking in the output, however, Sheet 2 has merged cells for both (1,1) (leaking from first sheet's data) and (20,1) (as expected):

image

and

image

... because Xlsx has following merge information:

Xlsx {_xlSheets = [("Sheet 1",
                    Worksheet {_wsColumnsProperties = [],
                               -- TRUNCATED
                               _wsMerges = [CellRef {unCellRef = "A1:B1"}],
                               -- TRUNCATED
                   ("Sheet 2",
                    Worksheet {_wsColumnsProperties = [],
                               -- TRUNCATED
                               _wsMerges = [CellRef {unCellRef = "A1:B1"},
                                            CellRef {unCellRef = "A20:B20"}],
                               -- TRUNCATED

The suspect seems to be the stateFromStyleSheet that keeps accumulating merge information regardless of related worksheet.

Do we really need to keep merge information as a global state variable? Or could we associate merge information with the worksheet?

Or am I getting it all wrong?

Edit: It is formatCell that updates the global merge information as it does not know anything about the worksheet?

vst commented 2 years ago

Issued a PR (#143) that works for me.

In summary, it resets merge information in formatWorkbook when starting to process new worksheet data.