在 Python 中使用 wxPython 导出实体类列表数据到 Excel,通常可以借助 openpyxlpandas 库来实现。本篇随笔由浅入深,逐步介绍导出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):包含一些字段,如 nameageemail,并定义了 to_dict 方法,将实体对象转换为字典格式,以便更容易处理。

export_to_excel:这个方法将实体类列表转换为字典列表,使用 pandas 库将数据导出为 Excel 文件。

如果你需要更多的功能(如自定义 Excel 格式,单元格样式等),可以进一步扩展 openpyxlxlsxwriter 来提供更复杂的导出选项。

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_columnscolumn_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()macOSLinux 系统中不可用。因此,在 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并打开的更多相关文章

  1. Vue+element UI实现表格数据导出Excel组件

    介绍 这是一个可以将页面中的表格数据导出为Excel文件的功能组件,该组件一般与表格一起使用,将表格数据传给组件,然后通过点击组件按钮可将表格中的数据导出成Excel文件. 使用方法 由于封装该组件内 ...

  2. 将页面中表格数据导出excel格式的文件(vue)

    近期由于项目需要,需要将页面中的表格数据导出excel格式的文件,折腾了许久,在网上各种百度,虽然资料不少,但是大都不全,踩了许多坑,总算是皇天不负有心人,最后圆满解决了. 1.安装相关依赖(npm安 ...

  3. 前端 vue表格数据导出Excel 文件实现

    实现思路 使用json2csv将后台json数据转化为csv格式数据 采用创建Blob(二进制大对象)的方式来存放缓存数据: 生成下载链接: 创建一个a标签,设置href和download属性 触发a ...

  4. 学习笔记 DataGridView数据导出为Excel

    DataGridView数据导出为Excel   怎样把WinForm下的“DGV”里的绑定数据库后的数据导出到Excel中. 比如:在窗体里有个一“DGV”,DataGridView1,绑定了数据源 ...

  5. asp.net将数据导出到excel

    本次应用datatable导出,若用gridview(假设gridview设为了分页显示)会出现只导出当前页的情况. protected void btnPrn_Click(object sender ...

  6. 机房收费系统——在VB中将MSHFlexGrid控件中的数据导出到Excel

    机房收费系统中,好多查询的窗体都包含同一个功能:将数据库中查询到的数据显示在MSHFlexGrid控件中,然后再把MSHFlexGrid控件中的数据导出到Excel表格中. 虽然之前做过学生信息管理系 ...

  7. 将Datagridview中的数据导出至Excel中

        首先添加一个模块ImportToExcel,并添加引用         然后导入命名空间: Imports Microsoft.Office.Interop Imports System.Da ...

  8. C#大量数据导出到Excel(转)

    工作过程中经常会用到将数据导出到Excel中,一般情况下需要导出的数据都是几百几千条或者上万条,这都没有什么问题,但有时候会遇到特殊的需求,客户要求把几十万条甚至上百万条的数据导出到Excel中,这就 ...

  9. Java利用Apache POI将数据库数据导出为excel

    将数据库中的数据导出为excel文件,供其他人查看 public class POITest { public static void main(String[] args) { POITest te ...

  10. Magic xpa 3.x很容易将数据导出到Excel中

    Magic xpa 3.x很方便的将表中数据导出到Excel文件中,还可以自动将表中数据生成各种图表. 通过使用自带的打印数据内部事即可实现. 1.首先将打印数据任务属性设置为“是”. 2.可使用主程 ...

随机推荐

  1. mongo集群同步数据异常,手动同步节点副本数据

    转载请注明出处: 数据同步方案 当副本集节点的复制进程落后太多,以至于主节点覆盖了该节点尚未复制的 oplog 条目时,副本集节点就会变为"陈旧".节点跟不上,就会变得" ...

  2. SpringBoot注解大全(详细)

    1. @ActiveProfiles 用来声明活动的profile–@ActiveProfiles("prod"(这个prod定义在配置类中)) @RunWith(SpringRu ...

  3. 暑假集训CSP提高模拟 16

    \[暑假集训CSP提高模拟 \lim_{x\rightarrow\infty}\frac{8f_{x}}{f_{x+1}}\times(\sqrt{5}+1),\ \forall f_{x}=f_{x ...

  4. 如何更改Wordpress语言为中文

    在使用WordPress的时候,一般安装默认语言是英文,可以在后台设置里面直接修改站点语言为简体中文,当后台没有语言选项框的这一栏,如下图所示,该怎么办呢? 这个时候我们可以找到文件wp-config ...

  5. springmvc参数传递不给参数值默认值设置方法

    @RequestMapping("hello") public voiid test001(@RequestParam(defaultValue = "11") ...

  6. 【墨天轮专访第四期】华为云GaussDB苏光牛:发挥生态优势,培养应用型DBA

    导读: 随着5G互联网时代的来临,各行各业对于数据库的依赖程度也在逐步提高.由于国内在数据库行业的发展起步较晚,数据库的市场份额长期被Oracle,微软等美国公司所控制.但是伴随着国内IT技术栈的不断 ...

  7. 如何理解 .Net 中的 委托

    // 委托 // 一种方法的声明和定义,也就是方法的占位符 // 一般使用在 参数 和 属性中 int Add(int a,int b) { return a + b; } // 定义委托的三种方法 ...

  8. C#扩展方法 Where Any Count Signal SignalOrDefault First 等方法的使用

    using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using Syst ...

  9. 19 Transformer 解码器的两个为什么(为什么做掩码、为什么用编码器-解码器注意力)

    博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...

  10. R语言经典统计分析

    经典统计分析包括了许多常用的统计方法和技术,用于数据的描述.推断和建模.本节将介绍经典统计分析方法(包括t检验.方差分析.卡方检验.线性回归)在R语言中的实现. 5.1.1  t检验 样本均值(sam ...