Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do i set table style #9

Closed
keithsun80 opened this issue Jan 16, 2014 · 16 comments
Closed

How do i set table style #9

keithsun80 opened this issue Jan 16, 2014 · 16 comments

Comments

@keithsun80
Copy link

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.

@keithsun80
Copy link
Author

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

so , Im waiting beta version.

@scanny
Copy link
Contributor

scanny commented Jan 16, 2014

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

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

@keithsun80
Copy link
Author

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.

@scanny
Copy link
Contributor

scanny commented Jan 20, 2014

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.

@keithsun80
Copy link
Author

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 ?

@scanny
Copy link
Contributor

scanny commented Jan 20, 2014

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

document = Document('base.docx')

@keithsun80
Copy link
Author

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)


@keithsun80
Copy link
Author

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

@scanny
Copy link
Contributor

scanny commented Jan 20, 2014

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'.

@keithsun80
Copy link
Author

thanks very much!

@scanny
Copy link
Contributor

scanny commented Jan 20, 2014

glad it worked out Keith :)

@aslam-vs
Copy link

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

@TomTrogh
Copy link

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(...)

@an1mehacker
Copy link

an1mehacker commented Jan 2, 2020

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']

@PovilasKirna
Copy link

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'.

It has been too long, I scoured the internet for an answer. Thank you
16c

@sqmch
Copy link

sqmch commented May 7, 2021

The above solution works fine if you start with the template file, but I find myself in a situation where I'm injecting tables into an existing .docx file (which doesn't stay static and can change, so I can't do my template creation trick there), meaning that I use a separate Document() to create the table and then inject it to the main file. That means that what ever I do with the styles of the table file, all of that gets lost once the table goes to the main file and I'm left with just the standard Table Grid as my choice. Are there any other options for me here or am I doomed? I also need to do things such as color the background of a cell depending on the content, also something that would get lost after injecting the tables to the main file.

Are there any alternatives or longer solutions I could look into, or is this the pinnacle of what python can do for me when it comes to working with .docx files? Many thanks to whoever can provide some insights.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants