任务:将一个一千多页的pdf中的表格数据提取出来,拼接成html表格,以便在富文本中更好查看
pdf中的表格如图所示
步骤
1.其中有些表格是跨页的(即同一张表格不在同一个页面),像上面的第一个表格就是属于跨列,如果不做判断,获取到的原属于同一个表格的就会分开了,所以要把属于同一个表格的拼接起来。
2.所有表头都是相同的,所以处理时候遇到表头就把上个表格内容存进数据库。
3.因为我们想要的表格是从30页开始,最后一页结束,所以这两页要特殊处理。
4.还有个需求,把表格第二列"搜素打开菜单"中的内容提取出来存进数据库的另一个字段,如:搜索打开菜单:【有价卡换卡】中的有价卡换卡。
代码
代码如下:
因为我有django项目,为了方便点,所以我直接就在项目里写一个路由(部分代码省略)用orm操作数据库,也可以自己修改成用原生操作数据库的方法存进数据库。
#将pdf中的测试步骤表格数据提取出来存进数据库 import pdfplumber, time from .models import ScenarioInfo #这里是引入模型中的ScenarioInfo表 with pdfplumber.open(r\'C:\Users\hisoft\Desktop\(2019-09-25)_21460.pdf\') as pdf: m = 0 # 测试步骤表格的数量(按表头数算) s = \'<table><tbody>\' mjcd = \'\' # 末级菜单 for i in range(29, len(pdf.pages)): # 从第30页开始获取表格数据 page = pdf.pages[i] # 设置操作页面 n = 1 # 当前页的第n个表格 for table in page.extract_tables(): k = True for row in range(len(table)): if str(table[ row]) == r"[\'Step\', \'案例步骤\', \'预期结果\', \'测试信息\', \'耗时(秒\n)\', \'结果\']": # 这是根据表格行内容判断是否是一个新的表格开头,因为表头内容都是固定的 if i == 29 and n == 1: # 判断是否是第30页的第一个表格 pass else: s += \'</tbody></table>\' print(\'i=\', i) # print(\'s=\', s) # print(\'mjcd=\', mjcd) m += 1 ScenarioInfo.objects.create(test_steps=s, lrry=\'哈哈哈\', mjcd=mjcd) #存进数据库,s是拼接好的表格字符串,富文本会识别表格标签显示 time.sleep(0.6) mjcd = \'\' s = \'<table><tbody>\' for j in range(len(table[row])): if j == 0: # 判断是否是当前行的第一列 s += \'<tr><td>\' s += table[row][j] if j == 1: # 判断是否是当前行的第二列,将末级菜单取出来,若碰到有多个末级菜单的只取第一个 if k: if len(table[row][j].split(\'搜索打开菜单:【\')) > 1: mjcd = table[row][j].split(\'搜索打开菜单:【\')[1].split(\'】\')[0] k = False if j == len(table[row]) - 1: # 判断是否是当前行的最后一列 s += \'</td></tr>\' else: s += \'</td><td>\' if i == len(pdf.pages) - 1: # 判断是否是最后一页 if n == len(page.extract_tables()): # 判断是否是最后一个表格 for row in range(len(table)): if row == len(table) - 1: # 判断是否是当前表格的最后一行 for j in range(len(table[row])): if j == len(table[row]) - 1: # 判断是否是当前行的最后一列 s += \'</tbody></table>\' print(\'i=\', i) print(\'end_s=:\', s) m += 1 print(\'m=\', m) print(\'mjcd=\', mjcd) ScenarioInfo.objects.create(test_steps=s, lrry=\'哈哈哈\', mjcd=mjcd) #存进数据库 n += 1