作为一个有理想的安服仔,肯定是担任重要任务,很多事情都要解决,虽然简单但是很繁琐,特别是word的文档处理这块,经常要处理几十个文档就很烦,挣扎了下还是打算写个脚本来批量处理这些事情,总不能因为这些事情耽误了自己进步(摸鱼)吧?由于之前没接触过py在word文档处理这块的东西,所以还是踩了一些坑的,写一下,后续有用到可以避避坑。
老样子,一开始还是先思考下,如果正常操作,我们会如何操作,然后根据这些操作去构思我们的路线,所有的方便都不会是直接来的,不是一两个函数就能解决的事情,就好像3D打印,你没构图,3D打印也没办法打出你想要的东西出来,所以一开始我构思了三条路线:
一:直接定位里面的内容,然后删除,插入自己想要的;
二:把我想要的内容独立做成一个文档,然后定位内容,把老的删除,删除之后粘贴新的;
三:将原文档的内容进行切块,然后再把自己想要的内容独立成一些文档,然后再把每个文档进行拼接,得到新的文档;
其实还有其他的思路,但是有点太过繁琐,后面我在实现的过程中发现实际上不需要那么复杂,是自己想太多了,后面会谈到,那么先说下第一个思路,简单易懂对吧,但是具体实现起来,发现删除了之后,我重新写进去的数据,会丢失之前的格式,而py的docx对于格式方面虽然说可以赋予格式,但是没办法跟真正的word一样去设置每一部分的格式,而且有一些是不存在的,所以这块就十分的麻烦,如果你的文档不存在格式的问题,就简简单单的文字,那完全可以根据这个思路去做,而且很方便。第二个思路的话,有个很重要的点就是,定位可以定位,但是粘贴新的内容的时候,他会跟在文档末尾,也就是说,如果你想要粘贴的在文档中间,那没办法去直接粘贴到指定位置(PS:没怎么接触这个,我就只是为了实现这个东西,才去看了下,如果有话,是小弟太菜了),第三个思路的话,乍一看似乎可以得到我们想要的东西,但是如果文件量多起来的话,问题在于怎么去做到准确切割自己想要的东西。
多说无益,动手才知道坑在哪,如果要批量转化word的话,那么第一步肯定是先拿到我们文件夹里面的文件,然后再轮询,这个可以先不管,先试试能不能修改word里面的内容,ok,这里经过一系列的百度之后,我发现了python的一个很神奇的库—python-docx,用于创建可修改微软Word的一个python库,提供全套的 Word操作,是最常用的Word工具,而且能保留我们原有的格式,那这不是直接起飞???
在开始使用之前,先说下关于word的一些概念:
Document
:是一个 Word 文档 对象,不同于 VBA 中 Worksheet 的概念,Document 是独立的,打开不同的 Word 文档,就会有不同的 Document 对象,相互之间没有影响Paragraph
:是段落,一个 Word 文档由多个段落组成,当在文档中输入一个回车键,就会成为新的段落,输入 shift + 回车,不会分段Run
表示一个节段,每个段落由多个 节段 组成,一个段落中具有相同样式的连续文本,组成一个节段,所以一个 段落 对象有个 Run 列表也就是说word 文档内容的结构是这样划分的:
第二个 段落(paragraph),没有内容,所以 节段(run)为空,了解到这,也基本上知道如何去定位我们想要的数据了,先轮询paragraph,然后在这个paragraph里面去轮询run,从而拿到我们的要的数据,说干就干,直接上,就拿上面的概念为文本,我们写个代码块去遍历这些段落,然后输出出来
1 | from docx import Document |
输出结果是这样的:
这就是每一段的内容,再遍历每一段里面的run块出来
可以看到run的区分不是根据词语的,而是根据写入的时间节点,如果时间节点不一样,那么run的内容就不一样,同一段文字,可能写入的时间节点不一致,遍历run的时候结果也不一样,这点暂时没办法解决,目前能想到的就是遍历的时候组合文字,当匹配出自己想要的文之后再进行替换。
1 | params = { |
这些能有效处理开头和中间的文字,而且这种方式替换的话,不会去掉文章原有的格式,而如果有需要替换大量的文字段落在文章末的时候,可以将文末需要替换的文字删除,需要删除空行,普通的clean命令只是将内容删除,而不会去除换行,所以删除之后会存在空行的情况 ,这时候如果复制另外一个文档的内容接入到文末的话,他会接在空行后面,所以需要删除空行。
1 | for paragraph in doc.paragraphs: |
这里有一点就是,把其他文档里面的内容合并到这个文档的时候,其他文档里面的文字内容格式是不会变的,这也跟我们最初的想法一致,保留原有的格式,所以可以直接使用
1 | bottom_title = 'bottom.docx' |
到这基本需要替换的就能够替换掉,并且保留文档格式了,但是有一点就是,去除空行不能够遍历全文,最好就是先定位到位置,再增加判断条件,不然容易将图片内容删除,因为当你遍历段落的时候,图片独占一行的时候该段落是空的,所以会将图片给删除掉,可以额外加一个判断,当存在图片的时候,该段落的run值是为0,而不存在图片单纯一个空行的时候,run是不存在任何值的。