1. 前言

关于 Word 文档的读写,前面两篇文章分别进行了一次全面的总结

最全总结 | 聊聊 Python 办公自动化之 Word(上)

最全总结 | 聊聊 Python 办公自动化之 Word(中)

本篇文章作为一个办公自动化 Word 篇的一个补充,写写几个比较实用的办公场景

包含:

页眉页脚处理

合并多个文档

新增数字索引

doc 批量转 docx

对比文档差异性

特别内容标注

替换文字内容

2. 页眉页脚

每一个页面章节都包含:页眉页脚

它可以单独设置,每个页面都不一样;也可以全部设置成与首页一样

这个功能,由章节对象中的属性 different_first_page_header_footer 来控制

当值为 True 时,代表页眉页脚不同于首页,每个页面章节的页眉、页脚都可以单独设置

当值为 False 时,所有页面的页眉、页脚都一样

# 1、获取待处理页眉、页脚的章节

header = self.doc.sections[0].header

footer = self.doc.sections[0].footer

# True if this section displays a distinct first-page header and footer

# True:页眉页脚不同于首页,每个页面章节的页眉页脚单独设置

# False:每个页面的页眉页脚相同

self.doc.sections[0].different_first_page_header_footer = True

添加页眉页脚包含两种,分别是:普通页眉页脚、自定义样式的页眉页脚

1 - 普通页眉页脚

def add_norm_header_and_footer(header, footer, header_content, footer_content):

"""

增加一个普通的页眉、页脚,并居中显示

:param header_content:

:param footer_content:

:return:

"""

# 新增/修改页眉、页脚

# 注意:一般页眉、页脚里只有一个段落

header.paragraphs[0].text = header_content

footer.paragraphs[0].text = footer_content

# 居中显示

header.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

footer.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

# 2、新增页眉

# 2.1 普通的页眉、页脚

add_norm_header_and_footer(header, footer, "我是一个页眉", "我是一个页脚")

2 - 自带样式的页眉页脚

def add_custom_style_header_and_footer(header, footer, header_content, footer_content, style):

"""

新增自定义的页眉、页脚

:param header:

:param footer:

:param header_content:

:param footer_content:

:param style:

:return:

"""

# 注意:style_type=2,否则会报错

header.paragraphs[0].add_run(header_content, style)

footer.paragraphs[0].add_run(footer_content, style)

# 2.2 自带样式的页眉、页脚

# 创建一个样式

style_paragraph = create_style(document=self.doc, style_name="style5", style_type=2, font_size=30,

font_color=[0xff, 0x00, 0x00], align=WD_PARAGRAPH_ALIGNMENT.CENTER)

add_custom_style_header_and_footer(header, footer, "我是页眉2", "我是页脚2", style_paragraph)

如果想将文档中所有的页眉、页脚删除掉,只需要 2 个步骤:

遍历文档中所有页面章节,将其 different_first_page_header_footer 属性值设置为 False

设置章节对象页眉页脚的 is_linked_to_previous 属性值为 True

PS:当 is_linked_to_previous 设置为 True 时,页眉页脚会被删除

def remove_all_header_and_footer(doc):

"""

删除文档中所有页眉和页脚

:param doc:

:return:

"""

for section in doc.sections:

section.different_first_page_header_footer = False

# 当is_linked_to_previous设置为True时,页眉页脚会被删除

section.header.is_linked_to_previous = True

section.footer.is_linked_to_previous = True

3. 合并多个文档

日常工作中,经常会遇到将多个 Word 文档合并成一个文件的需求

这里,可以使用另外一个 Python 依赖库:docxcompose

# 合并多个文件的依赖库

# pip3 install docxcompose

使用也非常简单,只需要下面 4 行代码,就能将多个文件进行合并,生成到一个新的文件中去

from docxcompose.composer import Composer

def compose_files(self, files, output_file_path):

"""

合并多个word文件到一个文件中

:param files:待合并文件的列表

:param output_file_path 新的文件路径

:return:

"""

composer = Composer(Document())

for file in files:

composer.append(Document(file))

# 保存到新的文件中

composer.save(output_file_path)

新增数字索引

我们经常需要在文档页脚处添加页面数字索引,可惜 python-docx 并没有提供现有方法

但是,在 stackoverflow 上找到实现的方式

from docx.oxml.xmlchemy import BaseOxmlElement, ZeroOrOne, ZeroOrMore, OxmlElement

from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

from docx.oxml import ns

def create_element(self, name):

return OxmlElement(name)

def create_attribute(self, element, name, value):

element.set(ns.qn(name), value)

def add_page_number(self, run):

"""

添加页面索引

:param run:

:return:

"""

fldChar1 = self.create_element('w:fldChar')

self.create_attribute(fldChar1, 'w:fldCharType', 'begin')

instrText = self.create_element('w:instrText')

self.create_attribute(instrText, 'xml:space', 'preserve')

instrText.text = "PAGE"

fldChar2 = self.create_element('w:fldChar')

self.create_attribute(fldChar2, 'w:fldCharType', 'end')

# run._r:class 'docx.oxml.text.run.CT_R'>

run._r.append(fldChar1)

run._r.append(instrText)

run._r.append(fldChar2)

默认生成的数字索引在页脚左下角,并不美观!

因此,这里我们可以使用 第一篇文章 的方法创建一个「文字块样式」,然后以文字块 Run 的形式,添加到页脚的第一个段落中去

# 注意:要设置页眉页脚的对齐方式,必须设置到段落上(文字块不能添加对齐方式)

doc.sections[0].footer.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

# 创建一个文字块样式,指定字体名称、大小、颜色

style = create_style(document=doc, style_name="style", style_type=2, font_size=10,

font_color=[0x00, 0x00, 0x00], font_name="黑体")

self.add_page_number(doc.sections[0].footer.paragraphs[0].add_run("", style))

doc.save("./output.docx")

print('添加页码索引成功!')

需要注意的,如果需要设置页面数字索引的对齐方式,必须针对页脚的段落进行设置,修改其 alignment 属性值即可

5. doc 转 docx

python-docx 对 doc 格式的文档不太友好,要处理这类文档,我们需要先将它转换为 docx 格式

对于 Windows 系统,完全可以使用 win32com 这个模块,用命令去调用 Word 应用,打开源文件后,保存了 docx 格式的文件即可

from win32com import client

def doc_to_docx_in_win(path_raw, path_output):

"""

doc转为docx(win)

:param path_original:

:param path_final:

:return:

"""

# 获取文件的格式后缀

file_suffix = os.path.splitext(path_raw)[1]

if file_suffix == ".doc":

word = client.Dispatch('Word.Application')

# 源文件

doc = word.Documents.Open(path_raw)

# 生成的新文件

doc.SaveAs(path_output, 16)

doc.Close()

word.Quit()

elif file_suffix == ".docx":

shutil.copy(path_raw, path_output)

而对于 Mac/Linux,推荐使用 LibreOffice 去转换文档格式

# 转换格式

./soffice --headless --convert-to docx 源文件.doc --outdir /output/path/

PS:LibreOffice 是一款由社区创造的自由免费办公套件,跨平台,内置的 soffice 可以用于文件转换

以 Mac OS 为例,我们按下面步骤来操作

官网下载 LibreOffice 软件并安装

找到 LibreOffice 软件安装目录,将 soffice 命令所在目录配置到环境变量中

重启 Pycharm

使用 os 模块下的 walk() 函数遍历所有源文件,组成一条 soffice 转换命令

执行转换命令

import os

source = "./doc/"

dest = "./docx/"

g = os.walk(source)

# 遍历文件夹

for root, dirs, files in g:

for file in files:

# 源文件完整路径

file_path_raw = os.path.join(root, file)

print(file_path_raw)

os.system("soffice --headless --convert-to docx {} --outdir {}".format(file_path_raw, dest))

对比文档差异性

两个 Word 文档的对比也是工作中比较常见的需求了

首先,遍历文档中所有段落,过滤掉空行,获取所有文本内容

# 分别获取段落内容

content1 = ''

content2 = ''

for paragraph in file1.paragraphs:

if "" == paragraph.text.strip():

continue

content1 += paragraph.text + '\n'

for paragraph in file2.paragraphs:

if "" == paragraph.text.strip():

continue

content2 += paragraph.text + '\n'

# 如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。

print("第二个文档数据如下:\n", content1.splitlines(keepends=False))

print("第一个文档数据如下:\n", content1.splitlines(keepends=False))

接着,使用 Python 中的标准依赖库 difflib 对比文字间的差异,最后生成 HTML 差异报告

import codecs

from difflib import HtmlDiff

# 差异内容

diff_html = HtmlDiff(wrapcolumn=100).make_file(content1.split("\n"), content2.split("\n"))

# 写入到文件中

with codecs.open('./diff_result.html', 'w', encoding='utf-8') as f:

f.write(diff_html)

7. 特别内容标注

我们经常需要对文档中部分重要内容进行特别标注

比如,我们需要对文档中包含「 微信 」的文字块或单元格,标为红色并加粗显示

1 - 段落内容

只需要遍历出段落中所有文字块 Run,直接修改文字块的 Font 属性即可

doc = Document(file)

# 关键字的文字块或单元格标红,并加粗

# 1、修改段落中包含关键字的文件块的样式

for paragraph in doc.paragraphs:

for run in paragraph.runs:

if keyword in run.text:

# 修改颜色为红色,并加粗显示

run.font.bold = True

run.font.color.rgb = RGBColor(255, 0, 0)

2 - 表格内容

设置满足条件的单元格样式有点特别,需要经过下面 4 个步骤

获取单元格对象,获取单元格文本内容,并临时保存

清空单元格数据

单元格对象追加一个段落和一个文字块 Run,返回一个文字块对象

设置文字块对象样式,标红并加粗

tables = [table for table in doc.tables]

for table in tables:

for row in table.rows:

for cell in row.cells:

if keyword in cell.text:

# 原内容

content_raw = cell.text

# 清空单元格数据

cell.text = ""

# 追加数据进去,并设置样式

run = cell.paragraphs[0].add_run(content_raw)

run.font.color.rgb = RGBColor(255, 0, 0)

run.font.bold = True

8. 替换文字内容

有时候,我们需要将文档中某个关键字全部替换成一个新的内容

这时候,我们可以遍历所有段落和表格,使用 replace() 函数对段落文本和单元格内容进行替换

def replace_content(self, old_content, new_content):

"""

替换文档中所有内容

:param old_content:旧的内容

:param new_content:新的内容

:return:

"""

# 替换段落

for paragraph in self.doc.paragraphs:

if old_content in paragraph.text:

# 替换内容后,重新设置进去

paragraph.text = paragraph.text.replace(old_content, new_content)

# 替换表格

# document.tables[表格索引].rows[行索引].cells[单元格列索引].text = “新的数据”。

tables = [table for table in self.doc.tables]

for table in tables:

for row in table.rows:

for cell in row.cells:

if old_content in cell.text:

# 重新设置单元格内容

cell.text = cell.text.replace(old_content, new_content)

# 保存到一个新的文件中

self.doc.save('./new.docx')

9. 最后

到此,Python 自动化 Word 篇的内容全部结束了!

如果实际工作中,有一些其他的业务场景文中没有覆盖到,可以在文末进行留言,后面办公自动化实战篇可能会提供对应的解决方案!

要获取全部源码,关注公众号,后台回复「 word 」即可获得全部源码

python办公自动化博客_最全总结 | 聊聊 Python 办公自动化之 Word(下)相关推荐

  1. python开源oa系统_最全总结 | 聊聊 Python 办公自动化之 Word(下)

    1. 前言 关于 Word 文档的读写,前面两篇文章分别进行了一次全面的总结 本篇文章作为一个办公自动化 Word 篇的一个补充,写写几个比较实用的办公场景 包含: 页眉页脚处理 合并多个文档 新增数 ...

  2. layui中table监听单元格_最全总结 | 聊聊 Python 办公自动化之 PPT(中)

    点击上方 "AirPython",选择 "加为星标" 第一时间关注 Python 技术干货! 1. 前言 上一篇文章简单地介绍了 PPT 的文档结构,并使用 p ...

  3. python开发个人博客_手把手教你用 Python + Flask 搭建个人博客

    Python 的语言特性使得自身编写 Web 框架极其容易,现在已经有上百种用 Python 编写的 Web 开发框架,其中用户量最大的两个就是 Django 和 Flask. Django 和 Fl ...

  4. insert into 多条数据_最全总结 | 聊聊 Python 数据处理全家桶(Sqlite篇)

    点击上方"AirPython",选择"加为星标" 第一时间关注 Python 技术干货! 1. 前言 上篇文章 聊到 Python 处理 Mysql 数据库最常 ...

  5. mysql打印语句_最全总结 | 聊聊 Python 数据处理全家桶(Mysql 篇)

    点击上方"AirPython",选择"加为星标" 第一时间关注 Python 技术干货! 1. 前言 在爬虫.自动化.数据分析.软件测试.Web 等日常操作中, ...

  6. python办公自动化博客_自动化办公 Python 操控 Word

    虽然Word不好用, 但还必须得用它, python-docx是专门用于编辑Word文档的一个工具库, 它有两大用途, 自动化生成word文档 and 自动化修改文档 python word 1. 自 ...

  7. python csdn博客_利用Python抓取CSDN博客

    这两天发现了一篇好文章,陈皓写的makefile的教程,具体地址在这里<跟我一起写makefile> 这篇文章一共分成了14个部分,我看东西又习惯在kindle上面看,感觉一篇一篇地复制成 ...

  8. python办公自动化价值是什么意思_最全总结 | 聊聊 Python 办公自动化之 Word(中)...

    1. 前言 上一篇文章,对 Word 写入数据的一些常见操作进行了总结 相比写入数据,读取数据同样很实用! 本篇文章,将谈谈如何全面读取一个 Word 文档中的数据,并会指出一些要注意的点 2. 基本 ...

  9. python刷微博关注_[代码全屏查看]-python刷新浪微博粉丝

    [1].[代码] [Python]代码 # -*- coding: utf-8 -*- import urllib, urllib2, cookielib, hashlib,threading imp ...

最新文章

  1. 通过internet在计算机之间以用户名,第7_8章_计算机网络与internet应用.doc
  2. ME3630模块常用指令介绍
  3. 服务器操作系统锁定设置,服务器操作系统锁定设置
  4. 非常有用的并发控制-循环栅栏CyclicBarrier
  5. 玩具谜题(洛谷-P1563)
  6. 腾讯云Nginx配置https
  7. 2016级算法期末模拟练习赛-E.AlvinZH的青春记忆III
  8. docker常用操作和命令
  9. 软件开发入门自学指南
  10. iOS蓝牙开发(三)实现外设功能
  11. 有哪些比较好用的开源项目管理工具?
  12. 思维导图----百度百科
  13. 完善智慧办公建设,小熊U租获京东数千万元A+轮融资
  14. docker的代理配置_wuli大世界_新浪博客
  15. 软件测试工程师必备技能(初中高)
  16. ps还原上一步快捷键_photoshop恢复上一步操作的快捷键是什么
  17. 用php编写一个函数_使给定的一个二维数组(3×3)转置,写一个函数 使给定的一个3x3的二维数组转置,即行列互换...
  18. 安装图解:Linux Mint 4.0(Daryna)(或者说完美的桌面系统)
  19. 欲登千层楼,又何惧寒风
  20. Unity 角色朝向目标 / 动态转向动画

热门文章

  1. C++关键字--volatile
  2. Flex与.NET互操作(十三):FluorineFx.Net实现视频录制与视频回放
  3. 实现跨域访问---同源策略 、常见跨域方法
  4. Python爬虫_BeauifulSoup
  5. 元学习Meta Learning/Learning to learn
  6. 复杂类型java对象 — dto数据传输对象
  7. mysql5.7存储json_MySQL5.7的json数据格式的问题
  8. 6种字符串数组的java排序 (String array sort)
  9. mybatis-generator 详细配置及使用,爬坑记录
  10. JavaScript笔记整理