当前位置: 首页 > news >正文

【Python】Word文档解析表格并导出Excel

 

一、需求背景

有N个docx文档,每个文档文件名是 xxxx公司-方案报告

然后每个文档中固定有两个表的数据需要获取,每个文档的表格不一定存在

表格数据固定在这两个的标题下面,系统漏洞 和 弱口令

image

系统漏洞表格列信息为,其中单位信息来自于文档的文件名上

单位 IP地址 端口 漏洞名称 风险等级 漏洞描述 加固措施

然后是弱口令列表

单位 序号 资产IP 弱口令用户名 密码 密码类型

 

二、逻辑分析

1、解决批量处理word文档的问题

  这个脑子很容易想到,放到一个目录下,读取全部docx文档的文件

2、读取每个文档后,找到目标标题,然后再找到表格信息

  这是最开始的读取逻辑思路,因为像Html文档结构一样,找到当前元素的下一个元素就可以了

  结果发现这些报告文件的标题信息都不一样,有的叫系统漏洞清单,弱密码列表,有的又是漏洞列表,弱密码清单

  第二个问题是,每个文档元素在word中没有必然关联性,无法通过当前元素对象来查找下一个元素

  所以想到本身是要查找表格,就干脆就去查表格就行

  只要这个表格的第一行的信息匹配固定的字符串,就可以确定是这个表格的数据需要读取

3、表格的信息还需要再调整

  对表格数据需要新增一列单位信息,单位信息的数据在文件名上提供了

  然后是每个表格都携带了表格头,需要去除第一行的信息

  再汇总到一个集合中,这样就是一个完整的数据了

4、最后创建excel生成

  创建一个Excel,两个Sheet页,一个叫系统漏洞,一个叫弱密码

    每个Sheet页声明好列头信息,然后写入上述读取的数据源

  完成后生成文件结束

 

三、代码实现

import os
import re
from datetime import datetimeimport openpyxl
from docx import Document
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, Border, Side
from openpyxl.utils import get_column_letterdef extract_company_name(filename):"""从文件名中提取公司名称Args:filename (str): 文件名Returns:str: 公司名称"""# 使用正则表达式匹配"xxxx公司"格式match = re.search(r'(.+?公司)', filename)if match:return match.group(1)else:# 如果无法匹配,返回文件名(不含扩展名)的前部分return os.path.splitext(filename)[0].split('-')[0].strip()# 寻找特定表格数据
def find_target_tables(doc: Document):vuln_pattern = ['序号|IP地址|端口|漏洞名称|风险等级|加固措施|漏洞描述','IP地址|端口|漏洞名称|风险等级|漏洞描述|加固措施','IP地址|端口|漏洞名称|风险等级|漏洞描述|整改建议','IP地址|端口|漏洞名称|风险等级|漏洞描述|修复建议','IP地址|端口|漏洞名称|风险等级|漏洞描述|CVE编号',]weak_pwd_pattern = ['序号|资产IP|弱口令用户名|密码|密码类型','序号|资产IP|弱口令用户名|密码|密码类型|破解工具']vuln_table = Noneweak_pwd_table = Nonefor table in doc.tables:headerRow = table.rows[0]cells = [cell.text for cell in headerRow.cells]table_title = '|'.join(cells)if table_title in vuln_pattern:vuln_table = tablebreakfor table in doc.tables:headerRow = table.rows[0]cells = [cell.text for cell in headerRow.cells]table_title = '|'.join(cells)if table_title in weak_pwd_pattern:weak_pwd_table = tablebreakreturn vuln_table, weak_pwd_table# IP地址 | 端口 | 漏洞名称 | 风险等级 | 漏洞描述 | 加固措施 |
# 序号 | 资产IP | 弱口令用户名 | 密码 | 密码类型 |if __name__ == "__main__":# 指定包含Word文档的文件夹路径folder_path = r'C:\Users\Administrator\Desktop\工作日志\word-batch\调研报告方案-天融信'cate = '调研报告方案-天融信'# 检查路径是否存在if not os.path.exists(folder_path):print("指定的路径不存在!")exit()vuln_data = []weak_pwd_data = []# 遍历文件夹中的所有文件for filename in os.listdir(folder_path):# 从文件名提取公司名称if filename.endswith('.docx'):company_name = extract_company_name(filename)file_path = os.path.join(folder_path, filename)print(f'已读取到文件:{filename} 路径:{file_path}, 单位:{company_name}')# 处理单个文档doc = Document(file_path)vuln_table, weak_pwd_table = find_target_tables(doc)if vuln_table is not None:# for row in vuln_table.rows:#     for cell in row.cells:#         print(f'{cell.text}|', end='')#     print()print('- - - - - 漏洞信息 - - - - - ')for row_idx, row in enumerate(vuln_table.rows):# 跳过第一行(表头)if row_idx == 0:continue# 提取单元格数据row_data = [cell.text.strip() for cell in row.cells]# 在开头添加单位信息作为第一列row_data.insert(0, company_name)vuln_data.append(row_data)print(row_data)if weak_pwd_table is not None:# for row in weak_pwd_table.rows:#     for cell in row.cells:#         print(f'{cell.text} |', end='')#     print()print('- - - - - 弱密码 - - - - - ')for row_idx, row in enumerate(weak_pwd_table.rows):# 跳过第一行(表头)if row_idx == 0:continue# 提取单元格数据row_data = [cell.text.strip() for cell in row.cells]# 在开头添加单位信息作为第一列row_data.insert(0, company_name)weak_pwd_data.append(row_data)print(row_data)# 创建工作薄wb = Workbook()# 设置sheet信息sheet1 = wb.activesheet1.title = "主机漏洞"sheet2 = wb.create_sheet(title="弱口令")# 设置表头样式header_font = Font(bold=True, size=12, color="FFFFFF")header_fill = "004C99"  # 深蓝色header_alignment = Alignment(horizontal='center', vertical='center', wrap_text=True)data_font = Font(size=11)data_alignment = Alignment(horizontal='left', vertical='center')thin_border = Border(left=Side(style='thin'),right=Side(style='thin'),top=Side(style='thin'),bottom=Side(style='thin'))# 设置标题头sheet1_headers = ["单位", "IP地址", "端口", "漏洞名称", "风险等级", "漏洞描述", "加固措施"]for col, header in enumerate(sheet1_headers, 1):cell = sheet1.cell(row=1, column=col, value=header)cell.font = header_fontcell.alignment = header_alignmentcell.fill = openpyxl.styles.PatternFill(start_color=header_fill, end_color=header_fill, fill_type="solid")cell.border = thin_bordersheet2_headers = ["单位", "序号", "资产IP", "弱口令用户名", "密码", "密码类型"]for col, header in enumerate(sheet2_headers, 1):cell = sheet2.cell(row=1, column=col, value=header)cell.font = header_fontcell.alignment = header_alignmentcell.fill = openpyxl.styles.PatternFill(start_color=header_fill, end_color=header_fill, fill_type="solid")cell.border = thin_border# 写入数据for row_idx, vuln in enumerate(vuln_data, 2):  # 从第2行开始for col_idx, value in enumerate(vuln, 1):cell = sheet1.cell(row=row_idx, column=col_idx, value=value)cell.font = data_fontcell.alignment = data_alignmentcell.border = thin_borderfor row_idx, wp in enumerate(weak_pwd_data, 2):for col_idx, value in enumerate(wp, 1):cell = sheet2.cell(row=row_idx, column=col_idx, value=value)cell.font = data_fontcell.alignment = data_alignmentcell.border = thin_border# 6. 自动调整列宽for sheet in wb:for col in sheet.columns:max_length = 0column_letter = get_column_letter(col[0].column)for cell in col:try:if cell.value:# 计算单元格内容的长度cell_length = len(str(cell.value))# 如果是日期格式,可能需要额外长度if isinstance(cell.value, datetime):cell_length = 10  # 标准日期格式长度max_length = max(max_length, cell_length)except:pass# 设置最小和最大列宽adjusted_width = min(max(max_length + 2, 10), 50)sheet.column_dimensions[column_letter].width = adjusted_width# 生成带时间戳的文件名timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")filename = f"漏洞和弱口令汇总_{cate}_{timestamp}.xlsx"file_path = os.path.join(folder_path, filename)wb.save(file_path)print(f"Excel文件已成功创建: {file_path}")

  

 

http://www.hskmm.com/?act=detail&tid=561

相关文章:

  • 海明码破解指南:从让人头疼的软考题到内存背后的无名英雄
  • 2025.9.9 总结
  • 基于Python+Vue开发的医院门诊预约挂号系统源码+运行
  • 2025 9 6 总结
  • 2025.9.8 总结
  • OLE读取EXCEL内容
  • 第5篇、 Kafka 数据可靠性与容错机制
  • Shell符号详解
  • Dynamics 365 CRM + Power Platform 技术顾问:解锁 IT 高薪赛道,长沙爱码士 IT 助你全程通关
  • Rope pbds
  • 295、嫦娥
  • 25.9.8随笔联考总结
  • rmrs 题解
  • IT 失业人员的福音:借微软 Dynamics 365 CRM 与 Power Platform 快速重启职业生涯
  • qoj10096 Generating Random Trees
  • 测试
  • PHP 轻松处理千万行数据 内存不爆,服务器不卡
  • 2025 杭电暑期多校训练
  • 友链
  • BongoCat - 可爱的桌面互动猫咪
  • qoj6279 Honeycomb
  • Vue 将api 获取的 json 数据保存到本地
  • Claude Code新手入门指南:AI编程助手完全教程
  • 0124_观察者模式(Observer)
  • 读人形机器人07零售行业
  • 你可能不需要WebSocket-服务器发送事件的简单力量
  • 2014年11月微软安全更新风险评估与技术解析
  • 洛谷P5854 【模板】笛卡尔树 题解 笛卡尔树模板题
  • [Flink] Flink 经典场景:数据流输出到多个Sink
  • 都江堰操作系统