Functions-d 1.28__tar.gz → 1.30__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1558,7 +1558,129 @@ class DataProcessingAndMessaging:
1558
1558
  # 其他未知错误才记录警告
1559
1559
  self.logger.warning(f"关闭Excel进程时发生异常: {str(e)}")
1560
1560
 
1561
+ # -------------------------- 上传文件/DF到内网文件服务器(最终完整版) --------------------------
1562
+ def upload_to_internal_server(self, input_data, filename_in_server: str = "dataframe_result.xlsx"):
1563
+ """
1564
+ 上传数据到内网 http://fs-cc.xin.com(带网络重试保障)
1565
+ :param input_data: 支持 3 种输入 →
1566
+ 1) 单个 DataFrame
1567
+ 2) 字典 {sheet名: df} → 自动生成多Sheet Excel
1568
+ 3) 本地Excel文件路径(str)
1569
+ :param filename_in_server: 服务器上显示的文件名
1570
+ :return: 下载链接(失败返回None)
1571
+ """
1572
+ import requests
1573
+ import pandas as pd
1574
+ import os
1575
+ import datetime
1576
+ from io import BytesIO
1577
+ from requests.adapters import HTTPAdapter
1578
+ from urllib3.util.retry import Retry
1579
+
1580
+ upload_url = "http://fs-cc.xin.com"
1581
+ self.logger.info(f"开始上传数据到内网服务器,服务器文件名:{filename_in_server}")
1582
+ print(f"📤 正在上传 → 服务器文件名:{filename_in_server}")
1583
+
1584
+ # ====================== 【核心:网络重试保障机制】 ======================
1585
+ def create_retry_session(retries=3):
1586
+ session = requests.Session()
1587
+ retry_strategy = Retry(
1588
+ total=retries,
1589
+ backoff_factor=1,
1590
+ status_forcelist=[500, 502, 503, 504],
1591
+ allowed_methods=["POST"]
1592
+ )
1593
+ adapter = HTTPAdapter(max_retries=retry_strategy)
1594
+ session.mount("http://", adapter)
1595
+ session.mount("https://", adapter)
1596
+ return session
1597
+
1598
+ # ======================================================================
1599
+
1600
+ try:
1601
+ # ==============================================
1602
+ # 【核心升级点】支持 单个DF / 多个DF(多Sheet)
1603
+ # ==============================================
1604
+ if isinstance(input_data, dict):
1605
+ # 字典 → 多Sheet Excel
1606
+ self.logger.info(f"输入类型为【多DataFrame字典】,共 {len(input_data)} 个Sheet")
1607
+ excel_buffer = BytesIO()
1608
+ with pd.ExcelWriter(excel_buffer, engine="openpyxl") as writer:
1609
+ for sheet_name, df in input_data.items():
1610
+ # 截取sheet名(Excel限制31字符)
1611
+ safe_sheet_name = sheet_name[:30]
1612
+ df.to_excel(writer, sheet_name=safe_sheet_name, index=False)
1613
+ excel_buffer.seek(0)
1614
+ file_obj = excel_buffer
1615
+ file_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
1616
+
1617
+ elif isinstance(input_data, pd.DataFrame):
1618
+ # 单个DF
1619
+ self.logger.info("输入类型为【单个DataFrame】")
1620
+ excel_buffer = BytesIO()
1621
+ with pd.ExcelWriter(excel_buffer, engine="openpyxl") as writer:
1622
+ input_data.to_excel(writer, index=False)
1623
+ excel_buffer.seek(0)
1624
+ file_obj = excel_buffer
1625
+ file_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
1626
+
1627
+ elif isinstance(input_data, str) and os.path.isfile(input_data):
1628
+ # 本地文件
1629
+ self.logger.info(f"输入类型为【本地文件】:{input_data}")
1630
+ file_obj = open(input_data, 'rb')
1631
+ if input_data.endswith('.xlsx'):
1632
+ file_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
1633
+ elif input_data.endswith('.xls'):
1634
+ file_type = "application/vnd.ms-excel"
1635
+ else:
1636
+ raise ValueError(f"仅支持xlsx/xls,不支持:{input_data}")
1637
+
1638
+ else:
1639
+ raise ValueError(f"不支持输入类型:{type(input_data)}")
1640
+
1641
+ # 上传
1642
+ session = create_retry_session(retries=3)
1643
+ files = {"file": (filename_in_server, file_obj, file_type)}
1644
+ response = session.post(upload_url, files=files, timeout=(10, 60))
1645
+
1646
+ # 关闭文件
1647
+ if isinstance(input_data, str):
1648
+ file_obj.close()
1649
+
1650
+ # 结果处理
1651
+ if response.status_code == 200:
1652
+ download_url = response.text.strip()
1653
+ self.logger.info(f"✅ 上传成功,链接:{download_url}")
1654
+ print("✅ 上传成功!")
1655
+ print("🔗 下载地址:", download_url)
1561
1656
 
1657
+ # ====================== 【核心:生成同名链接文件】 ======================
1658
+ file_base_name = os.path.splitext(filename_in_server)[0]
1659
+ link_file_name = f"{file_base_name}.log"
1660
+ link_path = os.path.join(os.path.dirname(self.main_log_file), link_file_name)
1661
+
1662
+ now_str = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
1663
+ # 🔥 这里增加了提示语
1664
+ file_content = f"{now_str} | {filename_in_server} | {download_url}\n请打开链接下载报表"
1665
+
1666
+ with open(link_path, 'a', encoding='utf-8') as f:
1667
+ f.write(file_content)
1668
+ # ======================================================================
1669
+
1670
+ self.logger.info(f"上传链接已保存到:{link_path}")
1671
+ return download_url
1672
+
1673
+ else:
1674
+ err = f"❌ 上传失败,状态码:{response.status_code}"
1675
+ self.logger.error(err)
1676
+ print(err)
1677
+ return None
1678
+
1679
+ except Exception as e:
1680
+ err_msg = f"❌ 上传异常:{str(e)}"
1681
+ self.logger.error(err_msg, exc_info=True)
1682
+ print(err_msg)
1683
+ return None
1562
1684
  # 使用示例
1563
1685
  if __name__ == "__main__":
1564
1686
  # 实例化 DataProcessingAndMessaging 类
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Functions_d
3
- Version: 1.28
3
+ Version: 1.30
4
4
  Summary: 包含数据处理、Hive交互、企业微信消息发送、Excel操作等功能的工具类库
5
5
  Author: DongYang
6
6
  Author-email: 649898871@qq.com
@@ -30,6 +30,7 @@ Requires-Dist: pillow>=8.4.0
30
30
  Requires-Dist: pypinyin>=0.48.0
31
31
  Requires-Dist: psutil>=5.8.0
32
32
  Requires-Dist: tenacity>=8.0.0
33
+ Requires-Dist: openpyxl>=3.0.0
33
34
 
34
35
  # 说明
35
36
  这是一个函数封装工具
@@ -14,3 +14,4 @@ pillow>=8.4.0
14
14
  pypinyin>=0.48.0
15
15
  psutil>=5.8.0
16
16
  tenacity>=8.0.0
17
+ openpyxl>=3.0.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Functions_d
3
- Version: 1.28
3
+ Version: 1.30
4
4
  Summary: 包含数据处理、Hive交互、企业微信消息发送、Excel操作等功能的工具类库
5
5
  Author: DongYang
6
6
  Author-email: 649898871@qq.com
@@ -30,6 +30,7 @@ Requires-Dist: pillow>=8.4.0
30
30
  Requires-Dist: pypinyin>=0.48.0
31
31
  Requires-Dist: psutil>=5.8.0
32
32
  Requires-Dist: tenacity>=8.0.0
33
+ Requires-Dist: openpyxl>=3.0.0
33
34
 
34
35
  # 说明
35
36
  这是一个函数封装工具
@@ -1,6 +1,6 @@
1
1
  [metadata]
2
2
  name = Functions_d
3
- version = 1.28
3
+ version = 1.30
4
4
  author = DongYang
5
5
  author_email = 649898871@qq.com
6
6
  description = 包含数据处理、Hive交互、企业微信消息发送、Excel操作等功能的工具类库
@@ -36,6 +36,7 @@ install_requires =
36
36
  pypinyin>=0.48.0
37
37
  psutil>=5.8.0
38
38
  tenacity>=8.0.0
39
+ openpyxl>=3.0.0
39
40
 
40
41
  [options.packages.find]
41
42
  where = .
File without changes
File without changes
File without changes