从电子表格到纸张:Excel转PDF的神奇变身之旅!

news2024/12/23 18:49:50

当你需要将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编程语言和相关库来实现这个任务。希望本篇博客能对你有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/910092.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SCCB与IIC的异同及FPGA实现的注意事项

文章目录 前言一、信号线二、SCCB数据传输格式三、SCCB写(与IIC完全一致)四、SCCB读五、SCCB和IIC的区别 前言 IIC接口有比较广泛的应用,而SCCB(Serial Camera Control Bus,串行摄像头控制总线)是由OV&…

发现一款免费WEB在线使用的AI对话+绘画

这是一个优秀的golang开发作者 免费开放给大家使用的 简单上手 注册就能使用 多个AI角色多模型自由选择 下面是使用效果 链接地址在文末链接地址:目前免费体验

基于51单片机无线温度报警控制器 NRF24L01 多路温度报警系统设计

一、系统方案 1、本设计默认采用STC89C52单片机,如需更换单片机请联系客服。 2、接收板LCD1602液晶实时显示当前检测的2点温度值以及对应的上下限报警值。发射板由DS18B20采集温度值,通过无线模块NRF24L01传给接收板。 3、按键可以设置温度上下限值&…

硬编码基础三(变长指令的查询方式)

硬编码基础三(变长指令的查询方式) intel指令的格式可以看作如下形式: 前缀操作码modrmsib偏移立即数 其中操作码决定了是否存在moderm modrm中的rm位决定了是否存在sib 这边举个例子, 在intel白皮书中的A附录中的A.3章节有一…

HCIP---企业网三层架构实验

实验要求 实验拓扑及IP规划 实验步骤 1. Eth-Trunk通道(将多个接口逻辑的整合成一个接口,实现带宽叠加的作用) SW1和SW2起eth-trunk,并划入接口 [sw1]interface Eth-Trunk 0 [sw1-Eth-Trunk0]int g0/0/3 [sw1-GigabitEthernet0…

第5天----单词替换(C++replace()函数)

当一句话中出现错误的单词时&#xff0c;你是否想快速将它替换为你想要的&#xff0c;接下来的这篇文章&#xff0c;将带你了解什么是单词替换。 一、基本知识&#xff1a; 1. string::replace()函数 C <string>库中的replace()函数是用于替换字符串中的特定字符或子字…

微信小程序canvas type=2d生成海报保存到相册、文字换行溢出显示...、文字删除线、分享面板

做个简单的生成二维码海报分享&#xff0c;我做的时候也找简单的方法看能不能实现页面直接截图那种生成图片&#xff0c;原生小程序不支持&#xff0c;不多介绍下面有全部代码有注释、参数自行替换运行看看&#xff0c;有问题可以咨询我&#xff0c;我写的已经上线 效果如图&a…

CTFhub-sql-整数注入

判断存在 sqli 注入 1 1 and 11 1 and 12 因为 11 为真&#xff0c;12 为假&#xff0c;且 11 与 1 显示的数据一样&#xff0c;那么就存在 sqli 注入 查询该数据表的字段数量 一、 2 3 1,2成功带出数据&#xff0c;3没有数据&#xff0c;所以有两个字段 二、 1 order by …

数据结构---串(赋值,求子串,比较,定位)

目录 一.初始化 顺序表中串的存储 串的链式存储 二.赋值操作&#xff1a;将str赋值给S 链式表 顺序表 三.复制操作&#xff1a;将chars复制到str中 链式表 顺序表 四.判空操作 链式表 顺序表 五.清空操作 六.串联结 链式表 顺序表 七.求子串 链式表 顺序表…

Vue 2.x 项目升级到 Vue 3详细指南【修改清单】

文章目录 前言0.迁移过程1. 安装 Vue 32. 逐一处理迁移中的警告3. 迁移全局和内部 API4. 迁移 Vue Router 和 Vuex5. 处理其他的不兼容变更 1. Vue3特性1. Composition API2. 更好的性能3. 更好的 TypeScript 支持4. 多个根元素5. Suspense 组件6. Teleport 组件7. 全局 API 的…

python 打印人口分布金字塔图

背景 今天介绍一个不使用 matplot&#xff0c;通过DebugInfo模块打印人口金字塔图的方法。 引入模块 pip install DebugInfo打印人口金字塔图 下面的代码构建了两个人口数据&#xff08;仅做功能演示&#xff0c;不承诺任何参考价值&#xff09;&#xff0c;男性人口和女性…

基础论文学习(4)——CLIP

《Learning Transferable Visual Models From Natural Language Supervision》 CLIP的英文全称是Contrastive Language-Image Pre-training&#xff0c;即一种基于对比文本-图像对的预训练模型。CLIP是一种基于对比学习的多模态模型&#xff0c;与CV中的一些对比学习方法如moc…

软考高级架构师下篇-12层次式架构设计理论与实践

目录 1. 考情分析2. 层次式体系结构概述3. 表现层框架设计4. 中间层框架设计5. 数据访问层设计6. 数据架构规划与设计7. 物联网层次架构设计7. 前文回顾1. 考情分析 根据考试大纲,层次式架构设计理论与实践知识点会涉及单选题型(约占2~5分)和案例题(25分),本小时内容偏重于方…

lesson9: C++多线程

1.线程库 1.1 thread类的简单介绍 C11 中引入了对 线程的支持 了&#xff0c;使得 C 在 并行编程时 不需要依赖第三方库 而且在原子操作中还引入了 原子类 的概念。要使用标准库中的线程&#xff0c;必须包含 < thread > 头文件 函数名 功能 thread() 构造一个线程对象…

LCD液晶屏接口静电浪涌保护用TVS/ESD二极管,如何选型?

LCD 液晶屏是Liquid Crystal Display 的简称&#xff0c;指将玻璃和LCD驱动器集成到一起的LCD显示产品&#xff0c;为用户提供了一个标准的LCD显示驱动接口&#xff0c;用户可以按照接口&#xff08;有4位、8位、VGA等不同类型&#xff09;要求进行操作来控制LCD正确显示。众所…

Fsm onehot

module top_module(input in,input [9:0] state,output [9:0] next_state,output out1,output out2);assign out1(state[8]|state[9])?1:0;assign out2(state[9]|state[7])?1:0;assign next_state[0](state[0]&(~in)) |(state[1]&(~in)) |(state[2]&(~in)) |(sta…

LVS+Keepalived 实验

Keepalived 是什么 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案&#xff0c;可以解决静态路由出现的单点故障问题的一款检查工具 在一个LVS服务集群中通常有主服务器&#xff08;MASTER&#xff09;和备份服务器&#xff08;BACKUP&#xff09;两种角色的服务器…

ShardingSphere01-docker环境安装

使用docker安装数据库是一个非常好的选择&#xff0c;后续的读写分离、数据分片等功能的数据库都是由docker创建。 一、安装准备 1、前提条件 Docker可以运行在Windows、Mac、CentOS、Ubuntu等操作系统上 Docker支持以下的CentOS版本&#xff1a; CentOS 7 (64-bit)CentOS …

LLM预训练大型语言模型Pre-training large language models

在上一个视频中&#xff0c;您被介绍到了生成性AI项目的生命周期。 如您所见&#xff0c;在您开始启动您的生成性AI应用的有趣部分之前&#xff0c;有几个步骤需要完成。一旦您确定了您的用例范围&#xff0c;并确定了您需要LLM在您的应用程序中的工作方式&#xff0c;您的下…

第59步 深度学习图像识别:误判病例分析(TensorFlow)

基于WIN10的64位系统演示 一、写在前面 本期内容对等于机器学习二分类系列的误判病例分析&#xff08;传送门&#xff09;。既然前面的数据可以这么分析&#xff0c;那么图形识别自然也可以。 本期以mobilenet_v2模型为例&#xff0c;因为它建模速度快。 同样&#xff0c;基…