Python项目源码57:数据格式转换工具1.0(csv+json+excel+sqlite3)

news2025/5/9 12:01:30

1.智能路径处理:自动识别并修正文件扩展名,根据转换类型自动建议目标路径,实时路径格式验证,自动补全缺失的文件扩展名。

2.增强型预览功能:使用pandastable库实现表格预览,第三方模块自己安装一下,自动加载前10行数据,支持实时预览更新,自动调整列宽,SQLite表名自动检测。

pip install pandastable

3.改进的UI交互:分栏式布局(左侧控制/右侧预览),自动保存路径建议,智能表名检测(SQLite),实时错误反馈,一键清空预览。

4.使用说明:选择转换类型,浏览选择源文件(自动生成目标路径建议),查看右侧数据预览确认数据正确性,(数据库转换需要输入/选择表名),点击"开始转换"按钮
在这里插入图片描述

# -*- coding: utf-8 -*-
# @Author : 小红牛
# 微信公众号:WdPython
import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
from tkinter.simpledialog import askstring
import sqlite3
import pandas as pd
from pandastable import Table

class DataConverterApp:
    def __init__(self, root):
        self.root = root
        self.root.title("智能数据转换工具1.0")
        self.root.geometry("1200x700")

        # 初始化变量
        self.source_path = tk.StringVar()
        self.target_path = tk.StringVar()
        self.table_name = tk.StringVar()
        self.conversion_type = tk.StringVar(value="excel2json")

        # 文件类型映射
        self.file_extensions = {
            "excel": ("Excel文件", ".xlsx"),
            "json": ("JSON文件", ".json"),
            "csv": ("CSV文件", ".csv"),
            "sqlite": ("SQLite数据库", ".db")
        }

        # 创建界面
        self.create_widgets()
        self.setup_preview_table()

    def setup_preview_table(self):
        """初始化数据预览表格"""
        self.preview_frame = ttk.Frame(self.preview_container)
        self.preview_frame.pack(fill=tk.BOTH, expand=True)
        self.ptable = Table(self.preview_frame, showtoolbar=False, showstatusbar=True)
        self.ptable.show()

    def create_widgets(self):
        # 主容器
        main_frame = ttk.Frame(self.root, padding=20)
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 左侧控制面板
        control_frame = ttk.Frame(main_frame, width=400)
        control_frame.pack(side=tk.LEFT, fill=tk.Y)

        # 右侧预览面板
        self.preview_container = ttk.LabelFrame(main_frame, text="数据预览", padding=10)
        self.preview_container.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)

        # 转换类型选择
        type_frame = ttk.LabelFrame(control_frame, text="转换类型", padding=10)
        type_frame.pack(fill=tk.X, pady=5)

        conversion_types = [
            ("Excel → JSON", "excel2json"),
            ("JSON → Excel", "json2excel"),
            ("CSV → JSON", "csv2json"),
            ("JSON → CSV", "json2csv"),
            ("SQLite → Excel", "sqlite2excel"),
            ("Excel → SQLite", "excel2sqlite"),
            ("SQLite → CSV", "sqlite2csv"),
            ("CSV → SQLite", "csv2sqlite")
        ]

        for text, value in conversion_types:
            rb = ttk.Radiobutton(type_frame, text=text, variable=self.conversion_type,
                                 value=value, command=self.update_ui)
            rb.pack(anchor=tk.W, pady=2)

        # 源文件设置
        source_frame = ttk.LabelFrame(control_frame, text="源文件设置", padding=10)
        source_frame.pack(fill=tk.X, pady=5)

        ttk.Label(source_frame, text="源文件路径:").pack(anchor=tk.W)
        ttk.Entry(source_frame, textvariable=self.source_path, width=50).pack(side=tk.LEFT, fill=tk.X, expand=True)
        ttk.Button(source_frame, text="浏览...", command=self.browse_source).pack(side=tk.RIGHT)

        # 目标文件设置
        target_frame = ttk.LabelFrame(control_frame, text="目标设置", padding=10)
        target_frame.pack(fill=tk.X, pady=5)

        ttk.Label(target_frame, text="目标路径:").pack(anchor=tk.W)
        ttk.Entry(target_frame, textvariable=self.target_path, width=50).pack(side=tk.LEFT, fill=tk.X, expand=True)
        ttk.Button(target_frame, text="浏览...", command=self.browse_target).pack(side=tk.RIGHT)

        # 数据库表名设置
        self.table_frame = ttk.LabelFrame(control_frame, text="数据库设置", padding=10)
        ttk.Label(self.table_frame, text="表名:").pack(side=tk.LEFT)
        ttk.Entry(self.table_frame, textvariable=self.table_name).pack(side=tk.LEFT, fill=tk.X, expand=True)

        # 操作按钮
        btn_frame = ttk.Frame(control_frame)
        btn_frame.pack(fill=tk.X, pady=10)

        ttk.Button(btn_frame, text="开始转换", command=self.start_conversion).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="清空预览", command=self.clear_preview).pack(side=tk.LEFT, padx=5)
        ttk.Button(btn_frame, text="退出", command=self.root.quit).pack(side=tk.RIGHT, padx=5)

        # 绑定路径变化事件
        self.source_path.trace_add("write", self.update_preview)
        self.table_name.trace_add("write", self.update_preview)

        self.update_ui()

    def get_conversion_info(self):
        """获取当前转换类型信息"""
        ct = self.conversion_type.get()
        source_type = ct.split("2")[0]
        target_type = ct.split("2")[1]
        return source_type, target_type

    def update_ui(self):
        """更新界面元素"""
        source_type, target_type = self.get_conversion_info()

        # 更新数据库设置可见性
        if "sqlite" in self.conversion_type.get():
            self.table_frame.pack(fill=tk.X, pady=5)
        else:
            self.table_frame.pack_forget()

        # 自动更新目标路径后缀
        current_target = self.target_path.get()
        if current_target:
            base, _ = os.path.splitext(current_target)
            new_ext = self.file_extensions[target_type][1]
            self.target_path.set(f"{base}{new_ext}")

    def browse_source(self):
        """选择源文件"""
        source_type, _ = self.get_conversion_info()
        file_type = self.file_extensions[source_type]
        path = filedialog.askopenfilename(
            title="选择源文件",
            filetypes=[file_type, ("所有文件", "*.*")]
        )
        if path:
            self.source_path.set(path)
            self.auto_suggest_target_path(path)

    def auto_suggest_target_path(self, source_path):
        """自动生成目标路径建议"""
        source_type, target_type = self.get_conversion_info()
        base = os.path.splitext(source_path)[0]
        new_ext = self.file_extensions[target_type][1]
        suggested_path = f"{base}_converted{new_ext}"
        self.target_path.set(suggested_path)

    def browse_target(self):
        """选择目标路径"""
        _, target_type = self.get_conversion_info()
        file_type = self.file_extensions[target_type]
        path = filedialog.asksaveasfilename(
            title="保存目标文件",
            defaultextension=file_type[1],
            filetypes=[file_type, ("所有文件", "*.*")]
        )
        if path:
            self.target_path.set(path)

    def clear_preview(self):
        """清空预览"""
        self.ptable.clearTable()
        self.ptable.model.df = pd.DataFrame()
        self.ptable.redraw()

    def load_preview_data(self):
        """加载预览数据"""
        source_path = self.source_path.get()
        if not source_path:
            return None

        try:
            source_type, _ = self.get_conversion_info()
            if source_type == "excel":
                return pd.read_excel(source_path, nrows=10)
            elif source_type == "csv":
                return pd.read_csv(source_path, nrows=10)
            elif source_type == "json":
                return pd.read_json(source_path).head(10)
            elif source_type == "sqlite":
                conn = sqlite3.connect(source_path)
                table_name = self.table_name.get() or self.detect_table_name(conn)
                if table_name:
                    return pd.read_sql_query(f"SELECT * FROM {table_name} LIMIT 10", conn)
            return None
        except Exception as e:
            messagebox.showerror("预览错误", f"无法加载数据: {str(e)}")
            return None

    def detect_table_name(self, conn):
        """自动检测数据库表名"""
        cursor = conn.cursor()
        cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
        tables = cursor.fetchall()
        if tables:
            return askstring("选择表", "检测到多个表,请选择:", initialvalue=tables[0][0])
        return None

    def update_preview(self, *args):
        """更新数据预览"""
        df = self.load_preview_data()
        if df is not None:
            self.ptable.model.df = df
            self.ptable.redraw()
            self.ptable.autoResizeColumns()

    def start_conversion(self):
        """执行转换操作"""
        source_path = self.source_path.get()
        target_path = self.target_path.get()
        conversion_type = self.conversion_type.get()
        table_name = self.table_name.get()

        try:
            # 自动修正目标路径后缀
            _, target_type = self.get_conversion_info()
            target_ext = self.file_extensions[target_type][1]
            if not target_path.endswith(target_ext):
                target_path = f"{os.path.splitext(target_path)[0]}{target_ext}"
                self.target_path.set(target_path)

            # 执行转换逻辑
            if conversion_type == "excel2json":
                df = pd.read_excel(source_path)
                df.to_json(target_path, orient='records', indent=4)
            elif conversion_type == "json2excel":
                df = pd.read_json(source_path)
                df.to_excel(target_path, index=False)
            elif conversion_type == "csv2json":
                df = pd.read_csv(source_path)
                df.to_json(target_path, orient='records', indent=4)
            elif conversion_type == "json2csv":
                df = pd.read_json(source_path)
                df.to_csv(target_path, index=False)
            elif conversion_type == "sqlite2excel":
                conn = sqlite3.connect(source_path)
                table_name = table_name or self.detect_table_name(conn)
                df = pd.read_sql_query(f"SELECT * FROM {table_name}", conn)
                df.to_excel(target_path, index=False)
            elif conversion_type == "excel2sqlite":
                df = pd.read_excel(source_path)
                conn = sqlite3.connect(target_path)
                df.to_sql(table_name or "Sheet1", conn, if_exists='replace', index=False)
            elif conversion_type == "sqlite2csv":
                conn = sqlite3.connect(source_path)
                table_name = table_name or self.detect_table_name(conn)
                df = pd.read_sql_query(f"SELECT * FROM {table_name}", conn)
                df.to_csv(target_path, index=False)
            elif conversion_type == "csv2sqlite":
                df = pd.read_csv(source_path)
                conn = sqlite3.connect(target_path)
                df.to_sql(table_name or "CSV_Data", conn, if_exists='replace', index=False)

            messagebox.showinfo("成功", f"文件已成功保存到:\n{target_path}")
            self.update_preview()
        except Exception as e:
            messagebox.showerror("错误", f"转换失败: {str(e)}")


if __name__ == "__main__":
    root = tk.Tk()
    app = DataConverterApp(root)
    root.mainloop()

完毕!!感谢您的收看

----------★★跳转到历史博文集合★★----------
我的零基础Python教程,Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字典数据可视化 matplotlib 词云图 Pyecharts 海龟画图 Pandas Bug处理 电脑小知识office自动化办公 编程工具 NumPy Pygame

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

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

相关文章

雷赛伺服电机

ACM0经济 编码器17位: ACM1基本 编码器23位磁编, ACM2通用 编码器24位光电, 插头定义:

【deepseek教学应用】001:deepseek如何撰写教案并自动实现word排版

本文讲述利用deepseek如何撰写教案并自动实现word高效完美排版。 文章目录 一、访问deepseek官网二、输入教案关键词三、格式转换四、word进一步排版 一、访问deepseek官网 官网:https://www.deepseek.com/ 进入主页后,点击【开始对话】,如…

CH32V208GBU6沁恒绑定配对获取静态地址

从事嵌入式单片机的工作算是符合我个人兴趣爱好的,当面对一个新的芯片我即想把芯片尽快搞懂完成项目赚钱,也想着能够把自己遇到的坑和注意事项记录下来,即方便自己后面查阅也可以分享给大家,这是一种冲动,但是这个或许并不是原厂希望的,尽管这样有可能会牺牲一些时间也有哪天原…

RT Thread Studio创建软件和硬件RTC工程

MCU型号:STM32F103RET6 一.配置软件模拟RTC 1.生成一个带串口输出的工程文件,新建RT-Thread项目工程文件。 2.查看电路图中的串口输出管脚,根据STMCubeMx软件可知此串口为USART1,选择芯片型号为STM32F103RET6,控制台…

苍穹外卖心得体会

1 登录认证 技术点:JWT令牌技术(JSON Web Token) JWT(JSON Web Token)是一种令牌技术,主要由三部分组成:Header头部、Payload载荷和Signature签名。Header头部存储令牌的类型(如JW…

Zcanpro搭配USBCANFD-200U在新能源汽车研发测试中的应用指南(周立功/致远电子)

——国产工具链的崛起与智能汽车测试新范式 引言:新能源汽车测试的国产化突围 随着新能源汽车智能化、网联化程度的提升,研发测试面临三大核心挑战:多协议融合(CAN FD/LIN/以太网)、高实时性数据交互需求、复杂工况下…

青少年抑郁症患者亚群结构和功能连接耦合的重构

目录 1 研究背景及目的 2 研究方法 2.1 数据来源与参与者 2.1.1 MDD患者: 2.1.2 健康对照组: 2.2 神经影像分析流程 2.2.1 图像采集与预处理: 2.2.2 网络构建: 2.2.3 区域结构-功能耦合(SC-FC耦合&#xff09…

SQL手工注入(DVWA)

手工SQL注入攻击的标准思路 Low等级 (1)判断是否存在注入 (2)猜解字段个数 (3)确定字段顺序 (4)获取当前数据库 (5)获取当前数据库中的表 &#xff08…

【大模型系列篇】Qwen3开源全新一代大语言模型来了,深入思考,更快行动

Qwen3开源模型全览 Qwen3是全球最强开源模型(MoEDense) Qwen3 采用混合专家(MoE)架构,总参数量 235B,激活仅需 22B。 Qwen3 预训练数据量达 36T,并在后训练阶段多轮强化学习,将非思…

flutter 专题 一百零四 Flutter环境搭建

Flutter简介 Flutter 是Google开发的一个移动跨平台(Android 和 iOS)的开发框架,使用的是 Dart 语言。和 React Native 不同的是,Flutter 框架并不是一个严格意义上的原生应用开发框架。Flutter 的目标是用来创建高性能、高稳定性…

玩玩OCR

一、Tesseract: 1.下载windows版: tesseract 2. 安装并记下路径,等会要填 3.保存.py文件 import pytesseract from PIL import Image def ocr_local_image(image_path):try:pytesseract.pytesseract.tesseract_cmd rD:\Programs\Tesseract-OCR\tesse…

“Everything“工具 是 Windows 上文件名搜索引擎神奇

01 Everything 和其他搜索引擎有何不同 轻量安装文件。 干净简洁的用户界面。 快速文件索引。 快速搜索。 快速启动。 最小资源使用。 轻量数据库。 实时更新。 官网:https://www.voidtools.com/zh-cn/downloads/ 通过网盘分享的文件:Every…

TIME_WAIT状态+UDP概念及模拟实现服务器和客户端收发数据

目录 一、TIME_WAIT状态存在的原因 二、TIME_WAIT状态存在的意义 三、TIME_WAIT状态的作用 四、UDP的基本概念 4.1 概念 4.2 特点 五、模拟实现UDP服务器和客户端收发数据 5.1 服务器udpser 5.2 客户端udpcil 一、TIME_WAIT状态存在的原因 1.可靠的终止TCP连接。 2.…

一篇撸清 Http,SSE 与 WebSocket

HTTP,SSE 和WebSocket都是网络传输的协议,本篇快速介绍三者的概念和比较。 SSE(Server-Sent Events) 是什么? SSE(Server-Sent Events),服务器发送事件, 是一种基于 HTTP 的轻量级协议,允许服务器主动向客户端(如浏览器)推送实时数据。它设计用于单向通信(服务器到…

56、【OS】【Nuttx】编码规范解读(四)

背景 接之前 blog 53、【OS】【Nuttx】编码规范解读(一) 54、【OS】【Nuttx】编码规范解读(二) 55、【OS】【Nuttx】编码规范解读(三) 分析了行宽格式,注释要求,花括号风格等&#…

IOT项目——DIY 气象站

开源项目:ESP32 气象站 作者:GiovanniAggiustatutto 原文链接:原文 开源项目:太阳能 WiFi 气象站 V4.0 作者:opengreenenergy 原文链接:原文 DIY 气象站 简介1-制版2-物料 温度设备塔风向标风速计雨量计框…

MODSIM选型指南:汽车与航空航天企业如何选择仿真平台

1. 引言 在竞争激烈的汽车与航空航天领域,仿真技术已成为产品研发不可或缺的环节。通过在设计阶段验证概念并优化性能,仿真平台能有效缩短开发周期并降低物理样机制作成本。 MODSIM(建模与仿真)作为达索系统3DEXPERIENCE平台的核…

【JavaEE】springMVC返回Http响应

目录 一、返回页面二、Controller和ResponseBody与RestController区别三、返回HTML代码⽚段四、返回JSON五、HttpServletResponse设置状态码六、设置Header6.1 HttpServletResponse设置6.2 RequestMapping设置 一、返回页面 步骤如下: 我们先要在static目录下创建…

计算机网络八股文--day4 --传输层TCP与UDP

这是面试中最常考到的一层:端到端(也就是进程之间)的透明数据传输服务,差错控制和流量控制 该层呈上启下,像上面的资源子网提高服务,并使用下面通信子网的服务 端口,用于唯一标识主机上进程的&…

个人开发免费好用

聊一聊 现在输入法非常多,有时候都不知道哪个更好用。 其实,只有多尝试,才能找到适合自己的。 今天给大家分享一款输入法,用起来比较顺手,大家可以试试。 软件介绍 BL输入法 这是一款绿色纯净,安全放心…