|
|
|
|
@ -8,12 +8,12 @@ from fastapi import HTTPException
|
|
|
|
|
from fastapi.responses import JSONResponse
|
|
|
|
|
from docx import Document
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
from datetime import datetime, date
|
|
|
|
|
from docx.shared import Inches, Pt
|
|
|
|
|
from app.tools.deal_excels import deal_excel, top5_dod_analysis, transform_data
|
|
|
|
|
from app.tools.deal_excels import deal_excel, top5_dod_analysis, transform_data, deal_excel_over_load
|
|
|
|
|
from app.tools.get_time import get_time
|
|
|
|
|
from app.tools.replace_text import replace_text_in_docx
|
|
|
|
|
from app.tools.replace_table import copy_table, copy_sta_table, copy_table_no_align
|
|
|
|
|
from app.tools.replace_table import copy_table, copy_sta_table
|
|
|
|
|
from app.tools.style import table_style
|
|
|
|
|
from app.tools.effective_date import get_next_day
|
|
|
|
|
from app.tools.find_before_word import extract_overload_info_from_previous_day
|
|
|
|
|
@ -24,7 +24,7 @@ from app.tools.draw_picture import plot_electricity_comparison
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
def deal_docx(folder_path, save_path=None, time_type=0,over_load_value=0):
|
|
|
|
|
"""
|
|
|
|
|
:param folder_path: 文件上传后保存的路径
|
|
|
|
|
:param save_path: 最终生成的日报/简报的保存路径
|
|
|
|
|
@ -61,8 +61,12 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
file_path_dict["power_off_excel"] = folder_path + "/" + file
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
if file.endswith(".xlsx") and "停电报表配变明细" in file:
|
|
|
|
|
file_path_dict["over_load_excel"] = folder_path + "/" + file
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# 如果传入的文件不对,抛出异常
|
|
|
|
|
if len(file_path_dict) != 3:
|
|
|
|
|
if len(file_path_dict) != 4:
|
|
|
|
|
logger.exception("文件格式错误")
|
|
|
|
|
raise HTTPException(
|
|
|
|
|
status_code=400,
|
|
|
|
|
@ -104,13 +108,29 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
)
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
if "first_point_para2" not in doc_dict:
|
|
|
|
|
if re.match(r".*抢修工单.*", para.text):
|
|
|
|
|
# print(para.text)
|
|
|
|
|
doc_dict["first_point_para2"] = re.sub(
|
|
|
|
|
r"[,,]整体抢修工作态势正常。+$", "", para.text
|
|
|
|
|
)
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# 第二点过载台数
|
|
|
|
|
if re.search(r"过载(\d+)(?:[条台]|\s*)?", para.text):
|
|
|
|
|
doc_dict["over_load"] = (
|
|
|
|
|
re.search(r"过载(\d+)(?:[条台]|\s*)?", para.text).group().replace("过载", "")
|
|
|
|
|
).replace("条", "").replace("台", "")
|
|
|
|
|
# print(doc_dict['over_load'])
|
|
|
|
|
continue
|
|
|
|
|
"""
|
|
|
|
|
if re.search(r"过载\d+台", para.text):
|
|
|
|
|
doc_dict["over_load"] = (
|
|
|
|
|
re.search(r"过载\d+台", para.text).group().replace("过载", "")
|
|
|
|
|
).replace("台", "")
|
|
|
|
|
# print(doc_dict['over_load'])
|
|
|
|
|
continue
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# 拿到舆情的段落
|
|
|
|
|
paragraphs_sentiment = doc_sentiment.paragraphs
|
|
|
|
|
@ -137,11 +157,12 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
table1 = tables[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 表2配变过载监测汇总表
|
|
|
|
|
table2 = tables[1]
|
|
|
|
|
# 表2配变过载监测汇总表——配变过载集成到了一张表table1
|
|
|
|
|
#table2 = tables[1]
|
|
|
|
|
|
|
|
|
|
# 表3停电用户前五供电局
|
|
|
|
|
table3 = tables[2]
|
|
|
|
|
# 表3停电用户前五供电局——停电前五移动到了第二张表
|
|
|
|
|
table3 = tables[1]
|
|
|
|
|
#table3 = tables[2]
|
|
|
|
|
|
|
|
|
|
# 新增表4 95598供电类投诉前五供电局统计表
|
|
|
|
|
# table4 = doc_poweroff.add_table(6, 5)
|
|
|
|
|
@ -251,7 +272,7 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
count = 0
|
|
|
|
|
for i in range(len(need_district_statistics)):
|
|
|
|
|
current_poweroff_value = need_district_statistics[i][1]
|
|
|
|
|
if current_poweroff_value == poweroff_value:
|
|
|
|
|
if current_poweroff_value == poweroff_value and other_count >0:
|
|
|
|
|
count += 1
|
|
|
|
|
else:
|
|
|
|
|
top5_name_list.append(need_district_statistics[i][0])
|
|
|
|
|
@ -259,6 +280,11 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
top_dod_dict[need_district_statistics[i][0]] = top5_dod_analysis(
|
|
|
|
|
need_district_statistics[i], district_stat_before
|
|
|
|
|
)
|
|
|
|
|
if count >0 :
|
|
|
|
|
top5_name_list.append(f"其他{count + other_count}家单位")
|
|
|
|
|
top5_poweroff_list.append(poweroff_value)
|
|
|
|
|
top_dod_dict["其他单位"] = "—"
|
|
|
|
|
"""
|
|
|
|
|
if count == 1 and other_count==0:
|
|
|
|
|
top5_name_list.append(
|
|
|
|
|
need_district_statistics[len(need_district_statistics) - 1][0]
|
|
|
|
|
@ -276,7 +302,7 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
top5_name_list.append(f"其他{count + other_count}家单位")
|
|
|
|
|
top5_poweroff_list.append(poweroff_value)
|
|
|
|
|
top_dod_dict["其他单位"] = "—"
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
# old_version
|
|
|
|
|
"""
|
|
|
|
|
if len(district_statistics) >= 5:
|
|
|
|
|
@ -348,10 +374,10 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
standardize_date = (
|
|
|
|
|
f"{month_before}月{day_before}日17时至{month}月{day}日17时期间,"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
elif time_type == 1:
|
|
|
|
|
# -------------------------20250429更新,修改开始和结束时间---------------------------------
|
|
|
|
|
standardize_date = f"{year}年{month}月{day}日0时至24时期间,"
|
|
|
|
|
#standardize_date = f"{year}年{month}月{day}日0时至24时期间,"
|
|
|
|
|
standardize_date = f"{month}月{day}日0时至24时期间,"
|
|
|
|
|
# standardize_date = ''
|
|
|
|
|
# -------------------------20250429更新,修改开始和结束时间---------------------------------
|
|
|
|
|
|
|
|
|
|
@ -408,6 +434,7 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
short_precentage,
|
|
|
|
|
important_stop_outage,
|
|
|
|
|
type,
|
|
|
|
|
total_yesterday
|
|
|
|
|
) = count_change_outage(doc_dict["have_important"])
|
|
|
|
|
# 获取舆情数字信息
|
|
|
|
|
today_sentiment, type_sentiment, yesterday_sentiment, result_sentiment = (
|
|
|
|
|
@ -424,11 +451,22 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
|
|
|
|
|
current_doc_name = f"南方电网公司停电抢修投诉服务舆情管控三工单联动监测日报{year}{int(month):02d}{int(day):02d}.docx"
|
|
|
|
|
|
|
|
|
|
if "over_load" not in doc_dict:
|
|
|
|
|
raise Exception("过载数据不符合标准未解析,请查看文档")
|
|
|
|
|
doc_dict_over_load = doc_dict["over_load"]
|
|
|
|
|
over_load_before = extract_overload_info_from_previous_day(
|
|
|
|
|
current_word=current_doc_name
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# 2025-07-21
|
|
|
|
|
if not over_load_before :
|
|
|
|
|
if over_load_value>0:
|
|
|
|
|
over_load_before = over_load_value
|
|
|
|
|
else:
|
|
|
|
|
print("缺少昨日配变过载数量,需要手动填写")
|
|
|
|
|
return {
|
|
|
|
|
"status":False,
|
|
|
|
|
"error_message":"缺少昨日配变过载数量,需要手动填写"
|
|
|
|
|
}
|
|
|
|
|
if over_load_before:
|
|
|
|
|
# 将字符串转换为浮点数
|
|
|
|
|
over_load_before = float(over_load_before)
|
|
|
|
|
@ -483,10 +521,9 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
|
|
|
|
|
# 替换模板字符串
|
|
|
|
|
replace_text_in_docx(electricity_daily_simple, replacements_simple)
|
|
|
|
|
|
|
|
|
|
datas = {
|
|
|
|
|
"停电用户\n(万户)": {
|
|
|
|
|
"昨天": total_outage + change_outage,
|
|
|
|
|
"昨天": total_yesterday,
|
|
|
|
|
"今天": total_outage,
|
|
|
|
|
},
|
|
|
|
|
"过载配变\n(台)": {"昨天": over_load_before, "今天": doc_dict_over_load},
|
|
|
|
|
@ -503,12 +540,14 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
# 将数据转换为DataFrame
|
|
|
|
|
df = pd.DataFrame(datas)
|
|
|
|
|
# 遍历 datas 中的每个值,将 None 或 空字符串替换为 0
|
|
|
|
|
"""
|
|
|
|
|
for key, value in datas.items():
|
|
|
|
|
for sub_key, sub_value in value.items():
|
|
|
|
|
if sub_value is None or sub_value == "":
|
|
|
|
|
datas[key][sub_key] = None # 将不存在或为空的值设置为 0
|
|
|
|
|
else:
|
|
|
|
|
datas[key][sub_key] = int(sub_value) # 确保值是整数
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# 生成柱状图
|
|
|
|
|
img_path = plot_electricity_comparison(year, month, day, datas)
|
|
|
|
|
@ -577,7 +616,8 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
|
|
|
|
|
# 将数据组装相关的时间内容
|
|
|
|
|
doc_dict["first_point_para1"] = standardize_date + doc_dict["first_point_para1"]
|
|
|
|
|
doc_dict["sentiment_para"] = standardize_date + doc_dict["sentiment_para"]
|
|
|
|
|
#doc_dict["sentiment_para"] = standardize_date + doc_dict["sentiment_para"]
|
|
|
|
|
doc_dict["sentiment_para"] = doc_dict["sentiment_para"]
|
|
|
|
|
|
|
|
|
|
# {{standardize_date}}全网收到{{complain_num}}条供电类投诉,环比{{complain_dod}}条;
|
|
|
|
|
complain_text = (
|
|
|
|
|
@ -588,6 +628,7 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
replacements = {}
|
|
|
|
|
if time_type == 0:
|
|
|
|
|
# 组装替换的文本
|
|
|
|
|
day_cycle = getDayCycle(year,month,day)
|
|
|
|
|
replacements = {
|
|
|
|
|
"{{year}}": year,
|
|
|
|
|
"{{month}}": month,
|
|
|
|
|
@ -601,10 +642,12 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
"{{sentiment}}": doc_dict["sentiment_para"],
|
|
|
|
|
"{{sentiment_trend}}": doc_dict["sentiment_trend"],
|
|
|
|
|
"{{exception}}": electricity_exception,
|
|
|
|
|
"{{period}}": str(day_cycle),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
elif time_type == 1:
|
|
|
|
|
# 组装替换的文本
|
|
|
|
|
day_cycle = getDayCycle(year_now,month_now,day_now)
|
|
|
|
|
replacements = {
|
|
|
|
|
"{{year}}": str(year_now),
|
|
|
|
|
"{{month}}": str(month_now),
|
|
|
|
|
@ -618,6 +661,7 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
"{{sentiment}}": doc_dict["sentiment_para"],
|
|
|
|
|
"{{sentiment_trend}}": doc_dict["sentiment_trend"],
|
|
|
|
|
"{{exception}}": electricity_exception,
|
|
|
|
|
"{{period}}": str(day_cycle),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 组装日报
|
|
|
|
|
@ -678,21 +722,20 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
# 复制表1的数据
|
|
|
|
|
logger.info("将配变过载写入表0,第二行开始,第9列开始")
|
|
|
|
|
# 定义要查看的区域范围
|
|
|
|
|
start_row2 = 1 # 起始行索引(从0开始)
|
|
|
|
|
end_row2 = 7 # 结束行索引(不包括)
|
|
|
|
|
start_col2 = 2 # 起始列索引(从0开始)
|
|
|
|
|
end_col2 = 4 # 结束列索引(不包括)
|
|
|
|
|
target_row=1
|
|
|
|
|
target_col=7
|
|
|
|
|
copy_table_no_align(
|
|
|
|
|
table2,
|
|
|
|
|
start_row2 = 2 # 起始行索引(从0开始)
|
|
|
|
|
end_row2 = 8 # 结束行索引(不包括)
|
|
|
|
|
start_col2 = 9 # 起始列索引(从0开始)
|
|
|
|
|
end_col2 = 11 # 结束列索引(不包括)
|
|
|
|
|
#target_row=1
|
|
|
|
|
#target_col=7
|
|
|
|
|
copy_table(
|
|
|
|
|
table1,
|
|
|
|
|
electricity_daily.tables[0],
|
|
|
|
|
start_row2,
|
|
|
|
|
end_row2,
|
|
|
|
|
start_col2,
|
|
|
|
|
end_col2,
|
|
|
|
|
target_row,
|
|
|
|
|
target_col
|
|
|
|
|
0
|
|
|
|
|
)
|
|
|
|
|
"""
|
|
|
|
|
copy_table(
|
|
|
|
|
@ -748,6 +791,21 @@ def deal_docx(folder_path, save_path=None, time_type=0):
|
|
|
|
|
is_dynamics=False
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
logger.info("将配变重过载的数据插入表格5")
|
|
|
|
|
# 统计配变过载前五的数据
|
|
|
|
|
top_5_results = deal_excel_over_load(file_path_dict["over_load_excel"])
|
|
|
|
|
# 表4中的插入位置
|
|
|
|
|
start_tb4_row = 2
|
|
|
|
|
start_tb4_col = 8
|
|
|
|
|
if top_5_results:
|
|
|
|
|
#data = top_5_results.values
|
|
|
|
|
copy_sta_table(
|
|
|
|
|
electricity_daily.tables[1],
|
|
|
|
|
top_5_results,
|
|
|
|
|
start_tb4_row,
|
|
|
|
|
start_tb4_col,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# copy_sta_table(electricity_daily.tables[3], top5_list, start_tb4_row, start_tb4_col)
|
|
|
|
|
|
|
|
|
|
# 将表格中的字体中文设置成仿宋,英文数字设置成新罗马,均为11号大小
|
|
|
|
|
@ -821,6 +879,17 @@ def delete_old_file(file):
|
|
|
|
|
logger.info(f"删除旧文件失败:{e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def getDayCycle(year_str,month_str,day_str):
|
|
|
|
|
year = int(year_str)
|
|
|
|
|
month = int(month_str)
|
|
|
|
|
day = int(day_str)
|
|
|
|
|
# 创建日期对象
|
|
|
|
|
d = date(year, month, day)
|
|
|
|
|
# 获取是今年的第几天
|
|
|
|
|
day_of_year = d.timetuple().tm_yday-1
|
|
|
|
|
print(f"{year}年{month}月{day}日是今年的第 {day_of_year} 天。")
|
|
|
|
|
return day_of_year
|
|
|
|
|
|
|
|
|
|
# if __name__ == '__main__':
|
|
|
|
|
# folder_path = 'E:/work_data/work/三工单日报/20250310/20250310'
|
|
|
|
|
#
|
|
|
|
|
|