8

我正在使用带有 docx 的 python 2.7,我想根据条件更改表格中单元格的背景和文本颜色。

我找不到任何有关单个单元格格式的有用资源

有什么建议么?

编辑 1

我的代码

style_footer = "DarkList"
style_red = "ColorfulList"
style_yellow = "LightShading"
style_green = "MediumShading2-Accent6"
style_transperent = "TableNormal"
for a,rec in enumerate(data):
    #V headinh se piše prvo polje iz table heada
    document.add_heading(rec['tableHead'][0][0], level=1)
    image_path = imageFolder + "\\" + slike[a]
    document.add_picture(image_path, height=Inches(3.5))

    #y += 28
    #worksheet.insert_image( y, 1,imageFolder + "/" + slike[a])


    for i, head in enumerate(rec['tableHead']):
        table = document.add_table(rows=1, cols = len(head))
        hdr_cells = table.rows[0].cells
        for a in range(0,len(head)):
            hdr_cells[a].text = head[a] 


    for a,body in enumerate(rec['tableData']):
        row_cells = table.add_row().cells

        for a in range(0,len(body)):
            if body[a]['style'] == 'footer':
                stil = style_footer
            elif body[a]['style'] == 'red':
                stil = style_red

            elif body[a]['style'] == 'yellow':
                stil = style_yellow
            elif body[a]['style'] == 'green':
                stil = style_green

            else:
                stil = style_transperent

            row_cells[a].add_paragraph(body[a]['value'], stil)

document.save(wordDoc)

所有的细胞还是一样的。

4

7 回答 7

21

如果要对表格中的特定单元格进行颜色填充,可以使用下面的代码。例如,假设您需要用 RGB 颜色 1F5C8B 填充表格第一行中的第一个单元格:

from docx.oxml.ns import nsdecls
from docx.oxml import parse_xml

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[0].cells[1]._tc.get_or_add_tcPr().append(shading_elm_2)

...等等其他细胞。

来源:https ://groups.google.com/forum/#!topic/python-docx/-c3OrRHA3qo

于 2017-04-18T08:38:09.627 回答
4

我们发现,如果你做 cell.add_paragraph('sometext', style_object) ,它会保留现有的空段落并添加一个带有样式的附加段落,这并不理想。

你会想要做的是这样的:

# replace the entire content of cell with new text paragraph
cell.text = 'some text'
# assign new style to the first paragraph
cell.paragraphs[0].style = style_object 

请注意,样式应用于段落而不是单元格,这对于背景颜色并不理想(因为如果您有一些填充,它不会填充输入单元格。我还没有找到解决方法(除了在如果您希望每个单元格都具有背景颜色,则可以将样式应用于 table.style)。

另外,请确保您的样式已定义。你可以检查

styles = documents.styles
for s in styles:
  print s.name

查看您拥有的所有样式。您可以定义新样式,也可以加载带有预定义样式的模板文档。

于 2016-02-20T08:00:18.187 回答
4

使用 Nikos Tavoularis 的解决方案,我们必须为每个单元创建一个新元素。我创建了一个实现这一点的函数。适用于 Python 修订版 3.5.6 和 python-docx 修订版 0.8.10

from docx.oxml import OxmlElement
from docx.oxml.ns import qn

def set_table_header_bg_color(table.rows[row_ix].cell):
    """
    set background shading for Header Rows
    """
    tblCell = cell._tc
    tblCellProperties = tc.get_or_add_tcPr()
    clShading = OxmlElement('w:shd')
    clShading.set(qn('w:fill'), "00519E") #Hex of Dark Blue Shade {R:0x00, G:0x51, B:0x9E}
    tblCellProperties.append(clShading)
    return cell
"""
End of set_table_header_bg_color Function
"""
# main function
"""
..
..
..
1. Load Document
..
2. Access the required section
..
3. Load the required Table
..
4. Traverse to the cell by accessing the rows object
..
"""
for each_row in table.rows :
    for each_cell in each_row.cells:
        if each_cell.value satisfies a condition:
            set_table_header_bg_color(each_cell)
"""
5. Continue execution
"""
于 2020-05-29T05:05:24.677 回答
3

看起来不是使用cell.text = "Something"您需要使用cell.add_paragraph("SomeText", a_style)定义样式的方法 - 可能是以下之一:

  • 炫彩网格
  • ColorfulGrid-Accent1
  • ColorfulGrid-Accent2
  • ColorfulGrid-Accent3
  • ColorfulGrid-Accent4
  • ColorfulGrid-Accent5
  • ColorfulGrid-Accent6

完整列表在这里

如果您使用“默认”模板文档 - 否则您将不得不创建自己的。

于 2014-11-05T09:13:07.473 回答
0

如果要循环遍历一行中的单元格,请使用:

def color_row(row=0):
    'make row of cells background colored, defaults to column header row'
    row = t.rows[row]
    for cell in row.cells:
        shading_elm_2 = parse_xml(r'<w:shd {} w:fill="1F5C8B"/>'.format(nsdecls('w')))
        cell._tc.get_or_add_tcPr().append(shading_elm_2)

运行函数为第二行中的单元格着色

color_row(2)

于 2020-07-01T00:21:37.263 回答
0

从 Nikos Tavoularis 的回答中,我只会更改 shading_elm_1 声明,就好像您在循环中包含单元格颜色一样,例如事情可能会变得混乱。

因此,我的建议是:

from docx.oxml.ns import nsdecls
from docx.oxml import parse_xml

table.rows[0].cells[0]._tc.get_or_add_tcPr().append(parse_xml(r'<w:shd {} w:fill="1F5C8B"/>'.format(nsdecls('w'))))
于 2019-10-11T17:39:40.580 回答
0

我制作了一个视频,展示了一种方法,我从上面的人那里得到了灵感,但我仍然遇到问题,所以我也做了这个来帮助其他人。

https://www.youtube.com/watch?v=1Mgb95yigkk&list=PL_W7lgC2xeJfWBUllp7ALKOM5GUBMCVoP

    from docx import Document
    from docx.oxml import OxmlElement
    from docx.oxml.ns import qn
    document = Document("youfile.docx")
    Table = document.tables[0]

    #GET CELLS XML ELEMENT
    cell_xml_element = Table.rows[1].cells[0]._tc
    #RETRIEVE THE TABLE CELL PROPERTIES
    table_cell_properties = cell_xml_element.get_or_add_tcPr()
    #CREATE SHADING OBJECT
    shade_obj = OxmlElement('w:shd')
    #SET THE SHADING OBJECT
    shade_obj.set(qn('w:fill'), "ff00ff")
    #APPEND THE PROPERTIES TO THE TABLE CELL PROPERTIES
    table_cell_properties.append(shade_obj)

    document.save("yoursavefile.docx")

上面的代码将更改文档中第一个表格的第二行的第一个单元格。输出示例。

于 2022-03-04T04:04:07.133 回答