Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to split merged cells in excel workbook using python

Tags:

python

Is there any way to split/unmerge cells in excel workbook using python? What I want is explained below -

enter image description here

The result should a new excel file with following entries -

enter image description here

My solution using xlrd to copy the same string for all merged column is as given below -

[Note: "formatted_info = True" flag is not yet implemented in xlrd which I am using hence I cannot directly get the list of merged cells.. I am not supposed to upgrade xlrd on the setup.]

def xlsx_to_dict():
    workbook = xlrd.open_workbook(xlsfile)
    worksheet_names = workbook.sheet_names()
    for worksheet_name in worksheet_names:
        worksheet = workbook.sheet_by_name(worksheet_name)
        num_rows = worksheet.nrows - 1
        num_cells = worksheet.ncols - 1
        curr_row = -1
        header_row = worksheet.row(0)
        columns = []
        for cell in range(len(header_row)):
            value = worksheet.cell_value(0, cell)
            columns.append(value)

        cities = []

        for row in range(1,num_rows):
            value = worksheet.cell_value(row,0)
            type = worksheet.cell_type(row,0)
            if  not value == "":
                cities.append(value)

        names = []
        for row in range(1,num_rows):
            value = worksheet.cell_value(row,1)
            type = worksheet.cell_type(row,1)
            if  not value == "":
                names.append(value)

            current_city = cities[0]
            result_dict = {}
            for curr_row in range(1,num_rows):
                row = worksheet.row(curr_row)
                curr_cell = -1
                curr_name = names[0]
                while curr_cell < num_cells:
                    curr_cell += 1
                    cell_value = worksheet.cell_value(curr_row, curr_cell)
                    if cell_value in cities and curr_cell == 0:
                        current_city = cell_value
                        if not result_dict.has_key(current_city):
                            result_dict[current_city] = {}
                        continue
                    if cell_value == "" and curr_cell == 0:
                        continue
                    if cell_value in names and curr_cell == 1:
                        curr_name = cell_value
                        if not result_dict[current_city].has_key(curr_name):
                            result_dict[current_city][curr_name] = {}
                        continue
                    if cell_value == "" and curr_cell == 1:
                        continue
                    try:
                        result_dict[current_city][curr_name]['Phone'].append(cell_Value)
                    except:
                        result_dict[current_city][curr_name]['Phone'] = [cell_value]

The above function will return python dictionary as below -

{ 'New York' : { 'Tom' : [92929292, 33929] }, ........}

I will then traverse the directory and write new excel.

However, I want some generic way of splitting merged cells.

like image 707
Abhishek Kulkarni Avatar asked Mar 01 '26 19:03

Abhishek Kulkarni


1 Answers

This function gets the "real" cell value, i.e., the value of the merged cell if the coordinates are anywhere inside the merged cell.

def unmergedValue(rowx,colx,thesheet):
    for crange in thesheet.merged_cells:
        rlo, rhi, clo, chi = crange
        if rowx in xrange(rlo, rhi):
            if colx in xrange(clo, chi):
                return thesheet.cell_value(rlo,clo)
    #if you reached this point, it's not in any merged cells
    return thesheet.cell_value(rowx,colx)

Loosely based on http://www.lexicon.net/sjmachin/xlrd.html#xlrd.Sheet.merged_cells-attribute

Very innefficient, but should be acceptable for small-ish spreadsheets.

like image 154
Emilio M Bumachar Avatar answered Mar 04 '26 08:03

Emilio M Bumachar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!