-1

I am trying to automate the generation of a report by taking data out of excel and putting into a word document with tables . I know how to read from excel and write to word , but I am trying to generate a specific type of table in the word document and I cannot figure out how. I am relatively new to using the 'docx' package so I am not too savvy with the 'add_table' function, but from what I find, the function isn't very customizable and I am not able to find a way to generate the table I want. Here is a pic of the table I want to make, which I custom made in Word. enter image description here

Note that the first row has 5 columns which are subdivided into 10 columns (2 under each original column) in the second row. this is the result I am trying to achieve. If you can show me how to make them all different colors that would be a huge bonus! Also, I am not restricting myself to 'docx' package, I am open to using any other package that would create a table that can be saved as a .jpg or something of the sort.

Charlie Clark
  • 18,477
  • 4
  • 49
  • 55
  • Possible duplicate of [python-docx how to merge row cells](https://stackoverflow.com/questions/55717088/python-docx-how-to-merge-row-cells) – Smart Manoj Jun 04 '19 at 15:40

1 Answers1

0
from docx import Document 
# Importing the necessary functions to set the row height
from docx.shared import Cm
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
# Importing the required functions to set the required shading of a cell
from docx.oxml.ns import nsdecls
from docx.oxml import parse_xml
# Importing the required function to align our text inside the cells
from docx.enum.text import WD_ALIGN_PARAGRAPH 

First of all we need some helper functions.

We will create a function that merges 2 cells, into 1 cell:

def merge_two_cells(my_table, row_number, start_from_cell):
    a = my_table.rows[row_number].cells[start_from_cell]
    A = a.merge(my_table.rows[row_number].cells[start_from_cell+1])

Creating a function for setting the row height

def setRowHeight(row, height):
    """
    Sets the height of a table row.

    `Row` is a `docx.table._Row` object. `height` is the desired height in EMU.
    """
    trHeight = OxmlElement('w:trHeight')
    trHeight.set(qn('w:val'), str(height.twips))

    trPr = OxmlElement('w:trPr')
    trPr.append(trHeight)

    row._tr.append(trPr)

Creating the document:

document = Document()

table = document.add_table(rows=3, cols=10, style='Table Grid')

setRowHeight(table.rows[2], Cm(2))
## ...etc

merge_two_cells(table, 0, 0)
merge_two_cells(table, 0, 2)
merge_two_cells(table, 0, 4)
merge_two_cells(table, 0, 6)
merge_two_cells(table, 0, 8)

table.rows[0].cells[0].text = 'A'
table.rows[0].cells[2].text = 'B'
table.rows[0].cells[4].text = 'C'
table.rows[0].cells[6].text = 'D'
table.rows[0].cells[8].text = 'E'

table.rows[1].cells[0].text = 'a.1'
table.rows[1].cells[1].text = 'a.2'
table.rows[1].cells[2].text = 'b.1'
## ...etc

table.rows[2].cells[0].text = '1'
## ...etc

#For the shading check here:
#https://stackoverflow.com/questions/26752856/python-docx-set-table-cell-background-and-text-color/43467445#43467445

shading_elm_1 = parse_xml(r'<w:shd {} w:fill="1F5C8B"/>'.format(nsdecls('w')))
table.rows[0].cells[0]._tc.get_or_add_tcPr().append(shading_elm_1)

shading_elm_2 = parse_xml(r'<w:shd {} w:fill="1F5C8B"/>'.format(nsdecls('w')))
table.rows[1].cells[0]._tc.get_or_add_tcPr().append(shading_elm_2)

shading_elm_3 = parse_xml(r'<w:shd {} w:fill="F7CAAC"/>'.format(nsdecls('w')))
table.rows[0].cells[2]._tc.get_or_add_tcPr().append(shading_elm_3)
## ...etc

table.rows[0].cells[0].paragraphs[0].paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
## ...etc

document.save('my_test.docx')
Nikos Tavoularis
  • 2,843
  • 1
  • 30
  • 27