python实现word转成自定义格式的excel文档(解决思路和代码) 支持按照文件夹去批量处理,也可以单独一个文件进行处理,并且可以自定义标识符。
最近在开发一个答题类的小程序,到了录入试题进行测试的时候了,发现一个问题,试题都是word文档格式的,每份有100题左右,拿到的第一份试题,光是段落数目就有800个。而且可能有几十份这样的试题。
而word文档是没有固定格式的,想批量录入关系型数据库mysql,必须先转成excel文档。这个如果是手动一个个粘贴到excel表格,那就头大了。
我最终需要的excel文档结构是这样的:每道题独立占1行,每1列是这道题的一项内容,大概就是问题、选项A、选项B等等。、
但word文档是这种结构,如果按照网上通用的方式去转,基本上你得到的结果就是一大坨文字都在一格里,根本不符合需求。
最后我想到了一个解决思路,可以实现这个需求,先看看我转出来的结果:
这个格式虽然跟最终的有点差别,但是只要在excel文档或者在代码里稍微再修改一下,就能完全符合要求了。
废话少说,先贴出代码,看得懂的可以直接拿去用,看不懂的,可以看我后面的具体说明。
已经把它封装成通用脚本了,你可以直接调用。
import pandas as pd import os # 初始处理函数1,先对初始处理结果进行判断 def initail_handle_by_range(file_path, max_page_num, split_str): df = pd.read_table(file_path) # 2、先转成Series S = pd.Series(df['column1'].values) # 3、转成列表,列表的每个元素就是每个段落 list = S.tolist() # 传入一个max_page_num # 4、遍历列表,取出每个段落,按“.”切割,取出第一个元素进行判断,如果它是题号,就应该得到"1"或者"10" index_list = [] for content in list: try: # 不是每个段落都有“.”可以切割的,会报错,报错就跳过 first_str = content.split('%s'%split_str)[0] # 5、根据最大的题号,自动生成匹配的字符串,用来匹配题号(每个匹配字符串都放在patch_list中) patch_list = ['%d' % i for i in range(1, max_page_num + 1)] # 6、比对切割得到的第一个元素,如果它在匹配的字符串中,就获取它在列表中的索引,并把获取到的结果添加到列表index_list中,这就知道了每道题的开头在l中的哪个位置了 if first_str in patch_list: index = list.index(content) index_list.append(index) except: pass # 7、根据索引列表,我们可以知道每道题的第一段和最后一段在l中的哪个位置 # index_list = [0, 8, 16] # print(index_list) # 先计算每道题长度是否一致,不一致的,设置is_same_length = False is_same_length = True length = index_list[1] - index_list[0] max_index = len(list) for i in index_list: # 如果i不是最后一个,那么start就是i,end就是i的下一个 if i < index_list[-1]: start = i end = index_list[index_list.index(i) + 1] else: start = i end = max_index # 判断长度是否一致,不一致就对长度进行比较,把大的赋值给长度 if (end - start) != length: is_same_length = False if (end - start) > length: length = (end - start) result = [is_same_length, index_list, list, length] return result # 初始处理函数1,先对初始处理结果进行判断 def initail_handle_by_patchstr(file_path, patch_str, split_str): df = pd.read_table(file_path) # 2、先转成Series S = pd.Series(df['column1'].values) # 3、转成列表,列表的每个元素就是每个段落 list = S.tolist() # 传入一个max_page_num # 4、遍历列表,取出每个段落,按“.”切割,取出第一个元素进行判断,如果它是题号,就应该得到"1"或者"10" index_list = [] for content in list: try: # 不是每个段落都有“.”可以切割的,会报错,报错就跳过 first_str = content.split('%s'%split_str)[0] # 6、比对切割得到的第一个元素,如果它在匹配的字符串中,就获取它在列表中的索引,并把获取到的结果添加到列表index_list中,这就知道了每道题的开头在l中的哪个位置了 if first_str == patch_str: index = list.index(content) index_list.append(index) except: pass # 7、根据索引列表,我们可以知道每道题的第一段和最后一段在l中的哪个位置 # index_list = [0, 8, 16] # print(index_list) # 先计算每道题长度是否一致,不一致的,设置is_same_length = False is_same_length = True length = index_list[1] - index_list[0] max_index = len(list) for i in index_list: # 如果i不是最后一个,那么start就是i,end就是i的下一个 if i < index_list[-1]: start = i end = index_list[index_list.index(i) +