odfpy: need to copy an existing table

507 views Asked by At

I have an issue with odfpy and Python 3. I try to copy an existing table in an Opendocument Text file. I'm failing at getting the style information out of the original table. Here is my code:

# templateTable is a table.Table that has to be copied
for childNode in templateTable.childNodes:
    if 'style-name' in str(childNode.attributes):
        # the next command fails and the python interpreter tells me
        # 'style-name' is not in list
        style = childNode.getAttribute('style-name')

Help is welcome!

3

There are 3 answers

0
Ariq Ahmer On

I had to figure out what you actually did. Anyone else trying to figure out what OP did, basically remove the dashes/hyphens from the attribute names. So in this case, style-name becomes stylename. So if you have draw:style-name attribute, just pass in it as stylename instead of style-name

0
Cookie1980 On

I finally found a solution on my own. I would like to share it with you in case someone else has to work on the same problem as I had. You can find the code here.

def copyTable(document, tableSource, tableDestination):
    # document is of odf.opendocument
    # tableSource is a string with the name of the source table
    # tableDestination is a string with the name of the destination table
    
    # get all tables in document
    allTables = document.getElementsByType(table.Table)
    templateTable = None
    for xTable in allTables:
        if hasattr(xTable, 'attributes'):
            tableName = xTable.getAttribute('name')
            
            if tableName == tableSource:
                templateTable = xTable
                
    if templateTable is None:
        print('Table not found')
        return
        
    # first need to know about the columns in the original table
    cols = templateTable.getElementsByType(table.TableColumn)
    
    # create a new table for the copy
    copyTable = Table(name=tableDestination)
    
    # run through all columns and create a new column in the destination table
    # for each column in the source table
    for itm in cols:
        colNew = TableColumn()
        # copy the stylename of the column (needed for columnwidth
        colNew.setAttribute('stylename', itm.getAttribute('stylename') )
        
        # add the created column to the destination table
        copyTable.addElement(colNew)

    # get all rows from the original table
    rows = templateTable.getElementsByType(table.TableRow)
    
    #run through all rows
    for tempRow in rows:
        # create a new roz
        tr = TableRow()
        
        # get all cells from the original table
        cells = tempRow.getElementsByType(table.TableCell)
        
        # run through all cells 
        for tempCell in cells:
            # create a new cell
            cell = TableCell()
            
            # copy the attributes
            cell.setAttribute('stylename', tempCell.getAttribute('stylename') )
            cell.setAttribute('numbercolumnsspanned', tempCell.getAttribute('numbercolumnsspanned') )
            cell.setAttribute('numbermatrixcolumnsspanned', tempCell.getAttribute('numbermatrixcolumnsspanned') )
            
            # get all parapgraphs from the cell
            paras = tempCell.getElementsByType(text.P)
            for paraTemp in paras:
                # extract the text
                old_text = teletype.extractText(paraTemp)
                # create a new paragraph
                para_copy = P(text=old_text)
                # append paragraph to the cell
                cell.addElement(para_copy)
            
            # add the cell to the row   
            tr.addElement(cell)
            
        # append row to the destination table
        copyTable.addElement(tr)
        
    
    templateTable.parentNode.addElement(copyTable)
    templateTable.parentNode.addElement(P() )
0
Antonio Atomico Ritucci On

For anyone still here this is simple as this:

def fetch_sheet_table_by_name(doc, name_of_sheet):
    for sheet_ in doc.spreadsheet.getElementsByType(Table):
        sheet_name_ = sheet_.getAttribute("name")
        if sheet_name_ == name_of_sheet:
            return sheet_
    return None

def copyTable(document, tableSource, tableDestination, temp_document_name):
    document.save(temp_document_name)
    temp_document = load(temp_document_name)
    table_to_copy = fetch_sheet_table_by_name(temp_document, tableSource)
    table_to_copy.setAttribute("name", tableDestination)
    document.spreadsheet.addElement(table_to_copy)
    return document