tablepyxl icon indicating copy to clipboard operation
tablepyxl copied to clipboard

AttributeError: 'MergedCell' object attribute 'value' is read-only

Open kitqee opened this issue 5 years ago • 6 comments

Is it possible to make such a table?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    table {
      border-collapse: collapse;
    }

    table, th, td {
      border: 1px solid black;
    }

    th, td {
      padding: 8px;
      text-align: left;
    }
  </style>
</head>
<body>

<table>
  <tr>
    <th rowspan="2">Name</th>
    <th rowspan="2">Measure</th>
    <th colspan="3">Plan</th>
    <th colspan="3">Fact</th>
    <th rowspan="2">%</th>
  </tr>
  <tr>
    <th>Volume</th>
    <th>Price</th>
    <th>Total price</th>
    <th>Volume</th>
    <th>Price</th>
    <th>Total price</th>
  </tr>
  <tr>
    <th colspan="9">Section</th>
  </tr>
  <tr>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
  </tr>
  <tr>
    <th colspan="9">Subsection</th>
  </tr>
  <tr>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
    <td>value</td>
  </tr>
</table>

</body>
</html>
Now I get this error:
Traceback (most recent call last):
  File "/home/aesfur/workspace/osla-api/src/apps/building/__init__.py", line 27, in <module>
    tablepyxl.document_to_xl(table, 'data.xlsx')
  File "/home/aesfur/workspace/venv/osla/lib/python3.6/site-packages/tablepyxl/tablepyxl.py", line 96, in document_to_xl
    wb = document_to_workbook(doc, base_url=base_url)
  File "/home/aesfur/workspace/venv/osla/lib/python3.6/site-packages/tablepyxl/tablepyxl.py", line 86, in document_to_workbook
    table_to_sheet(table, wb)
  File "/home/aesfur/workspace/venv/osla/lib/python3.6/site-packages/tablepyxl/tablepyxl.py", line 68, in table_to_sheet
    insert_table(table, ws, 1, 1)
  File "/home/aesfur/workspace/venv/osla/lib/python3.6/site-packages/tablepyxl/tablepyxl.py", line 104, in insert_table
    row = write_rows(worksheet, table.body, row, column)
  File "/home/aesfur/workspace/venv/osla/lib/python3.6/site-packages/tablepyxl/tablepyxl.py", line 41, in write_rows
    cell.value = table_cell.value
AttributeError: 'MergedCell' object attribute 'value' is read-only

Process finished with exit code 1

openpyxl 3.0.3

kitqee avatar Jan 24 '20 08:01 kitqee

Did you find any workaround for this issue ?

DayDotMe avatar Jan 19 '21 15:01 DayDotMe

I'm getting the same error.

Jailtons7 avatar Jan 25 '21 15:01 Jailtons7

@Jailtons7 I was not able to find a workaround (tried older versions of tablepyxl and openpyxl) so I use this snippet in my frontend code, I hope it helps.

/**
 * Remove every rowspan in the table
 * Add a td to next row with the same text
 * @param table
 */

function removeRowspan(table) {
    for (let td of [...$(table).find("td[rowspan]")].filter(i => parseInt($(i).attr("rowspan")) > 1)) {
        td = $(td);
        const rowspan = parseInt(td.attr('rowspan'));
        let tr = td.parent().next();
        for (let i = 0; i < rowspan - 1; i++) {
            tr.prepend($('<td>').text(td.text())); // in my case colspan is always and only in first td
            tr = tr.next();
        }
        td.attr("rowspan", 1);
    }
}

DayDotMe avatar Jan 25 '21 16:01 DayDotMe

@MehdiBela Do you have the snippet wrote in python?

debparth avatar Mar 18 '21 06:03 debparth

I had a similar issue and I found a basic way to fix it using regex. I'll add this, in case it helps anyone else that might need it.

This function accepts a table as a string (must be separated by line) and returns it with the rowspans removed. Instead of spanning multiple rows like the last snippet did, it will put a blank cell in the spanned rows (I prefer the look of this but you can tweak it). It doesn't indent properly (and puts multiple

elements on the same line), but it worked for me without having to actually parse the tree.
def remove_rowspan(table):
    table = table.splitlines()
    new_table = []
    pattern = "<td rowspan=\"(\\d)\">(.*)</td>"
    rowspans = 0
    for line in table:
        match_rowspans = re.search(pattern, line)
        if match_rowspans:
            rowspans = int(match_rowspans.group(1)) - 1
            line = re.sub(pattern, "<td>" + match_rowspans.group(2) + "</td>", line)
        if rowspans > 0 and "<tr>" in line:
            line = line.replace("<tr>", "<tr><td> </td>")
            rowspans = rowspans - 1
        new_table.append(line)
        new_table_str = '\n'.join(new_table)
    return new_table_str

plastuk94 avatar May 26 '22 19:05 plastuk94

It worked for me. https://github.com/PaddlePaddle/PaddleOCR/discussions/12932

xgySTATISICT avatar Jul 08 '24 07:07 xgySTATISICT