'commit'
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# 采集配置
|
# 采集配置
|
||||||
SCROLL_DISTANCE_RATIO = 0.3
|
SCROLL_DISTANCE_RATIO = 0.3
|
||||||
MAX_STATIONS_COUNT = 3
|
MAX_STATIONS_COUNT = 30
|
||||||
FIRST_RUN_ONLY_ONE_STATION = False
|
FIRST_RUN_ONLY_ONE_STATION = False
|
||||||
# 场站去重过期时间(秒),在此时间内重复出现的场站不会再次点击进入详情页
|
# 场站去重过期时间(秒),在此时间内重复出现的场站不会再次点击进入详情页
|
||||||
REDIS_STATION_EXPIRE = 120
|
REDIS_STATION_EXPIRE = 120
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
BIN
Tools/Excel/20260115_100311/新电途_20260115_100311.xlsx
Normal file
BIN
Tools/Excel/20260115_100311/新电途_20260115_100311.xlsx
Normal file
Binary file not shown.
BIN
Tools/Excel/20260115_100311/特来电_20260115_100311.xlsx
Normal file
BIN
Tools/Excel/20260115_100311/特来电_20260115_100311.xlsx
Normal file
Binary file not shown.
BIN
Tools/Excel/20260115_100311/艾特吉易充_20260115_100311.xlsx
Normal file
BIN
Tools/Excel/20260115_100311/艾特吉易充_20260115_100311.xlsx
Normal file
Binary file not shown.
BIN
Tools/Excel/20260115_100311/驿来特_20260115_100311.xlsx
Normal file
BIN
Tools/Excel/20260115_100311/驿来特_20260115_100311.xlsx
Normal file
Binary file not shown.
BIN
Tools/Excel/20260115_100442/新电途_20260115_100442.xlsx
Normal file
BIN
Tools/Excel/20260115_100442/新电途_20260115_100442.xlsx
Normal file
Binary file not shown.
BIN
Tools/Excel/20260115_100442/特来电_20260115_100442.xlsx
Normal file
BIN
Tools/Excel/20260115_100442/特来电_20260115_100442.xlsx
Normal file
Binary file not shown.
BIN
Tools/Excel/20260115_100442/艾特吉易充_20260115_100442.xlsx
Normal file
BIN
Tools/Excel/20260115_100442/艾特吉易充_20260115_100442.xlsx
Normal file
Binary file not shown.
BIN
Tools/Excel/20260115_100442/驿来特_20260115_100442.xlsx
Normal file
BIN
Tools/Excel/20260115_100442/驿来特_20260115_100442.xlsx
Normal file
Binary file not shown.
@@ -11,7 +11,7 @@ from typing import Any, Dict, List, Optional, Set
|
|||||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
if project_root not in sys.path:
|
if project_root not in sys.path:
|
||||||
sys.path.append(project_root)
|
sys.path.append(project_root)
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ class DorisExcelExporter:
|
|||||||
if getattr(self.db, "engine", None):
|
if getattr(self.db, "engine", None):
|
||||||
await self.db.engine.dispose()
|
await self.db.engine.dispose()
|
||||||
|
|
||||||
async def fetch_current_station_rows(self) -> List[Dict[str, Any]]:
|
async def fetch_current_station_rows(self, operator: str) -> List[Dict[str, Any]]:
|
||||||
sql = """
|
sql = """
|
||||||
SELECT
|
SELECT
|
||||||
p.station_hash,
|
p.station_hash,
|
||||||
@@ -210,10 +210,10 @@ class DorisExcelExporter:
|
|||||||
ON p.station_hash = s.station_hash AND s.is_current = 1
|
ON p.station_hash = s.station_hash AND s.is_current = 1
|
||||||
LEFT JOIN t_station_price_schedule_scd pr
|
LEFT JOIN t_station_price_schedule_scd pr
|
||||||
ON p.station_hash = pr.station_hash AND pr.is_current = 1
|
ON p.station_hash = pr.station_hash AND pr.is_current = 1
|
||||||
WHERE p.is_current = 1
|
WHERE p.is_current = 1 AND p.operator = :operator
|
||||||
ORDER BY p.station_name
|
ORDER BY p.station_name
|
||||||
"""
|
"""
|
||||||
return await self.db.find(sql)
|
return await self.db.find(sql, {"operator": operator})
|
||||||
|
|
||||||
|
|
||||||
def _build_station_sheet(ws, row: Dict[str, Any]):
|
def _build_station_sheet(ws, row: Dict[str, Any]):
|
||||||
@@ -409,12 +409,12 @@ def _build_station_sheet(ws, row: Dict[str, Any]):
|
|||||||
_set_column_widths(ws, {1: 20, 2: 20, 3: 16, 4: 16, 5: 16, 6: 25})
|
_set_column_widths(ws, {1: 20, 2: 20, 3: 16, 4: 16, 5: 16, 6: 25})
|
||||||
|
|
||||||
|
|
||||||
def _build_summary_sheet(ws, rows: List[Dict[str, Any]]):
|
def _build_summary_sheet(ws, rows: List[Dict[str, Any]], operator: str):
|
||||||
ws.title = "场站总览"
|
ws.title = "场站总览"
|
||||||
ws.sheet_properties.tabColor = "4472C4" # Tab color matches theme
|
ws.sheet_properties.tabColor = "4472C4" # Tab color matches theme
|
||||||
|
|
||||||
# Row 1: Main Title
|
# Row 1: Main Title
|
||||||
title_cell = ws.cell(row=1, column=1, value="新电途充电场站数据总览")
|
title_cell = ws.cell(row=1, column=1, value=f"{operator}充电场站数据总览")
|
||||||
title_cell.font = TITLE_FONT
|
title_cell.font = TITLE_FONT
|
||||||
title_cell.alignment = Alignment(horizontal="center", vertical="center")
|
title_cell.alignment = Alignment(horizontal="center", vertical="center")
|
||||||
ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=10)
|
ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=10)
|
||||||
@@ -448,11 +448,11 @@ def _build_summary_sheet(ws, rows: List[Dict[str, Any]]):
|
|||||||
ws.freeze_panes = ws["A3"]
|
ws.freeze_panes = ws["A3"]
|
||||||
|
|
||||||
|
|
||||||
async def export_excel(output_path: str, *, limit: Optional[int] = None) -> str:
|
async def export_excel(operator: str, output_path: str, *, limit: Optional[int] = None) -> str:
|
||||||
exporter = DorisExcelExporter(db_url=DB_URL)
|
exporter = DorisExcelExporter(db_url=DB_URL)
|
||||||
await exporter.init()
|
await exporter.init()
|
||||||
try:
|
try:
|
||||||
rows = await exporter.fetch_current_station_rows()
|
rows = await exporter.fetch_current_station_rows(operator)
|
||||||
finally:
|
finally:
|
||||||
await exporter.close()
|
await exporter.close()
|
||||||
|
|
||||||
@@ -464,13 +464,13 @@ async def export_excel(output_path: str, *, limit: Optional[int] = None) -> str:
|
|||||||
if not rows:
|
if not rows:
|
||||||
ws = wb.active
|
ws = wb.active
|
||||||
ws.title = "无数据"
|
ws.title = "无数据"
|
||||||
ws.cell(row=1, column=1, value="未查询到任何场站数据")
|
ws.cell(row=1, column=1, value=f"未查询到 {operator} 的任何场站数据")
|
||||||
wb.save(output_path)
|
wb.save(output_path)
|
||||||
return output_path
|
return output_path
|
||||||
|
|
||||||
# 1. 创建总览页
|
# 1. 创建总览页
|
||||||
summary_ws = wb.active
|
summary_ws = wb.active
|
||||||
_build_summary_sheet(summary_ws, rows)
|
_build_summary_sheet(summary_ws, rows, operator)
|
||||||
|
|
||||||
# 2. 为每个场站创建独立页
|
# 2. 为每个场站创建独立页
|
||||||
existing_titles: Set[str] = {"场站总览"}
|
existing_titles: Set[str] = {"场站总览"}
|
||||||
@@ -487,18 +487,33 @@ async def main():
|
|||||||
# 配置:默认导出所有数据,如果需要测试少量数据,可以将 None 改为数字,如 10
|
# 配置:默认导出所有数据,如果需要测试少量数据,可以将 None 改为数字,如 10
|
||||||
limit = None
|
limit = None
|
||||||
|
|
||||||
# 构建默认输出路径
|
# 供应商列表
|
||||||
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
|
operators = ["新电途", "特来电", "驿来特", "艾特吉易充"]
|
||||||
output_filename = f"./Excel/station_export_{ts}.xlsx"
|
|
||||||
output_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), output_filename)
|
|
||||||
|
|
||||||
logger.info(f"开始导出 Excel...")
|
# 构建默认输出目录
|
||||||
logger.info(f"目标文件: {output_path}")
|
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
export_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Excel", ts)
|
||||||
|
if not os.path.exists(export_dir):
|
||||||
|
os.makedirs(export_dir, exist_ok=True)
|
||||||
|
|
||||||
|
logger.info(f"开始批量导出 Excel...")
|
||||||
|
logger.info(f"输出目录: {export_dir}")
|
||||||
|
|
||||||
|
for operator in operators:
|
||||||
|
output_filename = f"{operator}_{ts}.xlsx"
|
||||||
|
output_path = os.path.join(export_dir, output_filename)
|
||||||
|
|
||||||
|
logger.info(f"--- 正在导出 {operator} ---")
|
||||||
if limit is not None:
|
if limit is not None:
|
||||||
logger.info(f"限制导出记录数: {limit}")
|
logger.info(f"限制导出记录数: {limit}")
|
||||||
|
|
||||||
final_path = await export_excel(output_path, limit=limit)
|
try:
|
||||||
logger.info(f"Excel 导出完成: {final_path}")
|
final_path = await export_excel(operator, output_path, limit=limit)
|
||||||
|
logger.info(f"{operator} 导出完成: {final_path}")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"{operator} 导出失败: {e}")
|
||||||
|
|
||||||
|
logger.info("所有导出任务已结束。")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
Reference in New Issue
Block a user