備忘錄_20160105(定位)
修改
回首頁
程式 2025-04-24 11:11:36 1745464296 100
用 python 來產生 word 檔案
用 python 來產生 word 檔案
# pip install python-docx
from docx import Document
from docx.shared import Pt
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Cm
from docx.enum.section import WD_ORIENT
from docx.enum.text import WD_ALIGN_PARAGRAPH
def set_table_border(table):
tbl = table._tbl
tblPr = tbl.tblPr
# 建立 <w:tblBorders> 元素
tblBorders = OxmlElement('w:tblBorders')
for border_name in ('top', 'left', 'bottom', 'right', 'insideH', 'insideV'):
border = OxmlElement(f'w:{border_name}')
border.set(qn('w:val'), 'single') # 實線 single
border.set(qn('w:sz'), '1') # 線條寬度,單位為 1/8 pt,1pt=>8,目前用1,等於就是1/8pt
border.set(qn('w:space'), '0') # 線與內容之間距離
border.set(qn('w:color'), '000000') # 黑色
tblBorders.append(border)
# 加入到 <w:tblPr> 中
tblPr.append(tblBorders)
def cm_to_twips(cm):
return int(cm * 567) # 1 cm ≈ 567 twips
def set_table_width(table, width_cm):
table.autofit = False
tbl = table._tbl
tblPr = tbl.tblPr
width_twips = cm_to_twips(width_cm)
tblW = tblPr.xpath('./w:tblW')
if tblW:
tblW[0].set(qn('w:w'), str(width_twips))
tblW[0].set(qn('w:type'), 'dxa')
else:
tblW = OxmlElement('w:tblW')
tblW.set(qn('w:w'), str(width_twips))
tblW.set(qn('w:type'), 'dxa')
tblPr.append(tblW)
def set_table_alignment(table, alignment='center'):
"""
alignment: 'left', 'center', or 'right'
"""
tbl = table._tbl
tblPr = tbl.tblPr
jc = OxmlElement('w:jc')
jc.set(qn('w:val'), alignment)
tblPr.append(jc)
# 插入欄位函式(頁碼、總頁數用)
def insert_field(run, field_code):
fldChar1 = OxmlElement('w:fldChar')
fldChar1.set(qn('w:fldCharType'), 'begin')
instrText = OxmlElement('w:instrText')
instrText.set(qn('xml:space'), 'preserve')
instrText.text = field_code
fldChar2 = OxmlElement('w:fldChar')
fldChar2.set(qn('w:fldCharType'), 'separate')
fldChar3 = OxmlElement('w:fldChar')
fldChar3.set(qn('w:fldCharType'), 'end')
r_element = run._r
r_element.append(fldChar1)
r_element.append(instrText)
r_element.append(fldChar2)
r_element.append(fldChar3)
def set_cell_padding(cell, top=0, left=0, bottom=0, right=0):
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
# 建立 <w:tcMar>(儲存格內距)元素
tcMar = OxmlElement('w:tcMar')
for name, value in (('top', top), ('left', left), ('bottom', bottom), ('right', right)):
mar = OxmlElement(f'w:{name}')
mar.set(qn('w:w'), str(value)) # TWIPS 單位:1 pt = 20,1 cm ≈ 567
mar.set(qn('w:type'), 'dxa')
tcMar.append(mar)
tcPr.append(tcMar)
def set_table_cell_margins(table, margin=0):
"""
設定整張表格的儲存格內距為指定值(預設 0)
"""
tbl = table._tbl
tblPr = tbl.tblPr
tblCellMar = OxmlElement('w:tblCellMar')
for side in ('top', 'start', 'bottom', 'end'):
elem = OxmlElement(f'w:{side}')
elem.set(qn('w:w'), str(margin))
elem.set(qn('w:type'), 'dxa') # dxa = 1/20 pt
tblCellMar.append(elem)
tblPr.append(tblCellMar)
def set_paragraph_background(paragraph, color_hex):
"""
設定段落背景色,例如 color_hex = "FFFF00"(黃色)
"""
p = paragraph._p # 取得底層 <w:p> 元素
pPr = p.get_or_add_pPr() # 取得段落屬性 <w:pPr>
shd = OxmlElement('w:shd') # 建立 <w:shd> 元素
shd.set(qn('w:val'), 'clear') # 填滿方式,clear 表示實心
shd.set(qn('w:color'), 'auto') # 字體顏色(不設定)
shd.set(qn('w:fill'), color_hex) # 背景填滿色
pPr.append(shd) # 加到段落屬性中
def set_cell_background(cell, color_hex):
"""
設定儲存格背景色,例如 color_hex = "FFFF00"(黃色)
"""
tc = cell._tc # 取得底層 <w:tc> 元素
tcPr = tc.get_or_add_tcPr() # 取得 <w:tcPr> 儲存格屬性元素
shd = OxmlElement('w:shd') # 建立 <w:shd> 元素
shd.set(qn('w:val'), 'clear') # 填滿方式
shd.set(qn('w:color'), 'auto') # 不指定字體顏色
shd.set(qn('w:fill'), color_hex) # 背景填滿色
tcPr.append(shd) # 加到儲存格屬性中
# https://python-docx.readthedocs.io/en/latest/
oDoc=Document()
oSection=oDoc.sections[0]
oSection.orientation = WD_ORIENT.PORTRAIT
oSection.page_width = Cm(21)
oSection.page_height = Cm(29.7)
oSection.top_margin = Cm(1)
oSection.bottom_margin = Cm(1)
oSection.left_margin = Cm(1)
oSection.right_margin = Cm(1)
oFooter=oSection.footer
oP=oFooter.paragraphs[0]
oP.alignment = WD_ALIGN_PARAGRAPH.CENTER
oP.text="2025-04-24 大乘起信論勝異方便 "
oRun=oP.add_run()
insert_field(oRun, 'PAGE')
oP.add_run(" / ")
oRun=oP.add_run()
insert_field(oRun, 'NUMPAGES')
oP=oDoc.add_paragraph('')
oP.paragraph_format.space_before = Pt(0)
oP.paragraph_format.space_after = Pt(0)
oTable=oDoc.add_table(rows=0, cols=1)
oTable.autofit=False
oTable.allow_autofit=False
set_table_alignment(oTable, 'center')
set_table_width(oTable, 18)
set_table_border(oTable)
oP=oDoc.add_paragraph('')
oP.paragraph_format.space_before = Pt(0)
oP.paragraph_format.space_after = Pt(0)
# 第一個儲存格
if 1==1:
oCell=oTable.add_row().cells[0]
oCell.width=Cm(18)
set_cell_padding(oCell)
set_cell_background(oCell, 'e7e1fa')
# oP=oCell.paragraphs[0]
# oP=oCell.add_paragraph()
oP=oCell.paragraphs[0]
oP.paragraph_format.space_before = Pt(0)
oP.paragraph_format.space_after = Pt(0)
oRun=oP.add_run('大乘起信論勝異方便')
oRun.font.name='標楷體'
oRun._element.rPr.rFonts.set(qn('w:eastAsia'), '標楷體')
oRun.font.size=Pt(12)
oRun.font.bold=True
# 第二個儲存格
if 1==1:
oCell=oTable.add_row().cells[0]
oCell.width=Cm(18)
set_cell_padding(oCell)
set_cell_background(oCell, 'ffffff')
# oP=oCell.paragraphs[0]
# oP=oCell.add_paragraph()
oP=oCell.paragraphs[0]
oP.paragraph_format.space_before = Pt(0)
oP.paragraph_format.space_after = Pt(0)
oRun=oP.add_run('[開場白]')
oRun.font.name='標楷體'
oRun._element.rPr.rFonts.set(qn('w:eastAsia'), '標楷體')
oRun.font.size=Pt(24)
oRun.font.bold=True
# 第三個儲存格
if 1==1:
oCell=oTable.add_row().cells[0]
oCell.width=Cm(18)
set_cell_padding(oCell)
set_cell_background(oCell, 'cbeef7')
# oP=oCell.paragraphs[0]
# oP=oCell.add_paragraph()
oP=oCell.paragraphs[0]
oP.paragraph_format.space_before = Pt(0)
oP.paragraph_format.space_after = Pt(0)
oRun=oP.add_run('講稿與辭典')
oRun.font.name='標楷體'
oRun._element.rPr.rFonts.set(qn('w:eastAsia'), '標楷體')
oRun.font.size=Pt(12)
oRun.font.bold=True
# 第四個儲存格
if 1==1:
oCell=oTable.add_row().cells[0]
oCell.width=Cm(18)
set_cell_padding(oCell)
set_cell_background(oCell, 'ffffff')
# oP=oCell.paragraphs[0]
# oP=oCell.add_paragraph()
oP=oCell.paragraphs[0]
set_paragraph_background(oP, 'dddddd')
oP.paragraph_format.space_before = Pt(0)
oP.paragraph_format.space_after = Pt(0)
oRun=oP.add_run("諸位老師學長早安,\r\n阿彌陀佛。")
oRun.font.name='標楷體'
oRun._element.rPr.rFonts.set(qn('w:eastAsia'), '標楷體')
oRun.font.size=Pt(16)
oRun.font.bold=False
# oP=oCell.paragraphs[0]
# oP=oCell.add_paragraph()
oP=oCell.add_paragraph()
oP.paragraph_format.space_before = Pt(0)
oP.paragraph_format.space_after = Pt(0)
oRun=oP.add_run("這裡是辭典文字......")
oRun.font.name='標楷體'
oRun._element.rPr.rFonts.set(qn('w:eastAsia'), '標楷體')
oRun.font.size=Pt(12)
oRun.font.bold=False
######set_table_cell_margins(oTable, 0)
#nmomtf
oDoc.save('20250424.docx')