WxPython跨平台开发框架之表格数据导出到Excel并打开
在 Python 中使用 wxPython 导出实体类列表数据到 Excel,通常可以借助 openpyxl 或 pandas 库来实现。本篇随笔由浅入深,逐步介绍导出Excel文件的操作,然后结合跨平台项目的实现,根据抽象继承的方式,对不同业务模块的通用导出Excel文件功能,以及跨平台的打开处理方式的实现进行介绍。
以下是一个基本示例,展示如何将实体类的列表数据导出到 Excel 文件。
1、使用pandas 库导出Excel
import wx
import pandas as pd
# 假设这是你的实体类
class Person:
def __init__(self, name, age, email):
self.name = name
self.age = age
self.email = email
def to_dict(self):
return {"Name": self.name, "Age": self.age, "Email": self.email}
# 用一个 wxPython 窗口展示如何导出数据
class MyFrame(wx.Frame):
def __init__(self, parent, title):
super().__init__(parent, title=title, size=(300, 200))
self.panel = wx.Panel(self)
self.button = wx.Button(self.panel, label="导出到Excel", pos=(50, 50))
# 创建一些实体类数据
self.person_list = [
Person("Alice", 30, "alice@example.com"),
Person("Bob", 25, "bob@example.com"),
Person("Charlie", 35, "charlie@example.com")
]
self.Bind(wx.EVT_BUTTON, self.export_to_excel, self.button)
self.Show()
def export_to_excel(self, event):
# 将实体类列表转换为字典列表
data = [person.to_dict() for person in self.person_list]
# 使用 pandas 导出到 Excel
df = pd.DataFrame(data)
df.to_excel("exported_data.xlsx", index=False)
wx.MessageBox("导出成功!", "信息", wx.OK | wx.ICON_INFORMATION)
# 启动 wxPython 应用
app = wx.App(False)
frame = MyFrame(None, "导出实体类数据到 Excel")
app.MainLoop()
实体类 (Person):包含一些字段,如 name、age 和 email,并定义了 to_dict 方法,将实体对象转换为字典格式,以便更容易处理。
export_to_excel:这个方法将实体类列表转换为字典列表,使用 pandas 库将数据导出为 Excel 文件。
如果你需要更多的功能(如自定义 Excel 格式,单元格样式等),可以进一步扩展 openpyxl 或 xlsxwriter 来提供更复杂的导出选项。
2、使用 openpyxl 库导出Excel
要在 Excel 导出时为标题加粗并设置背景色,你可以使用 openpyxl 库,它提供了丰富的功能来设置单元格样式(如字体、背景色等)。
以下是一个更新的示例,演示如何在导出数据时,设置 Excel 标题行的加粗和背景色。
import wx
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill
# 假设这是你的实体类
class Person:
def __init__(self, name, age, email):
self.name = name
self.age = age
self.email = email
def to_dict(self):
return {"Name": self.name, "Age": self.age, "Email": self.email}
# 用一个 wxPython 窗口展示如何导出数据
class MyFrame(wx.Frame):
def __init__(self, parent, title):
super().__init__(parent, title=title, size=(300, 200))
self.panel = wx.Panel(self)
self.button = wx.Button(self.panel, label="导出到Excel", pos=(50, 50))
# 创建一些实体类数据
self.person_list = [
Person("Alice", 30, "alice@example.com"),
Person("Bob", 25, "bob@example.com"),
Person("Charlie", 35, "charlie@example.com")
]
self.Bind(wx.EVT_BUTTON, self.export_to_excel, self.button)
self.Show()
def export_to_excel(self, event):
# 将实体类列表转换为字典列表
data = [person.to_dict() for person in self.person_list]
# 创建 Excel 工作簿和工作表
wb = Workbook()
ws = wb.active
ws.title = "People Data"
# 设置标题行并加粗背景色
titles = ["Name", "Age", "Email"]
ws.append(titles)
# 设置标题样式:加粗和背景色
title_font = Font(bold=True)
title_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid") # 黄色背景
for cell in ws[1]:
cell.font = title_font
cell.fill = title_fill
# 填充数据
for person in data:
ws.append([person["Name"], person["Age"], person["Email"]])
# 保存到文件
wb.save("exported_data_with_styles.xlsx")
wx.MessageBox("导出成功!", "信息", wx.OK | wx.ICON_INFORMATION)
# 启动 wxPython 应用
app = wx.App(False)
frame = MyFrame(None, "导出实体类数据到 Excel")
app.MainLoop()
Excel 在 openpyxl 中可以设置自适应列宽或者指定具体的列宽,甚至可以设置框架(边框样式)。
虽然 openpyxl 本身并没有直接提供“自动调整列宽”的功能,但我们可以通过遍历列中的所有单元格来计算每列的最大宽度,然后动态调整列宽。
调整后的代码如下所示。
import wx
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Border, Side
# 假设这是你的实体类
class Person:
def __init__(self, name, age, email):
self.name = name
self.age = age
self.email = email
def to_dict(self):
return {"Name": self.name, "Age": self.age, "Email": self.email}
# 用一个 wxPython 窗口展示如何导出数据
class MyFrame(wx.Frame):
def __init__(self, parent, title):
super().__init__(parent, title=title, size=(300, 200))
self.panel = wx.Panel(self)
self.button = wx.Button(self.panel, label="导出到Excel", pos=(50, 50))
# 创建一些实体类数据
self.person_list = [
Person("Alice", 30, "alice@example.com"),
Person("Bob", 25, "bob@example.com"),
Person("Charlie", 35, "charlie@example.com")
]
self.Bind(wx.EVT_BUTTON, self.export_to_excel, self.button)
self.Show()
def export_to_excel(self, event):
# 将实体类列表转换为字典列表
data = [person.to_dict() for person in self.person_list]
# 创建 Excel 工作簿和工作表
wb = Workbook()
ws = wb.active
ws.title = "People Data"
# 设置标题行并加粗背景色
titles = ["Name", "Age", "Email"]
ws.append(titles)
# 设置标题样式:加粗和背景色
title_font = Font(bold=True)
title_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid") # 黄色背景
for cell in ws[1]:
cell.font = title_font
cell.fill = title_fill
# 填充数据
for person in data:
ws.append([person["Name"], person["Age"], person["Email"]])
# 设置列宽(手动指定或根据内容自适应)
# 自动调整列宽
for col in ws.columns:
max_length = 0
column = col[0].column_letter # 获取列字母
for cell in col:
try:
if len(str(cell.value)) > max_length:
max_length = len(cell.value)
except:
pass
adjusted_width = (max_length + 2)
ws.column_dimensions[column].width = adjusted_width
# 设置框架(边框)
border = Border(
left=Side(border_style="thin"),
right=Side(border_style="thin"),
top=Side(border_style="thin"),
bottom=Side(border_style="thin")
)
for row in ws.iter_rows():
for cell in row:
cell.border = border
# 保存到文件
wb.save("exported_data_with_styles_and_borders.xlsx")
wx.MessageBox("导出成功!", "信息", wx.OK | wx.ICON_INFORMATION)
# 启动 wxPython 应用
app = wx.App(False)
frame = MyFrame(None, "导出实体类数据到 Excel")
app.MainLoop()
点击“导出到Excel”按钮后,程序将生成一个包含:
- 自动调整列宽的 Excel 文件;
- 每个单元格的边框;
- 标题行加粗并带黄色背景色的 Excel 文件。
为了实现一个通用的导出函数,根据 display_columns 和 column_mapping 设置导出的字段,并映射标题名称,你可以设计一个灵活的函数,接收这些参数并根据需要导出数据到 Excel。
display_columns:一个字符串,指定需要导出的字段(如name,age,email)。column_mapping:一个字典,指定字段到显示名称的映射。list:包含实体类数据的列表,每个实体类需要提供to_dict()方法,将数据转换为字典格式。filename:保存的文件名。
import wx
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Border, Side
def export_to_excel(list_data, display_columns, column_mapping, filename):
# 解析 display_columns 为列表
display_columns = display_columns.split(',')
# 获取映射后的标题
headers = [column_mapping.get(col, col) for col in display_columns]
# 创建 Excel 工作簿和工作表
wb = Workbook()
ws = wb.active
ws.title = "Data"
# 设置标题行并加粗背景色
ws.append(headers)
title_font = Font(bold=True)
title_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid") # 黄色背景
for cell in ws[1]:
cell.font = title_font
cell.fill = title_fill
# 填充数据
for data_item in list_data:
row = [data_item.get(col) for col in display_columns]
ws.append(row)
# 设置列宽(自动调整)
for col in ws.columns:
max_length = 0
column = col[0].column_letter # 获取列字母
for cell in col:
try:
if len(str(cell.value)) > max_length:
max_length = len(cell.value)
except:
pass
adjusted_width = (max_length + 2)
ws.column_dimensions[column].width = adjusted_width
# 设置框架(边框)
border = Border(
left=Side(border_style="thin"),
right=Side(border_style="thin"),
top=Side(border_style="thin"),
bottom=Side(border_style="thin")
)
for row in ws.iter_rows():
for cell in row:
cell.border = border
# 保存到文件
wb.save(filename)
return f"导出成功!文件已保存为 {filename}"
调用代码如下所示
def export(self, event):
display_columns = "name,age,email" # 需要导出的字段
column_mapping = {
"age": "年龄",
"email": "电子邮箱",
"name": "显示名称"
}
filename = "exported_data.xlsx" # 保存的文件名
result = export_to_excel(
[person.to_dict() for person in self.person_list],
display_columns,
column_mapping,
filename
)
wx.MessageBox(result, "信息", wx.OK | wx.ICON_INFORMATION)
你只需调用 export_to_excel 函数并传递数据、要导出的字段(display_columns)、字段映射(column_mapping)和保存的文件名(filename)。它会生成一个 Excel 文件,并按要求设置样式。
在 openpyxl 中,自动调整列宽是通过检查列中内容的最大长度来实现的。如果你发现某一列(例如“年龄”列)的宽度过窄,可能是因为该列中的数据(例如数字)被视为较短的字符串,导致列宽过小。
为了解决这个问题,您可以通过设置列宽时为数字列提供额外的宽度补偿,或者通过在计算列宽时增加一个常量来确保列宽更合适。
# 设置列宽(自动调整)
for col in ws.columns:
max_length = 0
column = col[0].column_letter # 获取列字母
for cell in col:
try:
if cell.value:
cell_value = str(cell.value)
# 增加补偿宽度:如果是数字列,增加额外宽度
if isinstance(cell.value, (int, float)):
max_length = max(max_length, len(cell_value) + 2) # 数字列增加 2 的宽度
else:
max_length = max(max_length, len(cell_value))
except:
pass
adjusted_width = (max_length + 2) # 留出一些额外的空间
ws.column_dimensions[column].width = max(adjusted_width, 12) # 设置最小宽度为 12
- 列宽补偿:对于数字列(如
age列),在计算最大长度时增加一个+2的补偿。这将确保数字列的列宽足够显示数字值。 - 最小列宽:为了避免列过窄,我设置了
max(adjusted_width, 12),确保列宽至少为 12。如果计算出的列宽小于 12,将强制设置为 12。 - 自动列宽:自动计算每列的最大长度,并为每列分配合适的宽度。
如果我们需要再实际业务中导出数据,如对于用户信息,实体类为UserDto,那么我们需要在导出数据之前,将 UserDto 类型的对象转换为字典格式。
在每个 DTO 对象中,添加一个 to_dict 方法,用于将对象的属性转换为字典。to_dict 方法可以返回一个字典,其中每个键是类属性的名称,每个值是对应的属性值。
不过我的跨平台框架中的UserDto对象是与Pydantic模型的,因此它可以通过函数 model_dump 进行通用处理为字典对象。
使用 model_dump 方法可以很方便地将 Python 类对象(特别是 Pydantic 模型或者具备 model_dump 方法的类)转换为字典。如果你正在使用 Pydantic 或者使用了某些自定义实现了 model_dump 方法的类,可以直接调用该方法来完成对象到字典的转换。
假设你有一个 UserDto 类,它是一个 Pydantic 模型:
from pydantic import BaseModel
class UserDto(BaseModel):
name: str
age: int
email: str
# 创建一个 UserDto 实例
user = UserDto(name="Alice", age=30, email="alice@example.com")
# 使用 model_dump 将对象转换为字典
user_dict = user.model_dump()
print(user_dict)
在这个例子中,model_dump 会自动将 Pydantic 模型实例转换为字典,所有字段(即类的属性)都会成为字典的键,属性值成为字典的值。
如果你有嵌套的 Pydantic 模型,model_dump 会自动递归地将嵌套模型转换为字典。如果你的项目中使用了 Pydantic,这种方法将非常简便高效。
3、在项目列表基类中增加导出功能
通过上面的封装测试,我们可以把导出Excel的功能做的很不错了,因此把它整合到列表基类里面,通过基类界面中增加一个导出按钮即可实现所有业务模块的数据导出,不用每个页面都实现,简化了操作。

添加按钮采用通用辅助函数参加按钮及图标,并增加导出的处理函数,如下代码所示。
btn_export = ControlUtil.create_button(
pane, "导出Excel", "xls", handler=self.OnExport, is_async=True
)
OnExport函数的实现如下所示。
async def OnExport(self, event: wx.Event) -> None:
"""导出数据"""
# 检查数据是否是一个 Pydantic 实体
export_list = []
for item in self.data:
if hasattr(item, "model_dump"):
export_item = item.model_dump()
export_list.append(export_item)
else:
export_list.append(item)
# print(export_list)
filename = FileDialogUtil.save_excel(self)
if not filename:
return
result = ExcelUtil.export_to_excel(
export_list, self.display_columns, self.column_mapping, filename
)
if result:
if (
MessageUtil.show_confirm(self, "导出成功,是否打开文件?", "导出成功")
== wx.ID_YES
):
ExcelUtil.open_file(filename)
else:
MessageUtil.show_error(self, "导出失败")
在MacOS上弹出导出提示,如下所示。

确认后提示,是否打开文件如下。

导出的文件打开后,可以看到效果如下所示

4、文件的打开方式和跨平台打开实现
注意,不同平台打开文件进行查看,操作方式有所不同。
如果你想用默认应用(如 Excel 或 Numbers)直接打开 .xls 文件,你可以通过 Python 的 subprocess 模块调用 macOS 上的应用程序来打开文件。
在 macOS 中,open 命令可以用来打开任何文件。如果你希望在默认的应用程序中打开 .xls 文件(例如 Excel 或 Numbers),可以使用如下方法:
import subprocess
# 打开 .xls 文件
subprocess.run(["open", "your_file.xls"])
macOS 支持通过 os 模块调用系统命令来打开文件。可以通过 os.system() 或 subprocess.run() 来调用 open 命令,在 macOS 上打开文件。
import os
# 打开 .xls 文件
os.system("open your_file.xls")
通过 os.system("open your_file.xls") 或 subprocess.run(["open", "your_file.xls"]),你可以在 macOS 上使用默认的应用程序(如 Excel 或 Numbers)打开 .xls 文件。这些方法非常简单且不需要依赖外部库。
os.startfile() 是 Windows 系统中的一个特定方法,用于打开文件并在关联的默认应用程序中显示它。然而,os.startfile() 在 macOS 和 Linux 系统中不可用。因此,在 macOS 上使用该方法会导致错误。
为了使代码在不同平台上都能工作,您可以编写一个条件判断,区分操作系统并使用合适的命令来打开文件。
import os
import subprocess
import platform
def open_file(file_path):
system = platform.system()
if system == "Darwin": # macOS
subprocess.run(["open", file_path])
elif system == "Windows":
os.startfile(file_path)
elif system == "Linux":
subprocess.run(["xdg-open", file_path])
else:
raise NotImplementedError(f"Unsupported operating system: {system}")
# 示例调用
open_file("your_file.xls")
说明:
- macOS (Darwin):使用
open命令。 - Windows:使用
os.startfile(),这是 Windows 特有的方法。 - Linux:使用
xdg-open命令,适用于大多数 Linux 发行版。
对于跨平台执行系统命令,推荐使用 subprocess 模块,它提供了更强大的功能,并且更灵活和安全。subprocess.run() 方法是一个更通用的替代方案。
因此结合通用的导出Excel和打开文件,就可以实现Excel文件的导出打开操作了,各个业务列表模块度是基于列表基础页面的,因此自动具有导出的功能,当然,我们也可以根据一些条件进行判断是否使用导出按钮即可。
列表界面继承基类,从而可以大幅度的利用相应的规则和实现。

如对于两个例子窗体:系统类型定义,客户信息,其中传如对应的DTO信息和参数即可。


子类继承基类列表页面,并传入对应的参数即可具体化相关的业务功能了。

以上就是根据抽象继承的方式,对不同业务模块的通用导出Excel文件功能,以及跨平台的打开处理方式的实现。
WxPython跨平台开发框架之表格数据导出到Excel并打开的更多相关文章
- Vue+element UI实现表格数据导出Excel组件
介绍 这是一个可以将页面中的表格数据导出为Excel文件的功能组件,该组件一般与表格一起使用,将表格数据传给组件,然后通过点击组件按钮可将表格中的数据导出成Excel文件. 使用方法 由于封装该组件内 ...
- 将页面中表格数据导出excel格式的文件(vue)
近期由于项目需要,需要将页面中的表格数据导出excel格式的文件,折腾了许久,在网上各种百度,虽然资料不少,但是大都不全,踩了许多坑,总算是皇天不负有心人,最后圆满解决了. 1.安装相关依赖(npm安 ...
- 前端 vue表格数据导出Excel 文件实现
实现思路 使用json2csv将后台json数据转化为csv格式数据 采用创建Blob(二进制大对象)的方式来存放缓存数据: 生成下载链接: 创建一个a标签,设置href和download属性 触发a ...
- 学习笔记 DataGridView数据导出为Excel
DataGridView数据导出为Excel 怎样把WinForm下的“DGV”里的绑定数据库后的数据导出到Excel中. 比如:在窗体里有个一“DGV”,DataGridView1,绑定了数据源 ...
- asp.net将数据导出到excel
本次应用datatable导出,若用gridview(假设gridview设为了分页显示)会出现只导出当前页的情况. protected void btnPrn_Click(object sender ...
- 机房收费系统——在VB中将MSHFlexGrid控件中的数据导出到Excel
机房收费系统中,好多查询的窗体都包含同一个功能:将数据库中查询到的数据显示在MSHFlexGrid控件中,然后再把MSHFlexGrid控件中的数据导出到Excel表格中. 虽然之前做过学生信息管理系 ...
- 将Datagridview中的数据导出至Excel中
首先添加一个模块ImportToExcel,并添加引用 然后导入命名空间: Imports Microsoft.Office.Interop Imports System.Da ...
- C#大量数据导出到Excel(转)
工作过程中经常会用到将数据导出到Excel中,一般情况下需要导出的数据都是几百几千条或者上万条,这都没有什么问题,但有时候会遇到特殊的需求,客户要求把几十万条甚至上百万条的数据导出到Excel中,这就 ...
- Java利用Apache POI将数据库数据导出为excel
将数据库中的数据导出为excel文件,供其他人查看 public class POITest { public static void main(String[] args) { POITest te ...
- Magic xpa 3.x很容易将数据导出到Excel中
Magic xpa 3.x很方便的将表中数据导出到Excel文件中,还可以自动将表中数据生成各种图表. 通过使用自带的打印数据内部事即可实现. 1.首先将打印数据任务属性设置为“是”. 2.可使用主程 ...
随机推荐
- migration to end point routing
花了几个小时,记入一下吧. 1. odata https://devblogs.microsoft.com/odata/enabling-endpoint-routing-in-odata/ 找着弄就 ...
- Figma 学习笔记 – Component
参考 Guide to Components in Figma Figma Tutorial: Components - The Basics (Youtube) 定义与用途 Figma 的 Comp ...
- React的useId,现在Vue3.5终于也有了!
前言 React在很早之前的版本中加了useId,用于生成唯一ID.在Vue3.5版本中,终于也有了期待已久的useId.这篇文章来带你搞清楚useId有哪些应用场景,以及他是如何实现的. 关注公众号 ...
- 【赵渝强老师】MongoDB管理用户的认证机制
一.MongoDB用户认证机制简介 为了认证客户端,你必须要添加一个对应的用户到MongoDB.基本的步骤分为以下几步: 用户管理接口:db.createUser()方法可以创建一个用户,添加完成后可 ...
- 高通ramdump
背景 高通平台下提供了一个工具,专门用来抓取内核死机以后的dump信息.如果只是非系统层面的crash(例如底层应用,安卓程序),则不能抓取dump信息. 在阅读一些文档的时候知道有这个功能,但是一直 ...
- qemu的使用
一.QEMU的运行模式 直接摘抄自己<揭秘家用路由器0day漏洞挖掘技术>,网上查了一下也没有找到令人满意的QEMU的使用说明,就采用这本书上的介绍.如果后期能够找到比较满意的QEMU的使 ...
- 《你不知道的JavaScript》读书笔记(一):JS是如何查找变量的
这本书之前囫囵地看了一遍,确实点明了很多以前不清不楚的点,但是仅仅看一遍是没什么用的,最近面试遇到不少原理相关的题感觉答得不理想,回头看下其实以前都理解过,但是没有记下来,正好结合实际的问题来再学习一 ...
- rabbitmq 新下载链接🔗
Linux下安装RabbitMQ需要依赖socat和erlang插件环境 1 插件下载 1.1 RabbitMQ下载 下载地址一:https://www.rabbitmq.com/download. ...
- SqlUtils 使用
一.前言 随着 Solon 3.0 版本发布,新添加的 SqlUtils 接口,用于操作数据库,SqlUtils 是对 Jdbc 原始接口的封装.适合 SQL 极少或较复杂,或者 ORM 不适合的场景 ...
- 在 KubeSphere 上快速安装和使用 KDP 云原生数据平台
作者简介:金津,智领云高级研发经理,华中科技大学计算机系硕士.加入智领云 8 余年,长期从事云原生.容器化编排领域研发工作,主导了智领云自研的 BDOS 应用云平台.云原生大数据平台 KDP 等产品的 ...