# -*- coding: utf-8 -*-
"""Created on Fri Dec 13 17:57:45 2019
@author: johwang
"""
import win32com#引入win32com模块,通过.com调用office标准接口
from win32com.client import Dispatch, constants
import numpy#引入矩阵管理模块,允许调用矩阵管理命令
from tkinter import filedialog#引入对话框模块,用来通过选择的方式获取文件路径
from tqdm import tqdm
wc = win32com.client.constants#引入.com中的常量,获取后python可以获取VBA可以调用的各类常量,本文中用于辅助获取页码
msword = win32com.client.gencache.EnsureDispatch('word.Application')#建立一个word类的对象
msword.Visible = 0 #是否可见
msword.DisplayAlerts = 0
Fpath=filedialog.askopenfilename(title=u'请选择要提取目录的文件',) # 获取目标处理文件的路径
doc = msword.Documents.Open(Fpath) #建立与选定word之间的链接,可以通过doc.调用com接口
"""
下面这段用来获取word中Heading类型的标题数量,并创建一个尺寸对应的空矩阵用来存放页码及标题信息
"""
print("正在读取word中的标题数量,请等待……")
titlenum=0
for I in tqdm(range(1,doc.Paragraphs.Count)):
if 'Heading' in str(doc.Paragraphs(I).Style):
titlenum+=1
a= [[0] * 7 for _ in range(titlenum+2)]
"""
下面这段用来初始化矩阵的头信息,存储矩阵每列的代表信息
"""
a[0][0]="标题Style"
a[0][1]="标题名称"
a[0][2]="标题所在页码"
a[0][3]="标题上一段所在页码"
a[0][4]="标题层级"
a[0][5]="标题覆盖内容结束页码"
a[0][6]="标题编号"
"""
下面这段用来将word中的页码、标题、编号等信息读取到矩阵a中
"""
J=1
I=0
print("\n正在读取word中的页码及标题信息,请等待……")
for I in tqdm(range(1,doc.Paragraphs.Count)):
if 'Heading' in str(doc.Paragraphs(I).Style):
a[J][0] = str(doc.Paragraphs(I).Style)#读取word标题类型
a[J][1] = doc.Paragraphs(I).Range.Text#读取标题内容
a[J][2] = doc.Paragraphs(I).Range.Information(wc.wdActiveEndPageNumber)#读取标题所在页码
a[J][6] = doc.Paragraphs(I).Range.ListFormat.ListString#读取标题编号
if I>1:
a[J][3] = doc.Paragraphs(I - 1).Range.Information(wc.wdActiveEndPageNumber)
J=J+1
"""
下面4行用来获取整篇word最后一行的页码,同时将最后一行的标题定义成一级标题,用来辅助计算出每个章节的
结束页码
"""
a[J][0] = "Heading 1"
a[J][1] = "文档总页数(最后一行所在页数)"
a[J][2] = doc.Paragraphs(doc.Paragraphs.Count).Range.Information(wc.wdActiveEndPageNumber)
a[J][3] = doc.Paragraphs(doc.Paragraphs.Count).Range.Information(wc.wdActiveEndPageNumber)
a=numpy.array(a)#数组化,方便展示。无实际意义可以不用
"""
下面这6行用来计算,矩阵a中各级标题的级别,结果用来辅助计算每个章节的结束页码
"""
print("\n正在计算各级标题的层级,请等待……")
for j in tqdm(range(1,15)):
for i in range(1,len(a)):
if a[i-1][0] == 'Heading '+str(j):
a[i-1][4] = j
i=i+1
j+=1
print("\n正在计算各层级标题的结束页码,请等待……")
"""
下面这6行,是整个程序的核心算法,即通过两个原则推算出各级标题的结束页码
1、每一个层级标题的结束页码等于,下一个同等级别或者更高级别标题的前一段落的页码
2、最后一个各层级标题(7(最后一个一级标题);7.5(最后一个二级标题)……)的结束页码等于文档的结束页码
"""
for k in range (1,len(a)):
for l in range (k,len(a)-1):
if a[k][4]>=a[l][4]:
a[k][5]=a[l][3]
break
else:l+=1
k+=1
Savepath=filedialog.askdirectory(title=u'请选择目录的存放位置',)#通过界面获取存储章节目录文件的目录
savetxtname=input("请输入存储的文件名:")#通过界面获取文件名
print("正在写出文件,请等待……")
numpy.savetxt((Savepath+"/"+savetxtname+'.txt'),a, delimiter=',', fmt = '%s')#写出文件