Repetitive merge_range to same range causes warning in Excel 2016
See original GitHub issueHi,
When I, through a program error/bug, repetitively merge_range to the same range, Excel produces two warnings:
- We found a problem with some content in ‘Range.XLSX’. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes. Clicking Yes yields:
- Excel was able to open the file by repairing or removing the unreadable content. Removed records: Merge cells from /xl/worksheets/sheet2.xml part
I am using Python version 3.4.3 and XlsxWriter 0.8.6 and Excel 2016.
Here is some code that demonstrates the problem:
import xlsxwriter
workbook = xlsxwriter.Workbook('range.xlsx')
worksheet = workbook.add_worksheet()
merge_format = workbook.add_format({
'bold': True,
'align': 'center'
})
headings = (
("Alpha", "L1:W1"),
("Bravo", "X1:AI1"),
("Charlie", "AJ1:AU1"),
("Delta", "AV1:BG1"))
for (product, coordinates) in headings:
worksheet.merge_range("L1:W1", product, merge_format)
Granted it was my program error that caused the merge_format at the same coordinate. My guess is that all four merge_range functions were committed to the spreadsheet and when Excel saw all four merge_formats on the same range, Excel threw its hands up. In correcting/recovering the spreadsheet, Excel used the last value, Delta, in the range.
What I did not have time to test to see if a similar error occurs if I try to write to the same cell repetitively. Hope to follow up with a similar test in a couple of days. range.xlsx
Issue Analytics
- State:
- Created 7 years ago
- Comments:9 (5 by maintainers)
Top GitHub Comments
@hamx0r
If the first one is a genuine use case then you should open an issue in Pandas.
For the second one open an XlsxWriter issue with a small working example that shows the issue. Follow the instructions in the ISSUE_TEMPLATE.
Modify worksheet.merge_range to do something like the following:
Now what does that do? It mainly adds a call to this __insert_merged_range routine:
To support that, we must also modify the constructor as follows:
It’s handy to define an “overlap” function for half-open ranges. The proof of correctness is left as an exercise for the reader.
I’ll make an arbitrary decision for PERFORMANCE_THRESHOLD:
Now we need to figure out how to make a decently efficient MergeGroup object. A naive approach would simply compute a bounding box for the group, and use that bounding box as a way to possibly skip a detailed test of each contained block. In fact the bounding box idea is valuable, but we can do considerably better with the detailed test. Merge ranges will probably exhibit good spatial locality and alignment. We can take advantage of that fact with minimal pre-processing:
At this point, we have the upper rows representing a set of row equivalence classes.
We’re going to develop a simple run-length encoding of columns within the row equivalence classes. By considering merge blocks in left-to-right order by left bound, we get a surprisingly useful guarantee predicated on the knowledge that no two input blocks overlap:
Finally, we’d like to coalesce consecutive identical row classes:
The intersection test is now straightforward, although I’m going to defer solving the RLE intersection problem until later:
How can we tell which RLE lines are relevant to a given merge range? Like this:
Finally, we must solve the RLE_intersect problem. The solution is surprisingly straightforward. Proof of correctness is again left as an exercise to the reader. As a hint, recall that we’re dealing with half-open ranges.
The remaining unsolved open question is what to do if the number of merge groups gets large. I have an idea, but that is a problem for another day.
WARNING: I have not tested most of this code. I have only proved it correct. (I did considerable testing of RLE_intersect, though.)