Python可以利用python-docx模块处理word文档,处理方式是面向对象的。也就是说python-docx模块会把word文档,文档中的段落、文本、字体等都看做对象,对对象进行处理就是对word文档的内容处理。
如果需要读取word文档中的文字(一般来说,程序也只需要认识word文档中的文字信息),需要先了解python-docx模块的几个概念。
需要注意,python-docx模块安装需要在cmd命令行中输入pip install python-docx,如下图表示安装成功(最后那句英文Successfully installed,成功地安装完成)
注意在导入模块时,用的是import docx。
也真是奇了怪了,怎么安装和导入模块时,很多都不用一个名字,看来是很有必要出一个python版本的模块管理程序python-maven了,本段纯属PS。
在了解了上面的信息之后,就很简单了,下面先创建一个D:\temp\word.docx文件,并在其中输入如下内容。
import docx
file=docx.Document(r"F:\python从入门到放弃\7\2\wenjian.docx")
print('段落:'+str(len(file.paragraphs)))
#
# for para in file.paragraphs:
# print(para.text)
for i in range(len(file.paragraphs)):
print("第"+str(i)+"段的内容是:"+file.paragraphs[i].text)
import sys
from docx import Document
from docx.shared import Inches
def main():
# reload(sys)
# sys.setdefaultencoding('utf-8')
# 创建文档对象
document = Document()
# 设置文档标题,中文要用unicode字符串
document.add_heading(u'我的一个新文档',0)
# 往文档中添加段落
p = document.add_paragraph('This is a paragraph having some ')
p.add_run('bold ').bold = True
p.add_run('and some ')
p.add_run('italic.').italic = True
# 添加一级标题
document.add_heading(u'一级标题, level = 1',level = 1)
document.add_paragraph('Intense quote',style = 'IntenseQuote')
# 添加无序列表
document.add_paragraph('first item in unordered list',style = 'ListBullet')
# 添加有序列表
document.add_paragraph('first item in ordered list',style = 'ListNumber')
document.add_paragraph('second item in ordered list',style = 'ListNumber')
document.add_paragraph('third item in ordered list',style = 'ListNumber')
# 添加图片,并指定宽度
document.add_picture('cat.png',width = Inches(2.25))
# 添加表格: 1行3列
table = document.add_table(rows = 1,cols = 3)
# 获取第一行的单元格列表对象
hdr_cells = table.rows[0].cells
# 为每一个单元格赋值
# 注:值都要为字符串类型
hdr_cells[0].text = 'Name'
hdr_cells[1].text = 'Age'
hdr_cells[2].text = 'Tel'
# 为表格添加一行
new_cells = table.add_row().cells
new_cells[0].text = 'Tom'
new_cells[1].text = '19'
new_cells[2].text = '12345678'
# 添加分页符
document.add_page_break()
# 往新的一页中添加段落
p = document.add_paragraph('This is a paragraph in new page.')
# 保存文档
document.save('demo1.doc')
if __name__ == '__main__':
main()
读取表格:
import docx
doc = docx.Document('wenjian.docx')
for table in doc.tables: # 遍历所有表格
print('----table------')
for row in table.rows: # 遍历表格的所有行
# row_str = '\t'.join([cell.text for cell in row.cells]) # 一行数据
# print row_str
for cell in row.cells:
print(cell.text, '\t',)
print() #换行
首先是用docx.Document打开对应的文件目录。
docx文件的结构比较复杂,分为三层,
因此p.text会打印出整个的文本文档。而用doc.tables来遍历所有的表格。并且对每个表格通过遍历行,列的方式来得到所有的内容。
但是在运行结果中并没有找到我们插入的文件对象和图片,text.txt文档。这部分该如何解析呢。首先我们需要先来认识下docx文档的格式组成:
docx是Microsoft Office2007之后版本使用的,用新的基于XML的压缩文件格式取代了其目前专有的默认文件格式,在传统的文件名扩展名后面添加了字母“x”(即“.docx”取代“.doc”、“.xlsx”取代“.xls”、“.pptx”取代“.ppt”)。
docx格式的文件本质上是一个ZIP文件。将一个docx文件的后缀改为ZIP后是可以用解压工具打开或是解压的。事实上,Word2007的基本文件就是ZIP格式的,他可以算作是docx文件的容器。
docx 格式文件的主要内容是保存为XML格式的,但文件并非直接保存于磁盘。它是保存在一个ZIP文件中,然后取扩展名为docx。将.docx 格式的文件后缀改为ZIP后解压, 可以看到解压出来的文件夹中有word这样一个文件夹,它包含了Word文档的大部分内容。而其中的document.xml文件则包含了文档的主要文本内容
从上面的文档我们可以了解到docx文档实际上是由XML文档打包组成的。那么我们要得到其中所有的部分,可以用ZIP解压的方式来得到所有的部件。
我们先试下看是否可以
1 将docx文档改成ZIP的后缀
2 解压文件
解压之后得到如下几个文件

点开word文件夹:有如下的文件夹。document.xml就是描述文本对象的文件

其中embeddings文件中就是我们插入的文本对象text.txt. 是一个bin文件

Media文件中就是存储的图片:

我们通过手动的方式将插入的文本以及图片解析出来,那么通过代码也是同样可以解析的。代码如下。
os.chdir(r'E:\py_prj') #首先改变目录到文件的目录
os.rename('test.docx','test.ZIP') # 重命名为zip文件
f=zipfile.ZipFile('test.zip','r') #进行解压
for file in f.namelist():
f.extract(file)
file=open(r'E:\py_prj\word\embeddings\oleObject1.bin','rb').read() #进入文件路径,读取二进制文件。
for f in file:
print (f)
通过上面的方式,就可以将docx中插入的文件以及图片全部解析出来。
具体docx的写的方式可以参考官方文档的介绍
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我看到这个错误:translationmissing:da.datetime.distance_in_words.about_x_hours我的语言环境文件:http://pastie.org/2944890我的看法:我已将其添加到我的application.rb中:config.i18n.load_path+=Dir[Rails.root.join('my','locales','*.{rb,yml}').to_s]config.i18n.default_locale=:da如果我删除I18配置,帮助程序会处理英语。更新:我在config/enviorments/devolpment
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的