Python办公自动化 | word 文本转 excel

2022-08-22 10:43:38 浏览数 (1)

近日有工作上的需求,需要梳理数据元目录中的多个数据项,数据项条目可能达到1000多个,可以说这个工作量非常巨大,源文件是 word 版本的,无法进行筛选和标记(即使用颜色或者字体去标记之后,每次也需要肉眼去看某一项到底有没有梳理过),如果是 excel 版本就不一样了,已梳理和未梳理的可以很简单的完成分类,并且和其他文件进行比对,用以核实是否已经梳理过。

问题来了:如何进行 word 文本转 excel?

word 版本文件是这样的:

可以看出,文件具有4层目录,每一个数据项又包含了定义、英文缩写、数据格式、说明等内容。

python-docx 读取失败

想用 Python 处理 docx 自然就想到了 python-docx,这就去试试。

首先安装 python-docx

代码语言:javascript复制
pip install python-docx -i https://pypi.tuna.tsinghua.edu.cn/simple

然后用 python-docx 识别了一下文件内容

代码语言:javascript复制
from docx import Document

doc=Document(r'.demo.docx')
for i, paragraph in enumerate(doc.paragraphs):
    print(i,'------------', paragraph.text)

你有没有发现他居然把目录编号给丢弃了。。。

有点难以接受,随后我去翻阅了官方接口文档,也没有读取 heading 的方法,查阅了好久资料也没找到更好的包,问题搁置。。。

PyPDF2 读取失败

某天吃饭的时候,我突然想到能不能用 pdf 去试试,因为 word 文件的目录编号是格式上的,而 pdf 文件内容是所见即所得。

然后,我又去研究 pdf 内容读取,首先发现了 PyPDF2

但是他读取中文 pdf 都是乱码,找了好久也没找到设置编码的方法,遂放弃。。。

pdfplumber 读取成功并写入txt

最后,我又发现了 pdfplumber

他可以完美解析中文,太棒了

查看 page_text 数据类型,发现是 str ,就是返回的全部的文本内容,是一个很长很长的字符串,这种不方便进行后续处理。可以把 page_text 内容写入 txt,然后再逐行读取。

代码语言:javascript复制
import pdfplumber

file_path = r'.demo.pdf'
with pdfplumber.open(file_path) as pdf:
    pages = pdf.pages
    content = ''
    for i in range(len(pages)):
        page_text = pages[i].extract_text()
        if page_text:
            content = content   page_text
        with open('tmp.txt',mode='w ') as file:
            file.write(content)
            file.close

逐行读取txt

代码语言:javascript复制
f = open(".tmp.txt")
file = f.readlines()

使用正则表达式识别文本、OrderedDict封装文本

定义正则表达式 pattern

这里定义多个 pattern 表达式用于识别标题和文本内容

代码语言:javascript复制
title_level1=re.compile("d.[^0-9]")
title_level2=re.compile("d.d[^.0-9]")
title_level3=re.compile("d.d.d[^.0-9]")
title_level4=re.compile("d.d.d.d[^.0-9]")

content1 = re.compile("定义")
content2 = re.compile("英文缩写")
content3 = re.compile("数据格式")
content4 = re.compile("说明")

定义9个 OrderedDict

这里定义9个 OrderedDict 用于封装标题和文本内容,key_title 是最外层的 OrderedDict,title1 是第一个层级的key,后续所有内容封装到一个 OrderedDict,title2 是第二个层级的key,后续所有内容封装到一个 OrderedDict,后续各层原理一致

代码语言:javascript复制
key_title  = OrderedDict()
key_title1 = OrderedDict()
key_title2 = OrderedDict()
key_title3 = OrderedDict()
key_title4 = OrderedDict()
key_content1 = OrderedDict()
key_content2 = OrderedDict()
key_content3 = OrderedDict()
key_content4 = OrderedDict()

逐行进行正则识别,写入 OrderedDict

代码语言:javascript复制
for each in file:
    if title_level1.match(each):
        key_title1 = key_title.setdefault(each, OrderedDict())
    if title_level2.match(each):
        key_title2 = key_title1.setdefault(each, OrderedDict())
    if title_level3.match(each):
        key_title3 = key_title2.setdefault(each, OrderedDict())
    if title_level4.match(each):
        key_title4 = key_title3.setdefault(each, OrderedDict())
    if content1.match(each):
        key_content1 = key_title4.setdefault(each, OrderedDict())
    if content2.match(each):
        key_content2 = key_content1.setdefault(each, OrderedDict())
    if content3.match(each):
        key_content3 = key_content2.setdefault(each, OrderedDict())
    if content4.match(each):
        key_content4 = key_content3.setdefault(each, [])

解析 OrderedDict 写入xlsx

代码语言:javascript复制
result=[]
for title1, title2X in key_title.items():
    for title2, title3X in title2X.items():
        for title3, title4X in title3X.items():
            for title4, content_a in title4X.items():
                for content_a1, content_b in content_a.items():
                    for content_b1, content_c in content_b.items():
                        for content_c1, content_d in content_c.items():
                            for content_d1 in content_d.items():
                                result.append([title1, title2, title3, title4, content_a1[3:], content_b1[5:], content_c1[5:], content_d1[0][3:]])
df = pd.DataFrame(result, columns=['title1', 'title2', 'title3', 'title4', '定义', '英文缩写', '数据格式', '说明'])
df.to_excel("result.xlsx")

最终文件内容如下:

0 人点赞