废话不多说,直接上代码。
导入使用的包
import xlrd
from docx import Document
from docx.shared import Pt
from docx.oxml.ns import qn
import re
打开试题Excel文件。
data = xlrd.open_workbook("exam.xlsx")
获取工作表的数量。
sheetsnumber = data.nsheets
定义Word创建方法。
创建Word文件,设置字体类别和大小并保存,传入的参数为内容和文件名。
def word(item,file):
doc1 = Document()
doc1.styles['Normal'].font.name = u'宋体'
doc1.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
doc1.styles['Normal'].font.size = Pt(9)
doc1.add_paragraph(''.join(item))
doc1.save(file)
定义拼接每一行所需cell的方法。
将每张工作表里的每一行我们需要的Col拼接在一起。传入的参数为经过处理后的一行内容列表和length。
假定题目(包含单选、多选、判断)最多有8个选项,如果有更多,你也只需在letters这个List里往后加字母即可。
并且假定这题至少有一个选项。
我们为了保证文本没有多余的换行符,将每个Cell里的换行符替换为空,并且按照逻辑在必要的位置加上换行符。
def joinlist(item,fuck):
letters = ['B','C','D','E','F','G','H']
item[0] = str(item[0]).replace("\n","") + "\n"
item[1] = ("A." + str(item[1]).replace("\n","") if item[1] else "")
if fuck == 3:
item[fuck - 1] = " 答案:" + str(item[fuck - 1]).replace("\n","") + "\n"
return ''.join(item)
if fuck > 3:
for i in range(fuck - 3):
item[2+i] = (" " + str(letters[i])+ "." + str(item[2+i]).replace("\n","") if item[2+i] else "")
item[fuck - 1] = " 答案:" + str(item[fuck - 1]).replace("\n","") + "\n"
return ''.join(item)
定义获取每张工作表所需col索引和length的方法。
获取每张工作表里我们需要的Col。我们初始化一个题目索引列表、一个题库列表、一个问题列表、一个选项列表。
这个函数传入的是参数是每张工作表的第一行。因为第一行包含题目、选项、答案信息。处理的仅仅是一行内容,采用正则表达式,时间复杂度可以认为是O(1)。
一般的题库里会有题目内容、题目解析、答案、答案解析、题干、选项等信息。
在这里,我没有啥高深算法,基于对题目文件的特点的分析,第一个包含有题目或者题干字眼的往往是题目内容的所在列,
第一个包含有答案字眼的往往会是答案所在列。而选项往往会按顺序排布。如果选项超过8项,你只需在modelregexthree这个正则表达式里加入更多字母即可。
最后将匹配到后的结果所在的index一个个append到题目索引列表中。
def process(items):
questionindex = []
question = []
answer = []
choice = []
modelregexone = re.compile(r'题目|题干')
modelregextwo = re.compile(r'答案')
modelregexthree= re.compile(r'A|B|C|D|E|F|G|H',re.I)
for item in items:
if modelregexone.search(item):
question.append(items.index(item))
if modelregextwo.search(item):
answer.append(items.index(item))
if modelregexthree.search(item):
choice.append(items.index(item))
questionindex.append(question[0])
questionindex.extend(choice)
questionindex.append(answer[0])
return questionindex,len(questionindex)
初始化用来储存每张工作表拼接在一起的列表total,用来储存每张工作表内容的列表table,用来储存每张工作表有效行的列表nrows,
用来存储每张工作表有效列的列表ncols,以及用来储存每张工作表所需行内容的列表sum。
第一层循环,遍历每张工作表。
第二层循环,遍历每张工作表里每一行。
第三层循序,对每一行所需单元格进行拼接。
最后汇总拼接,将每张工作表的内容写入不同的Word文档。
total = [ 0 for i in range(sheetsnumber)]
table = [ 0 for i in range(sheetsnumber)]
nrows = [ 0 for i in range(sheetsnumber)]
ncols = [ 0 for i in range(sheetsnumber)]
sum = [ 0 for i in range(sheetsnumber)]
for i in range(sheetsnumber):
table[i] = data.sheets()[i]
nrows[i] = table[i].nrows
ncols[i] = table[i].ncols
temp,fuck = process(table[i].row_values(0,start_colx=0, end_colx=ncols[i]))
sum[i] = []
for j in range(nrows[i]-1):
everyrow = []
index = "(" + str(j+1) + ")"
for k in temp:
everyrow.append(table[i].cell_value(j+1, k))
everyrowlist = index + joinlist(everyrow,fuck)
sum[i].append(everyrowlist)
total[i] = ''.join(sum[i])
title = str(table[i].name) + "专业试题.docx"
word(total[i],title)