python操作word表格格式


 

簡介

python-docx--設置表格進階

在上面的博客中,主要介紹了如何合並、拆分表格等,中間用到了一些表格的基本設置,比如,指定表格樣式,內容居中等,在這篇博客中,詳細介紹這一部分

需求

1. 表格樣式修改

2. 列寬高設置

3. 屬性設置(居中)

4. 給每個單元格賦值

5. 設置表格邊框

模板設置

只需要在word中插入以下標簽

{{p mysubdoc}}

實現一:表格樣式修改

1. 代碼

from docxtpl import DocxTemplate
from docxtpl import Document
from docx.shared import Inches
import re
import json
import collections
 
 
tpl = DocxTemplate('test.docx')
sd = tpl.new_subdoc()
sd.add_paragraph('Drug Table :')
rows=3
cols=4
###創建表格的時候,指定style,這個style可以是docx的樣式,例如"Table Grid"
###style也可以是在word中自定義的表格樣式
table = sd.add_table(rows=rows, cols=cols ,style='outertable')
 
#header
cells = table.rows[0].cells
cells[0].text="Gene"
cells[1].text="Drug"
cells[2].text="Rank"
cells[3].text="Description"
 
 
table.cell(1,0).text="ALK"
table.cell(1,1).text="GENE1"
table.cell(1,2).text="GENE2"
table.cell(1,3).text="haha"
#
# #https://python-docx.readthedocs.io/en/latest/api/table.html#docx.table.Table.style
# #merge
table.cell(2,0).merge(table.cell(2,3)).text="One Drug"
 
context = {
    'mysubdoc' : sd,
}
 
 
tpl.render(context)
tpl.save('vertical_merge.docx')

上面的add_table還可以寫成下面的格式

table = sd.add_table(rows=rows, cols=cols)
table.style = "outertable"

2. 結果

 實現二:列寬高設置

1. 代碼

若不特殊指定列寬,則每列會平均分配

需要注意的是,Cm設置失敗,不起作用,原因不明

from docxtpl import DocxTemplate
from docxtpl import Document
from docx.shared import Inches
import re
import json
import collections
from docx.shared import Cm
from docx.oxml.shared import OxmlElement, qn
 
tpl = DocxTemplate('test.docx')
sd = tpl.new_subdoc()
sd.add_paragraph('Drug Table :')
rows=3
cols=4
table = sd.add_table(rows=rows, cols=cols,style="outertable")
width = OxmlElement('w:tblW')
width.set(qn('w:type'), 'pct')
width.set(qn('w:w'), '5000')
table._tblPr.append(width)

#header
cells = table.rows[0].cells
cells[0].text="Gene"
cells[1].text="Drug"
cells[2].text="Rank"
cells[3].text="Description" 
 
table.cell(1,0).text="ALK"
table.cell(1,1).text="GENE1"
table.cell(1,2).text="GENE2"
table.cell(1,3).text="haha"
# #merge
table.cell(2,0).merge(table.cell(2,3)).text="One Drug"
 
table.rows[0].height = Cm(2)

col_width = [1,2,3,4]
for col in range(4):
    table.cell(0,col).width = Inches(col_width[col])
#需要注意的是,Cm設置失敗,不起作用
# table.cell(0,0).width = Cm(1)
# table.cell(0,1).width = Cm(2)
# table.cell(0,2).width = Cm(3)
# table.cell(0,3).width = Cm(4)

context = {
    'mysubdoc' : sd,
}
 
 
tpl.render(context)
tpl.save('vertical_merge.docx')

2. 結果

實現三:屬性設置 

1. 代碼

除了直接指定style之外,還可以對具體一個屬性進行設置,比如常用的居中設置

有表格的居中以及表格文本的居中

表格的居中設置

from docx.enum.table import WD_TABLE_ALIGNMENT

table = sd.add_table(rows=rows, cols=cols,style="outertable")
table.alignment = WD_TABLE_ALIGNMENT.CENTER

不過我們一般說的居中指的是表格里文本的居中

水平居中

直接設置整個表格居中 CENTER  LEFT RIGHT

table.style.paragraph_format.alignment=WD_PARAGRAPH_ALIGNMENT.CENTER

或者也可以

table.style.paragraph_format.alignment=WD_TABLE_ALIGNMENT.CENTER

from docxtpl import DocxTemplate
from docxtpl import Document
from docx.shared import Inches
import re
import json
import collections
from docx.shared import Cm
from docx.oxml.shared import OxmlElement, qn
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
 
tpl = DocxTemplate('test.docx')
sd = tpl.new_subdoc()
sd.add_paragraph('Drug Table :')
rows=3
cols=4
table = sd.add_table(rows=rows, cols=cols,style="outertable")
width = OxmlElement('w:tblW')
width.set(qn('w:type'), 'pct')
width.set(qn('w:w'), '5000')
table._tblPr.append(width)

#header
cells = table.rows[0].cells
cells[0].text="Gene"
cells[1].text="Drug"
cells[2].text="Rank"
cells[3].text="Description" 
 
table.cell(1,0).text="ALK"
table.cell(1,1).text="GENE1"
table.cell(1,2).text="GENE2"
table.cell(1,3).text="haha"
# #merge
table.cell(2,0).merge(table.cell(2,3)).text="One Drug"
 
##設置標題行的高度
table.rows[0].height = Cm(2)
##設置每一列的寬度
col_width = [1,2,3,4]
for col in range(4):
    table.cell(0,col).width = Inches(col_width[col])

#水平居中
table.style.paragraph_format.alignment=WD_PARAGRAPH_ALIGNMENT.CENTER

context = {
    'mysubdoc' : sd,
}
 
 
tpl.render(context)
tpl.save('vertical_merge.docx')

也可以挨個為每個cell,設置水平居中

from docxtpl import DocxTemplate
from docxtpl import Document
from docx.shared import Inches
import re
import json
import collections
from docx.shared import Cm
from docx.oxml.shared import OxmlElement, qn
from docx.enum.text import WD_ALIGN_PARAGRAPH
 
tpl = DocxTemplate('test.docx')
sd = tpl.new_subdoc()
sd.add_paragraph('Drug Table :')
rows=3
cols=4
table = sd.add_table(rows=rows, cols=cols,style="outertable")
width = OxmlElement('w:tblW')
width.set(qn('w:type'), 'pct')
width.set(qn('w:w'), '5000')
table._tblPr.append(width)

#header
cells = table.rows[0].cells
cells[0].text="Gene"
cells[1].text="Drug"
cells[2].text="Rank"
cells[3].text="Description" 
 
table.cell(1,0).text="ALK"
table.cell(1,1).text="GENE1"
table.cell(1,2).text="GENE2"
table.cell(1,3).text="haha"
# #merge
table.cell(2,0).merge(table.cell(2,3)).text="One Drug"
 
##設置標題行的高度
table.rows[0].height = Cm(2)
##設置每一列的寬度
col_width = [1,2,3,4]
for col in range(4):
    table.cell(0,col).width = Inches(col_width[col])

###為每一列設置居中
for row in range(3):
    for col in range(4):
        cell = table.cell(row, col)
        pa = cell.paragraphs[0]
        pa.alignment = WD_ALIGN_PARAGRAPH.CENTER  ##居中

context = {
    'mysubdoc' : sd,
}
 
 
tpl.render(context)
tpl.save('vertical_merge.docx')

垂直居中

目前我還不知道,如何給整個表格設置垂直居中

垂直共有3種格式:CENTER TOP BOTTOM

from docxtpl import DocxTemplate
from docxtpl import Document
from docx.shared import Inches
import re
import json
import collections
from docx.shared import Cm
from docx.oxml.shared import OxmlElement, qn
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT,WD_ALIGN_PARAGRAPH
from docx.enum.table import WD_ALIGN_VERTICAL
 
tpl = DocxTemplate('test.docx')
sd = tpl.new_subdoc()
sd.add_paragraph('Drug Table :')
rows=3
cols=4
table = sd.add_table(rows=rows, cols=cols,style="outertable")
width = OxmlElement('w:tblW')
width.set(qn('w:type'), 'pct')
width.set(qn('w:w'), '5000')
table._tblPr.append(width)

#header
cells = table.rows[0].cells
cells[0].text="Gene"
cells[1].text="Drug"
cells[2].text="Rank"
cells[3].text="Description" 
 
table.cell(1,0).text="ALK"
table.cell(1,1).text="GENE1"
table.cell(1,2).text="GENE2"
table.cell(1,3).text="haha"
# #merge
table.cell(2,0).merge(table.cell(2,3)).text="One Drug"
 
##設置標題行的高度
table.rows[0].height = Cm(2)
##設置每一列的寬度
col_width = [1,2,3,4]
for col in range(4):
    table.cell(0,col).width = Inches(col_width[col])

#水平居中
#table.style.paragraph_format.alignment=WD_PARAGRAPH_ALIGNMENT.CENTER
###為每一列設置居中
for row in range(3):
    for col in range(4):
        cell = table.cell(row, col)
        pa = cell.paragraphs[0]
        pa.alignment = WD_ALIGN_PARAGRAPH.CENTER  ##水平居中
        cell.vertical_alignment = WD_ALIGN_VERTICAL.CENTER  ##垂直居中

context = {
    'mysubdoc' : sd,
}
 
 
tpl.render(context)
tpl.save('vertical_merge.docx')

2. 結果

水平居中的結果

垂直居中的結果

 實現四:給每個單元格賦值

1. 代碼

第一種如上方代碼

table.cell(1,0).text="ALK"

第二種

run是比paragraphs更小的單位

cell = table.cell(i + 1, col)
pa = cell.paragraphs[0]
pa.add_run("xxxxx")

實現五:設置表格邊框

docx包比較貼近word底層結構,想要讀明白需要花點功夫。

python-docx: docx.xml.table

這里是給表格的每個單元格設置邊框

insertH ,insertV:不用於單元格

color: 邊框顏色,RRGGBB格式,不需要加#

val: 邊框樣式,例如single: 單行,none:無框線,dashed:虛線

from docx.oxml.shared import OxmlElement, qn
from docxtpl import DocxTemplate, InlineImage, RichText
from docx.oxml import parse_xml

#設置單元格的邊框
def set_cell_border(self, cell, **kwargs):
    """
    Set cell`s border
    Usage:
    set_cell_border(
        cell,
        top={"sz": 12, "val": "single", "color": "FF0000", "space": "0"},
        bottom={"sz": 12, "color": "00FF00", "val": "single"},
        left={"sz": 24, "val": "dashed", "shadow": "true"},
        right={"sz": 12, "val": "dashed"},
    )
    """
    tc = cell._tc
    tcPr = tc.get_or_add_tcPr()

    tcBorders = tcPr.first_child_found_in("w:tcBorders")
    if tcBorders is None:
        tcBorders = OxmlElement('w:tcBorders')
        tcPr.append(tcBorders)

    for edge in ('left', 'top', 'right', 'bottom', 'insideH', 'insideV'):
        edge_data = kwargs.get(edge)
        if edge_data:
            tag = 'w:{}'.format(edge)

            # check for tag existnace, if none found, then create one
            element = tcBorders.find(qn(tag))
            if element is None:
                element = OxmlElement(tag)
                tcBorders.append(element)

            # looks like order of attributes is important
            for key in ["sz", "val", "color", "space", "shadow"]:
                if key in edge_data:
                    element.set(qn('w:{}'.format(key)), str(edge_data[key]))

def table():
    doc = DocxTemplate('xxx.docx')
    sd = doc.new_subdoc()
    table = sd.add_table(rows=1, cols=2)
    set_cell_border(table.cell(0,0), bottom={"sz": 6, "color": "#000000", "val": "single"})
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM