265 lines
8.5 KiB
Python
265 lines
8.5 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
"""
|
|||
|
|
测试Word COM操作,定位报告生成卡住的具体位置
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import json
|
|||
|
|
import sys
|
|||
|
|
import os
|
|||
|
|
import time
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
def test_basic_word_operations():
|
|||
|
|
"""测试基本的Word COM操作"""
|
|||
|
|
print("测试基本Word COM操作:")
|
|||
|
|
print("=" * 40)
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
import win32com.client
|
|||
|
|
from win32com.client import constants
|
|||
|
|
|
|||
|
|
print("✓ 导入win32com成功")
|
|||
|
|
|
|||
|
|
# 创建Word应用程序
|
|||
|
|
print("创建Word应用程序...")
|
|||
|
|
word_app = win32com.client.Dispatch("Word.Application")
|
|||
|
|
word_app.Visible = False # 不显示Word窗口
|
|||
|
|
print("✓ Word应用程序创建成功")
|
|||
|
|
|
|||
|
|
# 创建新文档
|
|||
|
|
print("创建新文档...")
|
|||
|
|
doc = word_app.Documents.Add()
|
|||
|
|
print("✓ 新文档创建成功")
|
|||
|
|
|
|||
|
|
# 插入表格
|
|||
|
|
print("插入测试表格...")
|
|||
|
|
table = doc.Tables.Add(doc.Range(0, 0), 25, 10) # 25行10列,比实际需要的大
|
|||
|
|
print("✓ 表格插入成功")
|
|||
|
|
|
|||
|
|
# 测试单元格写入
|
|||
|
|
print("测试单元格写入...")
|
|||
|
|
test_cells = [
|
|||
|
|
(1, 1, "测试1"),
|
|||
|
|
(5, 3, "23.2"),
|
|||
|
|
(10, 5, "2025-11-27 11:30:00"),
|
|||
|
|
(20, 8, "478.0")
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
for row, col, value in test_cells:
|
|||
|
|
try:
|
|||
|
|
cell = table.Cell(row, col)
|
|||
|
|
cell.Range.Text = str(value)
|
|||
|
|
print(f" ✓ 写入单元格 ({row}, {col}): {value}")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" ✗ 写入单元格 ({row}, {col}) 失败: {e}")
|
|||
|
|
|
|||
|
|
print("✓ 基本操作测试完成")
|
|||
|
|
|
|||
|
|
# 清理
|
|||
|
|
doc.Close(SaveChanges=False)
|
|||
|
|
word_app.Quit()
|
|||
|
|
print("✓ Word应用程序已关闭")
|
|||
|
|
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"✗ Word COM操作失败: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def test_template_operations():
|
|||
|
|
"""测试模板操作"""
|
|||
|
|
print("\n测试Word模板操作:")
|
|||
|
|
print("=" * 40)
|
|||
|
|
|
|||
|
|
# 查找模板文件
|
|||
|
|
template_files = []
|
|||
|
|
search_paths = [
|
|||
|
|
Path("."),
|
|||
|
|
Path("E:/docx_creatorV2"),
|
|||
|
|
Path("f:/PyPro/docx_creator")
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
for search_path in search_paths:
|
|||
|
|
if search_path.exists():
|
|||
|
|
templates = list(search_path.glob("*.docx"))
|
|||
|
|
template_files.extend(templates)
|
|||
|
|
|
|||
|
|
if not template_files:
|
|||
|
|
print("⚠️ 未找到Word模板文件")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
print(f"找到模板文件: {len(template_files)} 个")
|
|||
|
|
for template in template_files[:3]: # 只显示前3个
|
|||
|
|
print(f" - {template}")
|
|||
|
|
|
|||
|
|
# 测试打开模板
|
|||
|
|
try:
|
|||
|
|
import win32com.client
|
|||
|
|
|
|||
|
|
word_app = win32com.client.Dispatch("Word.Application")
|
|||
|
|
word_app.Visible = False
|
|||
|
|
|
|||
|
|
template_path = template_files[0]
|
|||
|
|
print(f"\n尝试打开模板: {template_path}")
|
|||
|
|
|
|||
|
|
# 确保使用绝对路径
|
|||
|
|
abs_template_path = template_path.resolve()
|
|||
|
|
print(f"绝对路径: {abs_template_path}")
|
|||
|
|
|
|||
|
|
if not abs_template_path.exists():
|
|||
|
|
print(f"✗ 模板文件不存在: {abs_template_path}")
|
|||
|
|
word_app.Quit()
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
doc = word_app.Documents.Open(str(abs_template_path))
|
|||
|
|
print("✓ 模板打开成功")
|
|||
|
|
|
|||
|
|
# 检查模板中的表格
|
|||
|
|
tables_count = doc.Tables.Count
|
|||
|
|
print(f"模板中的表格数量: {tables_count}")
|
|||
|
|
|
|||
|
|
if tables_count > 0:
|
|||
|
|
table = doc.Tables(1) # Word中索引从1开始
|
|||
|
|
rows_count = table.Rows.Count
|
|||
|
|
cols_count = table.Columns.Count
|
|||
|
|
print(f"第一个表格尺寸: {rows_count} 行 x {cols_count} 列")
|
|||
|
|
|
|||
|
|
# 查找scriptTable1标记
|
|||
|
|
found_token = False
|
|||
|
|
try:
|
|||
|
|
for i in range(1, min(rows_count + 1, 10)): # 只检查前10行
|
|||
|
|
for j in range(1, min(cols_count + 1, 10)): # 只检查前10列
|
|||
|
|
try:
|
|||
|
|
cell_text = table.Cell(i, j).Range.Text
|
|||
|
|
if "scriptTable1" in cell_text:
|
|||
|
|
print(f"✓ 找到scriptTable1标记在 ({i}, {j})")
|
|||
|
|
found_token = True
|
|||
|
|
break
|
|||
|
|
except:
|
|||
|
|
continue
|
|||
|
|
if found_token:
|
|||
|
|
break
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"搜索标记时出错: {e}")
|
|||
|
|
|
|||
|
|
if not found_token:
|
|||
|
|
print("⚠️ 未找到scriptTable1标记")
|
|||
|
|
|
|||
|
|
doc.Close(SaveChanges=False)
|
|||
|
|
word_app.Quit()
|
|||
|
|
print("✓ 模板测试完成")
|
|||
|
|
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"✗ 模板操作失败: {e}")
|
|||
|
|
try:
|
|||
|
|
word_app.Quit()
|
|||
|
|
except:
|
|||
|
|
pass
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def test_large_data_processing():
|
|||
|
|
"""测试大量数据处理"""
|
|||
|
|
print("\n测试大量数据处理:")
|
|||
|
|
print("=" * 40)
|
|||
|
|
|
|||
|
|
# 模拟你的实际数据量
|
|||
|
|
test_data = []
|
|||
|
|
for row in range(21): # 0-20行
|
|||
|
|
for col in range(7): # 0-6列
|
|||
|
|
if (row, col) in [(1, 1), (1, 3), (0, 1)]: # 时间和环境温度
|
|||
|
|
test_data.append({"row": row, "col": col, "value": "2025-11-27 11:30:00"})
|
|||
|
|
elif row >= 4 and row <= 20: # 温度数据
|
|||
|
|
test_data.append({"row": row, "col": col, "value": f"{20 + row + col * 0.5:.1f}"})
|
|||
|
|
|
|||
|
|
print(f"测试数据量: {len(test_data)} 个单元格")
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
import win32com.client
|
|||
|
|
|
|||
|
|
word_app = win32com.client.Dispatch("Word.Application")
|
|||
|
|
word_app.Visible = False
|
|||
|
|
|
|||
|
|
doc = word_app.Documents.Add()
|
|||
|
|
table = doc.Tables.Add(doc.Range(0, 0), 25, 10)
|
|||
|
|
|
|||
|
|
print("开始批量写入数据...")
|
|||
|
|
start_time = time.time()
|
|||
|
|
|
|||
|
|
processed = 0
|
|||
|
|
for i, cell_data in enumerate(test_data):
|
|||
|
|
try:
|
|||
|
|
row = cell_data["row"] + 1 # Word索引从1开始
|
|||
|
|
col = cell_data["col"] + 1
|
|||
|
|
value = str(cell_data["value"])
|
|||
|
|
|
|||
|
|
cell = table.Cell(row, col)
|
|||
|
|
cell.Range.Text = value
|
|||
|
|
processed += 1
|
|||
|
|
|
|||
|
|
# 每50个单元格报告一次进度
|
|||
|
|
if (i + 1) % 50 == 0:
|
|||
|
|
elapsed = time.time() - start_time
|
|||
|
|
print(f" 进度: {i + 1}/{len(test_data)} ({elapsed:.1f}秒)")
|
|||
|
|
|
|||
|
|
# 如果处理时间过长,提前退出
|
|||
|
|
if elapsed > 30: # 30秒超时
|
|||
|
|
print("⚠️ 处理时间过长,提前退出")
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" ✗ 处理单元格 ({row}, {col}) 失败: {e}")
|
|||
|
|
break
|
|||
|
|
|
|||
|
|
total_time = time.time() - start_time
|
|||
|
|
print(f"✓ 处理完成: {processed}/{len(test_data)} 个单元格,耗时 {total_time:.1f} 秒")
|
|||
|
|
|
|||
|
|
if total_time > 10:
|
|||
|
|
print("⚠️ 处理时间较长,可能存在性能问题")
|
|||
|
|
|
|||
|
|
doc.Close(SaveChanges=False)
|
|||
|
|
word_app.Quit()
|
|||
|
|
|
|||
|
|
return processed == len(test_data)
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"✗ 大量数据处理失败: {e}")
|
|||
|
|
try:
|
|||
|
|
word_app.Quit()
|
|||
|
|
except:
|
|||
|
|
pass
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
print("Word COM操作测试")
|
|||
|
|
print("=" * 50)
|
|||
|
|
|
|||
|
|
# 测试基本操作
|
|||
|
|
basic_ok = test_basic_word_operations()
|
|||
|
|
|
|||
|
|
# 测试模板操作
|
|||
|
|
template_ok = test_template_operations()
|
|||
|
|
|
|||
|
|
# 测试大量数据处理
|
|||
|
|
data_ok = test_large_data_processing()
|
|||
|
|
|
|||
|
|
print("\n" + "=" * 50)
|
|||
|
|
print("测试结果总结:")
|
|||
|
|
print(f"基本Word操作: {'✓ 通过' if basic_ok else '✗ 失败'}")
|
|||
|
|
print(f"模板操作: {'✓ 通过' if template_ok else '✗ 失败'}")
|
|||
|
|
print(f"大量数据处理: {'✓ 通过' if data_ok else '✗ 失败'}")
|
|||
|
|
|
|||
|
|
if not all([basic_ok, template_ok, data_ok]):
|
|||
|
|
print("\n建议:")
|
|||
|
|
if not basic_ok:
|
|||
|
|
print("- 检查Word安装和COM组件")
|
|||
|
|
if not template_ok:
|
|||
|
|
print("- 检查Word模板文件是否存在和可访问")
|
|||
|
|
if not data_ok:
|
|||
|
|
print("- 可能是大量数据处理导致的性能问题")
|
|||
|
|
print("- 建议分批处理数据或优化算法")
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|