Python-docx: How do i set table style

Created on 16 Jan 2014  Â·  14Comments  Â·  Source: python-openxml/python-docx

Hi scanny.

How do i set table style?

When i using

document.add_table(rows=len(table_data), cols=len(table_data[0]),style="TableGrid")

I search the API , but i didn't find method do it, I need set table size and width and height and color and so on.

"Cell class" also didn't find any method support it.

Most helpful comment

You have to set it using Document object which contains all the styles. https://python-docx.readthedocs.io/en/latest/user/styles-understanding.html#table-styles-in-default-template
Like this

document = Document()
table.style = document.styles['Table Grid']

All 14 comments

I'm sorry,i just understood what's the alpha version mean.

so , Im waiting beta version.

table = document.add_table(rows, cols)
table.style = 'TableGrid'

http://python-docx.readthedocs.org/en/latest/api/table.html#docx.table.Table.style

Yes,I konw that ,But if i want set color to table , how can i do that, for example

table = document.add_table(rows, cols)
table.style = 'TableGrid'
table.row[0].style = "borderColor:red;background-color:gray"

and i need set font style , like ,color ,size ,and so on.

There's currently no way to define table styles within python-docx. However if the "template" document you start with contains table styles, you can use them by name as above.

So if you want a customized table style, just customize it in the template document you're using and apply it by name to the table.

Thanks scanny,
Actually i just try to use "template " ,
I use microsoft Word open 'default.docx' file ,and add something ,
But doesn't work , so could you give some advice ?

paste in the code you're using to open the document so I can see, like:

document = Document('base.docx')
def create_content_docx(proj_id,svgs,version):

    store_path = report_utils.get_archive_dir(proj_id,version)

    proj = survey_utils.get_project(proj_id)
    file_name = "/%s_c.docx " % proj.title_as_txt

    document = Document()

    document.add_heading(proj.title_as_txt, 0)

    document.add_paragraph(proj.title_as_txt , style="Title1")

    question_style = "Quote"

    proj_dict = get_struct_dict(proj_id,version)
    question_list = proj_dict.get("question_list")

    for index,question in enumerate(question_list):
        question_id = question.get("id")
        question_cid = question.get("cid")
        question_title = question_cid+":"+question.get("title")
        question_type = question.get("question_type")

        document.add_paragraph(question_title , style=question_style)

        if question_type in [4,5,7,100]:
            matrix_content(document,question)
        else:
            normal_question(document,question)

        document.add_paragraph("")

    document.save(store_path+file_name)

    return  get_docx_content_stream(proj_id,version)


def matrix_content(document,question):

    question_type = question.get("question_type")

    position_content = ""

    table = document.add_table(rows=len(question.get("matrixrow_list"))+1, cols=len(question.get("option_list"))+1,style="TableGrid")

    if question_type == enums.QUESTION_TYPE_MATRIX_SCORE:
        max_num = question.get("custom_attr").get("max_answer_num")
        position_content = u"%s" % (u" ★ " * int(max_num))

    if question_type == enums.QUESTION_TYPE_MATRIX_BLANK:
        position_content = "____________"

    if question_type == enums.QUESTION_TYPE_MATRIX_SINGLE:
        position_content = u" â—‹  "

    if question_type == enums.QUESTION_TYPE_MATRIX_MULTIPLE:
        position_content = u" â–¡  "

    for i,row in enumerate(table.rows):
        if i == 0:
            option_cells = table.rows[0].cells
            for j,option in enumerate(question.get("option_list")):
                if j == 0:
                    option_cells[j].text = ""
                option_cells[j+1].text = option.get("title")
        else:
            matrix_cells = table.rows[i].cells
            matrix_list = question.get("matrixrow_list")

            for j,m_cell in enumerate(matrix_cells):
                if j == 0:
                    m_cell.text = matrix_list[i-1].get("title")
                    continue
                m_cell.text = position_content 


def normal_question(document,question):
    question_type = question.get("question_type")
    custom_attr = question.get("custom_attr")
    option_style = ""

    for index,option in  enumerate(question.get("option_list")):
        option_content = option.get("title")

        if question_type == enums.QUESTION_TYPE_SCORE:
            max_num = custom_attr.get("max_answer_num")
            stars = u"★  " * int(max_num)
            option_content += stars

        if question_type in (enums.QUESTION_TYPE_BLANK,enums.QUESTION_TYPE_MULTIPLE_BLANK):
            option_content += "____________"

        sign = ""
        if question_type == enums.QUESTION_TYPE_SINGLE:
            sign = u" â—‹  "

        if question_type == enums.QUESTION_TYPE_MULTIPLE:
            sign = u"  â–¡  "
        content = "%s %s" % (sign,option_content)
        # add feature
        document.add_paragraph(content,option_style)


Because, My Project is website ,so the code maybe too long , so give me some information about how to set 'template ' , that's okay.

What you need to do is open a document in your Document() call, not just use the default.

  1. Create a blank document in Word and save it as 'template.docx'.
  2. Customize one of the table styles in 'template.docx' to look the way you want.
  3. Create a new table while still in Word, and apply the customized table style to it
  4. After that you can delete the table and save the file again.

After that you start a new document in python-docx using document = Document('template.docx') and it will use the file you customized. The table style you customized will be available to apply to tables you make with python-pptx. The table style name is the same as it is in Word, with all spaces removed. For example, 'Light Shading - Accent 1' becomes 'LightShading-Accent1'.

thanks very much!

glad it worked out Keith :)

I want to change font size of table content. I tried lots.

It seems the font of the previous paragraph is reused (which is a problem from Word itself). I used this not-so-beautiful workaround:

  • add a paragraph
  • set its font size
  • remove the paragraph

Then, the next table will have the deleted paragraph's font size.

Code:

doc.add_paragraph('')
paragraph = doc.paragraphs[-1]
paragraph.style.font.size = Pt(font_size)
p = paragraph._element
p.getparent().remove(p)
p._p = p._element = None
doc.add_table(...)

You have to set it using Document object which contains all the styles. https://python-docx.readthedocs.io/en/latest/user/styles-understanding.html#table-styles-in-default-template
Like this

document = Document()
table.style = document.styles['Table Grid']

Was this page helpful?
0 / 5 - 0 ratings