当你需要将Excel文件转换为PDF时,可以使用Python编程语言和一些流行的库来实现这个任务。在本篇博客中,我将介绍如何使用wxPython、pandas和PyMuPDF库创建一个简单易用的图形用户界面(GUI)工具来完成这项工作。
C:\pythoncode\new\excelexportpdf.py
准备工作
在开始之前,请确保你已经安装了Python以及以下所需的库:
- wxPython:用于创建GUI界面。
- pandas:用于读取Excel文件数据。
- PyMuPDF:用于将数据导出为PDF文件。
你可以使用pip工具来安装这些库:
pip install wxPython pandas PyMuPDF
创建GUI界面
我们将使用wxPython库来构建用户界面。首先,导入所需的库:
import wx
import pandas as pd
import fitz
接下来,我们将创建一个名为ExcelToPDFFrame
的类,继承自wx.Frame
类。这个类将代表我们的主窗口:
class ExcelToPDFFrame(wx.Frame):
def __init__(self, parent, title):
super(ExcelToPDFFrame, self).__init__(parent, title=title, size=(400, 200))
在__init__
方法中,我们设置了窗口的标题和大小。接下来,我们创建了窗口中的各个元素,如文件选择器、下拉框和转换按钮:
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
self.file_picker = wx.FilePickerCtrl(panel, style=wx.FLP_OPEN)
vbox.Add(self.file_picker, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)
self.sheet_picker = wx.ComboBox(panel)
vbox.Add(self.sheet_picker, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)
self.output_picker = wx.FilePickerCtrl(panel, style=wx.FLP_SAVE | wx.FLP_OVERWRITE_PROMPT)
vbox.Add(self.output_picker, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)
convert_btn = wx.Button(panel, label='Convert')
vbox.Add(convert_btn, proportion=0, flag=wx.ALIGN_CENTER | wx.ALL, border=10)
panel.SetSizer(vbox)
我们使用wx.FilePickerCtrl
来创建一个文件选择器,用于选择Excel文件。使用wx.ComboBox
创建一个下拉框,用于显示Excel文件中的表格名称。然后,我们使用wx.FilePickerCtrl
创建一个文件选择器,用于指定转换后的PDF文件的保存路径。最后,我们创建了一个按钮用于触发转换操作。
实现转换操作
接下来,我们需要实现转换操作的逻辑。我们将为文件选择器的EVT_FILEPICKER_CHANGED
事件和转换按钮的EVT_BUTTON
事件绑定相应的处理方法。
首先,我们实现on_file_picker_changed
方法,当用户选择Excel文件时,它将被调用。该方法将获取所选文件的路径,并使用pd.ExcelFile
读取文件中的表格名称,然后将它们填充到下拉框中:
def on_file_picker_changed(self, event):
filepath = self.file_picker.GetPath()
sheets = self.get_excel_sheets(filepath)
self.sheet_picker.Clear()
self.sheet_picker.AppendItems(sheets)
if len(sheets) > 0:
self.sheet_picker.SetSelection(0)
然后,我们实现on_convert_btn_click
方法,当用户点击转换按钮时,它将被调用。该方法将获取所选的Excel文件路径、所选的表格名称和输出文件路径。如果这些信息都提供了,它将使用pd.read_excel
读取Excel数据,并调用export_to_pdf
方法将数据导出为PDF文件:
def on_convert_btn_click(self, event):
excel_file = self.file_picker.GetPath()
sheet_name = self.sheet_picker.GetStringSelection()
output_file = self.output_picker.GetPath()
if excel_file and sheet_name and output_file:
excel_data = self.read_excel(excel_file, sheet_name)
if excel_data is not None:
self.export_to_pdf(excel_data, output_file)
wx.MessageBox('Conversion completed成功!')
def get_excel_sheets(self, file_path):
excel_file = pd.ExcelFile(file_path)
return excel_file.sheet_names
def read_excel(self, file_path, sheet_name):
try:
excel_data = pd.read_excel(file_path, sheet_name=sheet_name)
return excel_data
except Exception as e:
wx.MessageBox(f'Error reading Excel file: {str(e)}', 'Error', wx.OK | wx.ICON_ERROR)
return None
def export_to_pdf(self, excel_data, output_file):
doc = fitz.open()
page = doc.new_page()
table = fitz.Table(page)
table.auto_table(excel_data.values.tolist(), excel_data.columns.tolist())
table.draw_on_page(page, (20, 20))
doc.save(output_file)
doc.close()
上述代码中,get_excel_sheets
方法获取Excel文件中的表格名称,read_excel
方法读取指定表格的数据,export_to_pdf
方法将数据导出为PDF文件。我们使用PyMuPDF库创建一个新的PDF文档,然后创建一个新的页面,在页面上绘制一个表格,并将数据填充到表格中。最后,我们保存PDF文档并关闭它。
运行应用程序
最后,我们需要创建一个wx.App
实例,并创建并显示ExcelToPDFFrame
实例。然后,调用app.MainLoop()
进入主事件循环,等待用户交互:
if __name__ == '__main__':
app = wx.App()
frame = ExcelToPDFFrame(None, 'Excel to PDF Converter')
frame.Show()
app.MainLoop()
现在,我们已经完成了这个简单的Excel转PDF的GUI工具。你可以将它保存为一个Python脚本并运行它。当你打开GUI界面时,选择要转换的Excel文件、表格名称和输出PDF文件的路径,然后点击转换按钮即可完成转换操作。
全部代码
import wx
import pandas as pd
import fitz
class ExcelToPDFFrame(wx.Frame):
def __init__(self, parent, title):
super(ExcelToPDFFrame, self).__init__(parent, title=title, size=(400, 200))
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
self.file_picker = wx.FilePickerCtrl(panel, style=wx.FLP_OPEN)
vbox.Add(self.file_picker, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)
self.sheet_picker = wx.ComboBox(panel)
vbox.Add(self.sheet_picker, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)
self.output_picker = wx.FilePickerCtrl(panel, style=wx.FLP_SAVE | wx.FLP_OVERWRITE_PROMPT)
vbox.Add(self.output_picker, proportion=0, flag=wx.EXPAND | wx.ALL, border=10)
convert_btn = wx.Button(panel, label='Convert')
vbox.Add(convert_btn, proportion=0, flag=wx.ALIGN_CENTER | wx.ALL, border=10)
panel.SetSizer(vbox)
self.file_picker.Bind(wx.EVT_FILEPICKER_CHANGED, self.on_file_picker_changed)
convert_btn.Bind(wx.EVT_BUTTON, self.on_convert_btn_click)
def on_file_picker_changed(self, event):
filepath = self.file_picker.GetPath()
sheets = self.get_excel_sheets(filepath)
self.sheet_picker.Clear()
self.sheet_picker.AppendItems(sheets)
if len(sheets) > 0:
self.sheet_picker.SetSelection(0)
def on_convert_btn_click(self, event):
excel_file = self.file_picker.GetPath()
sheet_name = self.sheet_picker.GetStringSelection()
output_file = self.output_picker.GetPath()
if excel_file and sheet_name and output_file:
excel_data = self.read_excel(excel_file, sheet_name)
if excel_data is not None:
self.export_to_pdf(excel_data, output_file)
wx.MessageBox('Conversion completed successfully!', 'Success')
else:
wx.MessageBox('Failed to read Excel data. Please check the file and sheet name.', 'Error')
else:
wx.MessageBox('Please select an Excel file, sheet, and specify an output file path.', 'Error')
def get_excel_sheets(self, file_path):
sheets = []
try:
excel_data = pd.ExcelFile(file_path)
sheets = excel_data.sheet_names
except Exception as e:
print(str(e))
return sheets
def read_excel(self, file_path, sheet_name):
excel_data = None
try:
excel_data = pd.read_excel(file_path, sheet_name=sheet_name)
except Exception as e:
print(str(e))
return excel_data
def export_to_pdf(self, excel_data, output_file_path):
doc = fitz.open()
page = doc.new_page()
table_width = 400 # 设置表格宽度
table_height = excel_data.shape[0] * 25 + 25 # 设置表格高度
# 绘制表格边框
rect = fitz.Rect(50, 50, 50 + table_width, 50 + table_height)
page.draw_rect(rect)
# 设置表头样式
header_font = 'Helvetica'
# header_font_path = "/Noto_Sans_SC/static/NotoSansSC-Black.ttf" # 替换为您自己的字体文件路径
# header_font = fitz.Font(header_font_path)
# header_font = 'Noto Sans SC'
# header_font = 'SimSun'
# header_font = 'SimHei'
# header_font = 'Microsoft YaHei'
# header_font = 'LiSu'
# header_font = 'YouYuan'
# header_font = 'STSong'
# header_font = 'STHeiti'
# header_font = 'STKaiti'
# header_font = 'STFangsong'
# header_font = 'STZhongsong'
# header_font = 'STHupo'
header_fontsize = 12
header_color = (0, 0, 0)
header_bgcolor = (0.8, 0.8, 0.8)
# 绘制表头
for col_idx, column in enumerate(excel_data.columns):
header_rect = fitz.Rect(50 + col_idx * 100, 50, 50 + (col_idx + 1) * 100, 75)
page.draw_rect(header_rect, fill=header_bgcolor)
page.insert_textbox(header_rect, column, fontname=header_font, fontsize=header_fontsize, color=header_color, align=1)
# 设置单元格样式
# cell_font = "/Noto_Sans_SC/static/NotoSansSC-Black.ttf" # 替换为您自己的字体文件路径
# cell_font = fitz.Font(header_font_path)
# cell_font = 'Noto Sans SC'
cell_font = 'Helvetica'
# cell_font= 'SimSun'
# cell_font= 'SimHei'
# cell_font= 'Microsoft YaHei'
# cell_font= 'LiSu'
# cell_font= 'YouYuan'
# cell_font= 'STSong'
# cell_font= 'STHeiti'
# cell_font= 'STKaiti'
# cell_font= 'STFangsong'
# cell_font= 'STZhongsong'
# cell_font= 'STHupo'
cell_fontsize = 10
cell_color = (0, 0, 0)
# 绘制单元格内容
for row_idx, row in enumerate(excel_data.itertuples(index=False), start=1):
for col_idx, cell_value in enumerate(row, start=0):
cell_rect = fitz.Rect(50 + col_idx * 100, 75 + row_idx * 25, 50 + (col_idx + 1) * 100, 75 + (row_idx + 1) * 25)
# cell_rect = fitz.Rect(50 + col_idx * 100, 50 + row_idx * 75, 50 + (row_idx + 1) * 25)
page.insert_textbox(cell_rect, str(cell_value), fontname=cell_font, fontsize=cell_fontsize, color=cell_color, align=1)
doc.save(output_file_path)
doc.close()
app = wx.App()
frame = ExcelToPDFFrame(None, 'Excel to PDF Converter')
frame.Show()
app.MainLoop()
总结
在本篇博客中,我们使用wxPython、pandas和PyMuPDF库创建了一个Excel转PDF的GUI工具。通过这个工具,我们可以方便地选择Excel文件、表格和输出路径,将Excel数据转换为PDF文件。这个工具可以帮助我们在处理Excel数据时更加高效和方便,同时也展示了如何使用Python编程语言和相关库来实现这个任务。希望本篇博客能对你有所帮助!