【python-docx】Python读写Word文件_doc.paragraphs-程序员宅基地

技术标签: Python基础  doc.paragraphs  Python-docx  doc.tables  Python-Word文档  

python-docx是一个在Python环境下读写word文档的“利器”。在使用前可以通过 pip install python-docx 命令安装,再通过import docx 引用即可。下面简单介绍一下 python-docx 的基本操作。

1、新建/打开及保存

文档的新建和打开比较简单,只需要用docx的Document类,若指定路径则是打开文档;若没有指定路径则是新建文档。

对文档的操作结束后可以通过Document类的save方法进行保存,其中参数是保存的文件路径,或者要保存的文件流。一般指定路径即可。

doc = docx.Document('D:\project\python\docx\test.docx') #打开文档
doc_new = docx.Document()  #新建文档

doc.save()  #保存
doc_new.save('D:\project\python\docx\1.docx')  #保存

2. 对象操作

python-docx包含了word文档的相关对象集合,如段落(doc.paragraphs)、表格(doc.tables)、节(doc.sections)、样式(doc.styles)、内置图形(doc.inline_shapes)等等。我们可以通过这些对象集合进行信息读取。在这里我主要说一下段落和表格的操作吧。

2.1 doc.paragraphs

在docx中,可以通过 doc.paragraphs 访问word中的段落信息。

我们通过 print(doc.paragraphs) 和 print(type(doc.paragraphs))  可以知道,doc.paragraphs给出的是一个包含paragraph对象的list。我们可以通过 len(doc.paragraphs)  查看段落的数量。

print(doc.paragraphs)
print(type(doc.paragraphs)) #<class 'list'>
print(len(doc.paragraphs)) #9

如果想访问文档的具体内容,可以通过遍历的方式,利用 doc.paragraphs.text 的命令来读取,也可以通过制定的下标访问制定段落。

for i in doc.paragraphs:  #遍历全部段落
    print(i.text)    #提取段落内容

print(doc.paragraphs[1]) #访问具体段落

 不过,上述方式仅仅是获得了文字内容,而把格式全忽略了。比如加粗、颜色、居中等等。在paragraph中,这些东西叫做run。一个Run对象就是style相同的一段文本,一个段落是由许多run组成的,就像这样:

我们可以通过runs分割、获取文本:

print(doc.paragraphs[1].text) #访问具体段落
print(doc.paragraphs[1].runs)
print(len(doc.paragraphs[1].runs))  
print(doc.paragraphs[1].runs[1].text)

运行结果如下: 

通过python-docx,我们不仅可以读出paragraph的内容,还进行写入和修改。修改比较简单,直接给text赋值就行:

print(doc.paragraphs[1].runs[3].text)
doc.paragraphs[1].runs[3].text="不伤悲" #修改文字
print(doc.paragraphs[1].text)

处理刚才“芙蓉如面柳如眉,对此如何不泪垂”那一句,运行结果如下: 

添加内容可以使用 add_paragraph()  add_run()方法来进行:

import docx

doc = docx.Document('1.docx')

#在文档末尾添加段落
doc.add_paragraph(u'北方有佳人,遗世而独立',style=None)
doc.add_paragraph(u'一顾倾人城,再顾倾人国',style='Heading 2')

#在段落末尾添加文字
q=doc.paragraphs[2]
q.add_run(u'爱而不见,搔首踟蹰',style=None)

doc.save('1_new.docx')

运行结果如下:

也可以对文字的样式进行设置。

import docx

doc = docx.Document('1.docx')

r=doc.paragraphs[2].runs[0]
print(r.text) #运行结果:静女其姝,俟我于城隅
r.font.bold = True    #加粗
r.font.italic = True  #倾斜

doc.save('1_new.docx')

结果如下:

2.2 doc.tables

在用docx处理word文件时,段落是可以用paragraph处理的,如果word中有表格,用 doc.paragraphs 根本读都读不到,因为表格在docx中是另一个类。要对表格进行操作,就需要用到 doc.tables 了。

我们可以通过下面的方式在.docx文件中添加表格:

table=doc.add_table(rows=2,cols=3,style=None)

接下来,我们用下面这个文档来作为例子,请记住它的样子:

doc.paragraphs类似,通过 doc.tables,我们可以获得文档中的全部表格,这也是个 list。但是但是表格是不能直接读的,因为我们知道表格的操作对象其实是“单元格”。我们可以分别对表格进行行(row)、列(column)、单元格(cell)的操作:

import docx

doc = docx.Document('2.docx')

print(type(doc.tables))   #<class 'list'>
print(len(doc.tables))   #2

#可以通过len(table.rows) 和 len(table.colums)读取表格的行和列
for i in doc.tables:
    print(len(i.rows),"*",len(i.columns))  
#运行结果: 4*3
#          2*5

如果要遍历表格中的元素,可以使用一下几种方式,自己写的,可能还有别的更好的方法:

#方法一:每一行遍历,同理也可以按每一列遍历
for i in range(0,len(table.rows)):
    for j in table.rows[i].cells:
        print(j.text)

#方法二:根据单元格下标依次遍历
for i in range(0,len(table.rows)):
    for j in range(0,len(table.columns)):
        print(table.cell(i,j).text)

通过遍历,我们可以查找表格中的数据或者找到对应单元格的位置。

for i in range(0,len(table.rows)):
    for j in range(0,len(table.columns)):
        if table.cell(i,j).text=="表格1-A21":
            print(i,",",j)  
#运行结果:2 , 1

要想提取表格中的内容,我们最好引入一个list对象用于保存数据:

import docx

doc = docx.Document('2.docx')
table=doc.tables[0]

_table_list = [] #用于保存表格内容

for i, row in enumerate(table.rows):   # 读每行
    row_content = [] #用于保存每行内容
    for cell in row.cells:  # 读一行中的所有单元格
        c = cell.text
        if c not in row_content:
            row_content.append(c)
    _table_list.append(row_content)

for i in _table_list:
    print(i)

运行结果如下:

要改变单元格中的内容也非常简单,直接对text赋值即可。如:

table.cell(2,2).text="王明"

表格中还需注意的是,对于合并单元格,其实它还是默认之前的行数或者列数:

import docx

doc = docx.Document('2.docx')

#例1
table_2 = doc.tables[1]
n = 0
for i in range(0, len(table_2.rows)):
    for j in range(0, len(table_2.columns)):
        if table_2.cell(i, j).text == "表格2-B1":
            n += 1

print(n)  #运行结果:2

#例2
for i in range(0,len(table_2.rows)):
    for j in range(0,len(table_2.columns)):
        if table_2.cell(i,j).text=="表格2-B2":
            print(i,",",j)
#运行结果:0,1
#         0,2
#         0,3
#         0.4

要想增加表格的行数或者列数,可以使用 table.add_row() 或 table.add_column():

import docx

doc = docx.Document('2.docx')

table=doc.tables[0]

table.add_row()
table.add_column(10) #需要指明列宽

doc.save("2_new.docx")

运行结果如下:

 我们现在把原文件中的表格1中的文字格式变为:蓝色,加粗。如果我们通过直接赋值的方法修改其中单元格中的内容,结果如下,可以看到修改后的内容有一个默认的文字格式。

如果我们想在不改变单元格文字样式的情况下修改内容应该怎么办呢?只需要改一下赋值代码:

import docx

doc = docx.Document('2.docx')

table=doc.tables[0]

#table.cell(2,2).text= '修改'  #修改后内容以默认格式显示
table.cell(2,2).paragraphs[0].runs[0].text= '修改'  #仅修改文字,保留原来的格式

doc.save("2_new.docx")

好了,docx最基础的使用就讲到这里了,当然还有非常多其他的操作,以后用到了再慢慢总结。Bye~


参考:

https://www.cnblogs.com/wrajj/p/4914102.html

https://www.cnblogs.com/anpengapple/p/8372958.html

https://www.cnblogs.com/anpengapple/p/8372987.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_45427038/article/details/102815533

智能推荐

跟着实训学习HTML CSS的第二天-程序员宅基地

文章浏览阅读72次。在练习五彩导航条的时候,许多同学都卡住了,最后经过分享,大家掌握了许多的方法来解决这个问题,还是很有帮助的。下面就是代码的实现部分:<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="wi

dfs 遍历二叉树_dfs遍历思想实际上是二叉树-程序员宅基地

文章浏览阅读830次。dfs 遍历二叉树为了更好的理解dfs手写了dfs 遍历二叉树的两种方式方法:一种是采用常用的递归执行另一种是采用循环执行(使用栈来代替递归)二叉树定义class Node { //get set方法省略 private Node leftChild; private Node rightChild; private int data; public Node(int d..._dfs遍历思想实际上是二叉树

手握Synchronized原理搞懂并发编程,阿里面试官:快到碗里来_python synchronized原理-程序员宅基地

文章浏览阅读478次。Synchronized原理简介synchronized想必大家都不陌生,用来解决线程安全问题的利器。同时也是Java高级程序员面试比较常见的面试题。下面会带大家彻底了解synchronized的实现。内容导航什么时候需要用Synchronized synchronized的使用 synchronized的实现原理分析什么时候需要用Synchronized想必大家对synchronized都不陌生,主要作用是在多个线程操作共享数据的时候,保证对共享数据访问的线程安全性。比如在下_python synchronized原理

同为容器,IoC和Docker有啥不同?_部署容器和ioc容器的区别-程序员宅基地

文章浏览阅读1.1w次,点赞87次,收藏121次。Spring中有容器技术,Docker中也有,容器技术中,能学到哪些思想呢?_部署容器和ioc容器的区别

hadoop下载安装_如何下载并安装Hadoop?-程序员宅基地

文章浏览阅读1.4k次。hadoop下载安装In this article, we will, 在本文中,我们将 Download and Install Virtual Box. 下载并安装Virtual Box。 Download and Install Cloudera Virtual Machine (VM) Image. 下载并安装Cloudera虚拟机(VM)映像。 Launch the Cloudera..._电脑如何下载havoado

mysql er分片_MyCat 学习笔记 第十篇.数据分片 之 ER分片-程序员宅基地

文章浏览阅读275次。1 应用场景这篇来说下mycat中自带的er关系分片,所谓er关系分片即可以理解为有关联关系表之间数据分片。类似于订单主表与订单详情表间的分片存储规则。本文所说的er分片分为两种:a. 依据主键进行数据分片,验证发现主表数据保存在第1个datanode中,子表数据根据分片规则存储。b. 依据分片关键字段进行分片,验证发现主表与子表根据分片规则存储,且保存在相同的分片内。接下来,可以下实际配置与数据..._er分片

随便推点

0-1背包问题(python实现)_python实现0-1背包问题-程序员宅基地

文章浏览阅读619次。定义一个二维数组 dp,其中dp[i][j]表示 将下标为 0-i之间的物品放入容量为j的背包的最大价值。_python实现0-1背包问题

牙齿开奶_怎么用牙开牛奶-程序员宅基地

文章浏览阅读102次。对学校的饭堂越来越不满意了,以前一直缺汤匙,今天更缺吸管了。今天买了一袋奶,找不到吸管,当时问服务员借剪刀她说没有,问她怎样开,她说真是读书读傻了,用牙齿嘛。我无语。。。想不到从小没有极尽牙齿之能的我,今天竟然第一次动用牙齿来代替剪刀了。不过想到其他同学牙齿的功效远不止剪刀的作用,我也只有尝试尝试这剪刀的威力了。不知道爱护牙齿是否必须通过这样锻炼出来的呢?2008-3-8..._怎么用牙开牛奶

go 判断字符是否为汉字或ascii码_go 字符串 asci码判断-程序员宅基地

文章浏览阅读9.2k次。判断是否为汉字func isHan(r rune) bool { return unicode.Is(unicode.Han, r)}判断是否为ascii码. 对应c的 int isascii(int c);func isAscii(r rune) bool { return unicode.Is(unicode.ASCII_Hex_Digit, r)..._go 字符串 asci码判断

Android开发小生(四)-程序员宅基地

文章浏览阅读346次。深入探讨Activity

如何开启远程桌面的服务器,如何启用远程服务器 开启服务器的远程桌面控制...-程序员宅基地

文章浏览阅读2.2k次。最近要将项目做重新的服务器上做项目部署。为了方便维护服务器,故需要开启服务器的远程桌面控制。于是就演示下操作的过程,配上图文,更加直观。以下为新版远程桌面的使用教程及效果图:1:打开主界面,主界面简洁大气,以下为效果图:2:服务器添加示例3、为使界面更美观,分辨率、状态检测、批量打开间隔时间等统一在“其他设置键”打开。4、示例之如何修改窗口大小,旧版名称为分辨率设置,新版的窗口设置更加方便,点开“..._服务器怎么开启远程桌面

SendMail 发送邮件_珊秀发送信息发送邮件-程序员宅基地

文章浏览阅读1k次。SendMail 发送邮件using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Net.Mail;using System.Data;using CDO;using ADODB;namespace SendMailTest{ class Program { st_珊秀发送信息发送邮件

推荐文章

热门文章

相关标签