"""
docx_demos.py
(创建文档类Document及属性方法, 创建段落文本类Paragraph及段落格式设置, 创建字体设置类Run及属性等)
使用:
一、创建文档类Document 及 段落文本类Paragraph :
docx.Document(),
Document.add_heading(),
二、添加段落文本类Paragraph 及 设置段落文本格式
Document.add_paragraph(),
Paragraph.insert_paragraph_before(),
Paragraph.add_run(),
Run.bold / sytle / italic / font.size / font.color.rgb #字体及颜色设置
三、设置段落文本的 对齐格式,缩进格式,段落间距,行间距格式,制表位等设置。
Paragraph.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER /
WD_ALIGN_PARAGRAPH.LEFT 左对齐
WD_ALIGN_PARAGRAPH.CENTER 文字居中
WD_ALIGN_PARAGRAPH.RIGHT 右对齐
WD_ALIGN_PARAGRAPH.JUSTIFY 本两端对齐
Paragraph.paragraph_format.left_indent = Pt(20) #左侧缩进 Pt(20) 表示4个空格缩进
Paragraph.paragraph_format.right_indent = Pt(20) #右侧缩进,Pt(20) 表示4个空格缩进
Paragraph.paragraph_format.first_line_indent = Pt(20) #首行缩进,Pt(20) 表示4个空格缩进
Paragraph.paragraph_format.tab_stops.add_tab_stop(
Inches(5), #添加制表位为12个空格距离
WD_TAB_ALIGNMENT.LEFT, #添加制表符右对齐
WD_TAB_LEADER.DOTS) #添加制表符的前导字符为 点划线。
Paragraph.paragraph_format.space_before = Pt(80) #段前间距
Paragraph.paragraph_format.space_after = Pt(50) #段后间距
Paragraph.paragraph_format.line_spacing = Pt(30) #设置绝对行间距为 磅30
Paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE #设置相对行间距,1倍行间距。
四、添加文档的 分页符 (硬分页 和 段落文本的分页属性)
document.add_page_break() #硬分页,相当于Ctrl+Enter
Paragraph.paragraph_format.keep_together / keep_with_next / page_break_before / widow_control
#来设置 段落分页属性
五、添加图片
#使用:Document.add_picture(self, image_path_or_stream, width=None, height=None)
#来添加图表
六、添加表格
Document.add_table(self, rows, cols, style=None) 来添加表格
七、页面布局
Header.paragraphs[0].text 属性 来赋值设置 页眉文本内容。
"""
# =============================================================================
# #docx模块
# #docx模块用于创建和更新Word文档
# #涉及:页眉,标题,段落,字体,样式 以及 表格,图片等
#
# =============================================================================
import docx
from docx import Document #打开/新建文档类
from docx.text.paragraph import Paragraph #查看使用,段落文本类:Doc.add_paragraph()后返回该类对象
from docx.text.run import Run #查看使用,段落文本类的追加写入,设置格式使用,可设置字体等格式。Doc.add_run()后返回该类对象
from docx.enum.text import (WD_ALIGN_PARAGRAPH, #设置段落文本对象的对齐格式:.CENTER居中, .LEFT左对齐等。
WD_TAB_ALIGNMENT, #设置制表符的 对齐方式使用。
WD_TAB_LEADER, #设置制表符的 前导字符使用。
WD_LINE_SPACING, #设置相对行间距 的倍数使用。
)
from docx.shared import (Length, #设置宽度使用
Inches, #英寸单位,用于添加图像时 来设置图像大小
Pt, #磅单位,用于添加格式时 来设置缩进等
Cm, #厘米单位,
Mm, #毫米单位,
RGBColor, #设置字体颜色
)
#################### 创建文档 Document类对象及属性方法
########## 创建文档类Document 及 段落文本类Paragraph
#####
#使用:docx.Document(docx=None) 类 来 读取/创建 一个文档类。
#参数docx=None: 为读取的文档名称或路径,None则创建一个空的文档类模板。
docx_filename = r'docx_cases\docx_demos_case1.docx'
document = docx.Document() #首先创建一个空白文档类,也可传入文件名打开已有文档
#help(docx.document.Document)
#打开文档的其他方式:
#f = open('foobar.docx', 'rb')
#document = Document(f)
#
#f.close()
##### 添加标题
#使用:Document.add_heading(self, text='', level=1) 来添加标题。
#参数level: 指定标题级别,可设置标题级别1-9
h1 = document.add_heading('此处默认标题h1')
h2 = document.add_heading('此处添加标题h2',level=2)
h3 = document.add_heading('此处添加标题h3',level=3)
########## 添加段落文本类Paragraph 及 设置段落文本格式
#段落是Word的基础。
##### 添加段落文本
#使用:Document.add_paragraph(self, text='', style=None) 来添加段落文本
#参数text='' : 指定添加的文本内容
#参数style=None: 指定段落文本样式。
#返回:docx.text.paragraph.Paragraph类对象。
#help(docx.text.paragraph.Paragraph)
p1 = document.add_paragraph('添加段落p1, style=BodyText', style='BodyText')
##### 插入段落文本
#使用:Paragraph.insert_paragraph_before(self, text=None, style=None)
#来在Paragraph段落对象前 插入 新的段落文本。
p1_ins = p1.insert_paragraph_before('通过p1.insert_paragraph_before() 方法,'+
'在p1前插入段落 p1_ins')
##### 设置段落样式(不是格式)
#使用:Document.add_paragraph(text=None, style=None) 里参数style 来设置段落文本样式
#或
#使用:Paragraph.style 属性 来赋值 设置段落样式。
p2 = document.add_paragraph('添加段落p2,并 设置参数style="ListBullet"', style='List Bullet')
p3 = document.add_paragraph('添加段落p3,后 设置Paragraph.style属性为"ListBullet"')
p3.style = 'List Number'
##### 设置段落文本 Run类的 字体格式(通过段落文本添加的Run类对象):Font字体、颜色。
#首先创建Paragraph类对象,然后通过其创建Run类对象,使用Run类对象属性来赋值设置格式。
p = document.add_paragraph('Document.add_paragraph()添加段落文本,接下来开始要设置格式:\n')
#使用:Paragraph.add_run(text=None, style=None)
#来给Paragraph段落文本追加内容,和add_paragraph方法类同也可指定样式。
#参数text=None: 设置追加的文本内容
#参数style=None: 指定文本的样式
#返回:docx.text.run.Run 类对象
#help(docx.text.run.Run)
r1 = p.add_run('通过Paragraph.bold=True来设置粗体')
r1.bold = True
r1.style = 'Emphasis'
#使用:Run类的属性 赋值 来设置字体: 加粗、斜体、大小、颜色、下划线等。
#使用:Run.bold = Ture 来指定粗体
#使用:Run.italic = True 来指定斜体
#使用:Run.font.size 来指定 字体大小
#使用:Run.font.color.rgb 来指定字体颜色。
r2 = p.add_run('\n通过Run.italic = True 来设置斜体,' +
'\n通过Run.font.size = Pt(20) 来设置字体大小,' +
'\n通过Run.font.color.rgb = RGBColor 来设置字体颜色'
)
r2.italic = True
r2.font.size = Pt(20)
r2.font.color.rgb = RGBColor(200,77,150)
# =============================================================================
# all_caps => 全部大写字母
# bold => 加粗
# color => 字体颜色
# complex_script => 是否为“复杂代码”
# cs_bold => “复杂代码”加粗
# cs_italic => “复杂代码”斜体
# double_strike => 双删除线
# emboss => 文本以凸出页面的方式出现
# hidden => 隐藏
# imprint => 印记
# italic => 斜体
# name => 字体
# no_proof => 不验证语法错误
# outline => 显示字符的轮廓
# shadow => 阴影
# small_caps => 小型大写字母
# snap_to_grid => 定义文档网格时对齐网络
# strike => 删除线
# subscript => 下标
# superscript => 上标
# underline => 下划线
# =============================================================================
#参考官方文档:https://python-docx.readthedocs.io/en/latest/user/text.html
########### 设置段落文本的 对齐格式
#注意:如果段落文本存在于Table表格当中,则段落文本的边界等格式指定的是表单的单元格边界格式。
#使用:Paragraph.paragraph_format.alignment 属性 来赋值设置 段落文本的 对齐格式。
#WD_ALIGN_PARAGRAPH.LEFT 左对齐
#WD_ALIGN_PARAGRAPH.CENTER 文字居中
#WD_ALIGN_PARAGRAPH.RIGHT 右对齐
#WD_ALIGN_PARAGRAPH.JUSTIFY 本两端对齐
#官方文档:https://python-docx.readthedocs.io/en/latest/api/enum/WdAlignParagraph.html#wdparagraphalignment
p4 = document.add_paragraph('准备开始设置 段落文本的 对齐格式。')
p4.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
p41 = document.add_paragraph('p4.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER 设置居中')
p41.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
p42 = document.add_paragraph('p4.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT 左对齐')
p42.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.LEFT
p43 = document.add_paragraph('p4.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.RIGHT 右对齐')
p43.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.RIGHT
##### 设置段落文本的 缩进(左侧缩进,右侧缩进,首行缩进)
#注意:如果段落文本存在于Table表格当中,则段落文本的边界等格式指定的是表单的单元格边界格式。
#段落文本可以在左侧缩进、右侧缩进、首行缩进。
#段落文本的缩进值:诸如Inches(), Pt(), Cm(), 负值均有效,None值表示缩进值从样式层次结构继承。
##Pt(20) 表示4个空格缩进
#官方参考网址:https://python-docx.readthedocs.io/en/latest/api/shared.html#docx.shared.Length
#左侧缩进
#使用:Paragraph.paragraph_format.left_indent 属性 来赋值 设置段落文本的左侧缩进。
p5 = document.add_paragraph('\n准备开始设置缩进、段落间距、段落行距')
p5.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER #居中设置
p50 = document.add_paragraph('左侧缩进设置, '+
'这里使用的设置左侧缩进的代码是:'+
'p5.paragraph_format.left_indent = Pt(20)')
p50.paragraph_format.left_indent = Pt(20) #左侧缩进,Pt(20) 表示4个空格缩进
#右侧缩进
#使用:Paragraph.paragraph_format.right_indent 属性 来赋值 设置右侧缩进。
p51 = document.add_paragraph('右侧缩进设置, '+
'还可以设置右侧缩进,这里使用的设置右侧缩进的代码是: '+
'看看右侧缩进的效果怎么样'+
'p51.paragraph_format.right_indent = Pt(20)')
p51.paragraph_format.right_indent = Pt(20) #右侧缩进,Pt(20) 表示4个空格缩进
#首行缩进
#使用:Paragraph.paragraph_format.first_line_indent 属性来赋值 设置段落文本的首行缩进。
p6 = document.add_paragraph('盖闻:人生在世,富贵不能淫,贫贱不能移。' +
'文章盖世,孔子厄于陈邦;武略超群,太公钓于渭水。' +
'颜渊命短,殊非凶恶之徒;盗跖年长,岂是善良之辈。' +
'尧帝明圣,却生不肖之儿;瞽叟愚顽,反生大孝之子。' +
'张良原是布衣,萧何称谓县吏。晏子身无五尺,封作齐国宰相;孔明卧居草庐,能作蜀汉军师。' +
'楚霸虽雄,败于乌江自刎;汉王虽弱,竟有万里江山。' +
'李广有射虎之威,到老无封;冯唐有乘龙之才,一生不遇。' +
'韩信未遇之时,无一日三餐,及至遇行,腰悬三齐玉印,一旦时衰,死于阴人之手。')
p6.paragraph_format.first_line_indent = Pt(20) #首行缩进,Pt(20) 表示4个空格缩进
##### 设置段落文本的 制表位
#制表位决定了段落文字中制表符的呈现方式。
#它指定了制表符后面的文本的开始位置,与该位置对齐的方式,以及一个可选的前导字符来填充制表符跨越的水平空间。
p61 = document.add_paragraph('准备开始设置制表符')
p61.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER #居中设置
#使用:Paragraph.paragraph_format.tab_stops.add_tab_stop(position, alignment=0, leader=0)
#来添加新的制表位,即:从添加制表位以后,使用TAB则移动指定的position距离,默认是\t的距离。
#参数position : 制表符位置
#参数alignment=0 : 对齐选项,默认左对齐
#可使用常量类 WD_TAB_ALIGNMENT 来指定对齐方式。官方网址:https://python-docx.readthedocs.io/en/latest/api/enum/WdTabAlignment.html#wdtabalignment
#参数leader=0 : 指定前导字符,用来填充制表位前的空白区间。比如:在书籍的目录中用来索引标题的体制。
#有四种选项:实线,粗虚线,细虚线,点划线。
#可使用常量类 WD_TAB_LEADER 来指定类型,官方网址:https://python-docx.readthedocs.io/en/latest/api/enum/WdTabLeader.html#wdtableader
#help(p61.paragraph_format.tab_stops.add_tab_stop)
p61.paragraph_format.tab_stops.add_tab_stop(Pt(60)) #添加制表符为12个空格距离
p61.paragraph_format.tab_stops.add_tab_stop(Inches(5), #添加制表位为12个空格距离
WD_TAB_ALIGNMENT.LEFT, #添加制表符右对齐
WD_TAB_LEADER.DOTS) #添加制表符的前导字符为 点划线。
p61.add_run('\n\t\t') #写入一个\t制表符来查看效果
##### 设置段落文本的 段落间距 (段前间距 和 段后间距)
#使用:Paragraph.paragraph_format.space_before 属性 来赋值 设置段前间距
#使用:Paragraph.paragraph_format.space_after 属性 来赋值 设置段后间距
p7 = document.add_paragraph('准备开始设置 间距:段前间距Pt(80),段后间距Pt(50)\n'+
'可在文档上点击 右键--段落--间距 来查看间距')
p7.paragraph_format.space_before = Pt(80) #段前间距
p7.paragraph_format.space_after = Pt(50) #段后间距
##### 设置段落文本的 行间距 (绝对行间距 和 相对行高行间距)
#行距可以指定为 绝对距离 或 相对于行高(基本上是所用字体的磅值)。
#典型的绝对度量值为Pt(18)。典型的相对度量是双倍间距(2.0行高)。默认行距是单行距(1.0行高)。
#注意:
#设置段落行距
#当行距为 最小值 和 固定值时,设置值单位是 磅,用Pt;
#当行间距为 多倍行距 时,设置值为数值 即:倍数。
#使用:Paragraph.paragraph_format.line_spacing 来赋值 设置绝对行间距宽度。支持Pt()磅单位
p81 = document.add_paragraph('准备开始设置 绝对行间距\n p81.paragraph_format.line_spacing = Pt(30) \n'+
'有先贫而后富,有老壮而少衰。满腹文章,白发竟然不中;才疏学浅,少年及第登科。'+
'深院宫娥,运退反为妓妾;风流妓女,时来配作夫人。'+
'青春美女,却招愚蠢之夫;俊秀郎君,反配粗丑之妇。\n'+
'蛟龙未遇,潜水于鱼鳖之间;君子失时,拱手于小人之下。'+
'衣服虽破,常存仪礼之容;面带忧愁,每抱怀安之量。'+
'时遭不遇,只宜安贫守份;心若不欺,必然扬眉吐气。'+
'初贫君子,天然骨骼生成;乍富小人,不脱贫寒肌体。')
p81.paragraph_format.line_spacing = Pt(30) #设置绝对行间距为 磅30
#使用:Paragraph.paragraph_format.line_spacing_rule 来赋值 设置相对行间距。支持常量设置。
p82 = document.add_paragraph('准备开始设置 相对行间距\n p82.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE \n'+
'天不得时,日月无光;地不得时,草木不生;'+
'水不得时,风浪不平;人不得时,利运不通。'+
'注福注禄,命里已安排定,富贵谁不欲?人若不依根基八字,岂能为卿为相?')
p82.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE #设置相对行间距,1倍行间距。
#官方网址:https://python-docx.readthedocs.io/en/latest/api/enum/WdLineSpacing.html#wdlinespacing
# =============================================================================
# SINGLE 单倍行距(默认)
# ONE_POINT_FIVE 1.5倍行距
# DOUBLE2 倍行距
# AT_LEAST 最小值
# EXACTLY 固定值
# MULTIPLE 多倍行距
#
# paragraph.line_spacing_rule = WD_LINE_SPACING.EXACTLY #固定值
# paragraph_format.line_spacing = Pt(18) #固定值18磅
# paragraph.line_spacing_rule = WD_LINE_SPACING.MULTIPLE #多倍行距
# paragraph_format.line_spacing = 1.75 #1.75倍行间距
# =============================================================================
########## 添加文档的 分页符 (硬分页 和 段落文本的分页属性)
#硬分页
#使用:Document.add_page_break() 来进行硬分页,相当于Ctrl+Enter下一页
#document.add_page_break()
p9 = document.add_paragraph('使用:Document.add_page_break()硬分页,即使文本未满')
#段落文本的分页属性
#使用:Paragraph.paragraph_format.keep_together / keep_with_next / page_break_before / widow_control
#来设置 段落分页属性
#--------------------------------------------------------------------
#四个段落文本的分页属性:
#keep_together 导致整个段落出现在同一页面上,如果该段落在两个页面之间被打断,则会在该段落之前发出分页符。
#keep_with_next 与下一个段落在同一页面上保留一个段落。例如,这可用于使节标题与节的第一段在同一页面上。
#page_break_before 导致将段落放置在新页面的顶部。可以在章节标题上使用它,以确保章节在新页面上开始。
#widow_control 中断页面以避免将段落的第一行或最后一行与段落的其余部分放在单独的页面上。
#--------------------------------------------------------------------
#注意:这四个分页属性都包含三个状态,即:True,False或None。
#None指示属性值是从样式层次结构继承的。True表示“打开”,False表示“关闭”
p10 = document.add_paragraph(
'吾昔寓居洛阳,朝求僧餐,暮宿破窑,'+
'思衣不可遮其体,思食不可济其饥,上人憎,下人厌,人道我贱,非我不弃也。'+
'今居朝堂,官至极品,位置三公,'+
'身虽鞠躬于一人之下,而列职于千万人之上,有挞百僚之杖,有斩鄙吝之剑,'+
'思衣而有罗锦千箱,思食而有珍馐百味,出则壮士执鞭,入则佳人捧觞,上人宠,下人拥。'+
'人道我贵,非我之能也,此乃时也、运也、命也。')
p10.paragraph_format.keep_together = True
document.add_page_break() #硬分页,相当于Ctrl+Enter
########## 添加图片
#使用:Document.add_picture(self, image_path_or_stream, width=None, height=None)
#来添加图表
#参数image_path_or_stream: 指定图片名称或地址
#参数width : 设置图片宽度, 只设置一个宽度,则可以自动等比例高度
#参数height: 设置图片高度, 只设置一个高度,则可以自动等比例宽度
document.add_picture(r'docx_cases\002592.png', width=Inches(2))
########## 添加表格 及 设置表格样式
##### 添加表格
#使用:Document.add_table(self, rows, cols, style=None) 来添加表格
table = document.add_table(rows=2, cols=2)
table.style = 'LightShading-Accent1'
#使用:Table.cell(row_idx, col_idx) 来选择表格内单元格
#使用:Cell.text 属性 来赋值添加表格内单元格的文本内容
cell = table.cell(0,1)
cell.text = '通过cell.text()来添加内容' #选择表格内单元格、单元格赋值添加和改变内容
#使用:Table.rows 来获取表格的所有行,列表结构,可迭代,可通过索引获取指定行
#使用:Table.columns 来获取表格的所有列,列表结构,可迭代,可通过索引获取指定列
#使用:Table.rows[索引号].cells 来获取指定行的所有单元格,可迭代,可索引。
#注意:索引从0开始。
row = table.rows[1] #选择表格的行,通过索引,然后索引单元格
row.cells[0].text = '通过.add_table(,)来添加表格'
row.cells[1].text = '通过for row in table.rows内嵌套 for cell in row.cells来循环输出表格内容'
for row in table.rows: #for循环逐行输出表格内容
for cell in row.cells:
print(cell.text)
row_count = len(table.rows) #len表格内行数
col_count = len(table.columns) #len表格内列数
print(row_count,col_count,'现表格行列数')
#使用:Table.add_row() 来追加行,结合使用for循环可实现循环添加行。
row = table.add_row() #逐步添加行
print(len(table.rows),len(table.columns),'添加后表格行列数')
table1 = document.add_table(1,3) #添加另一个表格,可通过 参数style来指定表格样式
table1.style = 'LightShading-Accent2' #设置表格样式,可以通过 参数style或 属性style
heading_cells = table1.rows[0].cells #获取 行列标
heading_cells[0].text = 'Qtx' #为行列表内的cell单元格 赋值
heading_cells[1].text = 'Sku'
heading_cells[2].text = 'Des'
items = (
(7,'1024','plush kitens'),
(3,'2042','furbees'),
(1,'1288','french poodle collars,deluxe')
)
for item in items:
cells = table1.add_row().cells #逐行追加行,并变量赋值每行的所有单元格。
cells[0].text = str(item[0])
cells[1].text = str(item[1])
cells[2].text = str(item[2])
########## 页面布局
##### #页眉设置 和 页眉删除
#使用:Document.sections 来获取文档的页面对象列表结构。
#注意:默认只有一个页面对象,可通过Document.add_section()来添加页面对象。
len(document.sections)
section = document.sections[0] #
#使用:Section.header 来获取页面的头部对象
#使用:Section.header.is_linked_to_previous 属性的值来判断 页眉的状态。True为无页眉设置。
header = section.header
print(header.is_linked_to_previous)
#使用:Header.paragraphs[0].text 属性 来赋值设置 页眉文本内容。
len(header.paragraphs)
yemei = header.paragraphs[0]
yemei.text = '这里是页眉内容'
yemei.text = 'Left Text \t Center Text \t Right Text'
#使用:Section.header.is_linked_to_previous 属性 设置为True 来删除页眉设置。
header.is_linked_to_previous = True
########## 文档的保存
document.save(docx_filename)