使用wxPython和Python-docx创建合同生成器:一个实用的GUI应用程序教程

在当今的商业世界中,合同是不可或缺的。但是,反复修改和生成合同可能会是一个耗时且容易出错的过程。今天,我们将探讨如何使用Python创建一个简单但强大的合同生成器,它不仅可以节省时间,还能减少人为错误。

项目概述

我们将创建一个图形用户界面(GUI)应用程序,允许用户:

  1. 选择一个Word模板文件
  2. 输入合同详细信息,如甲方、乙方、日期、总金额等
  3. 自动生成一个新的、定制的合同文档

这个项目将展示如何结合使用wxPython(用于创建GUI)和Python-docx(用于处理Word文档)来创建一个实用的业务工具。
C:\pythoncode\new\contacttodoct.py

技术栈

  • Python 3.x
  • wxPython: 用于创建跨平台的GUI应用程序
  • Python-docx: 用于读取和修改Word文档

全部代码

import wx
import os
from docx import Document
from docx.shared import Pt
from datetime import datetime

class ContractFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='Contract Generator', size=(500, 600))
        
        # 创建主面板
        main_panel = wx.Panel(self)
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        
        # 创建滚动窗口
        self.scrolled_window = wx.ScrolledWindow(main_panel)
        self.scrolled_window.SetScrollRate(0, 10)
        
        # 创建控件
        self.template_path = wx.TextCtrl(self.scrolled_window)
        browse_button = wx.Button(self.scrolled_window, label='Browse')
        browse_button.Bind(wx.EVT_BUTTON, self.on_browse)

        self.party_a = wx.TextCtrl(self.scrolled_window)
        self.party_b = wx.TextCtrl(self.scrolled_window)
        self.date = wx.TextCtrl(self.scrolled_window)
        self.total_amount = wx.TextCtrl(self.scrolled_window)

        self.payment_dates = [wx.TextCtrl(self.scrolled_window) for _ in range(3)]
        self.payment_amounts = [wx.TextCtrl(self.scrolled_window) for _ in range(3)]
        self.payment_percentages = [wx.TextCtrl(self.scrolled_window) for _ in range(3)]

        generate_button = wx.Button(main_panel, label='Generate Contract')
        generate_button.Bind(wx.EVT_BUTTON, self.on_generate)

        # 创建滚动窗口内的布局
        scroll_sizer = wx.BoxSizer(wx.VERTICAL)
        scroll_sizer.Add(wx.StaticText(self.scrolled_window, label="Template File:"), 0, wx.ALL, 5)
        scroll_sizer.Add(self.template_path, 0, wx.EXPAND|wx.ALL, 5)
        scroll_sizer.Add(browse_button, 0, wx.ALL, 5)
        
        scroll_sizer.Add(wx.StaticText(self.scrolled_window, label="Party A:"), 0, wx.ALL, 5)
        scroll_sizer.Add(self.party_a, 0, wx.EXPAND|wx.ALL, 5)
        scroll_sizer.Add(wx.StaticText(self.scrolled_window, label="Party B:"), 0, wx.ALL, 5)
        scroll_sizer.Add(self.party_b, 0, wx.EXPAND|wx.ALL, 5)
        scroll_sizer.Add(wx.StaticText(self.scrolled_window, label="Date:"), 0, wx.ALL, 5)
        scroll_sizer.Add(self.date, 0, wx.EXPAND|wx.ALL, 5)
        scroll_sizer.Add(wx.StaticText(self.scrolled_window, label="Total Amount:"), 0, wx.ALL, 5)
        scroll_sizer.Add(self.total_amount, 0, wx.EXPAND|wx.ALL, 5)

        for i in range(3):
            scroll_sizer.Add(wx.StaticText(self.scrolled_window, label=f"Payment {i+1}:"), 0, wx.ALL, 5)
            scroll_sizer.Add(wx.StaticText(self.scrolled_window, label="Date:"), 0, wx.ALL, 5)
            scroll_sizer.Add(self.payment_dates[i], 0, wx.EXPAND|wx.ALL, 5)
            scroll_sizer.Add(wx.StaticText(self.scrolled_window, label="Amount:"), 0, wx.ALL, 5)
            scroll_sizer.Add(self.payment_amounts[i], 0, wx.EXPAND|wx.ALL, 5)
            scroll_sizer.Add(wx.StaticText(self.scrolled_window, label="Percentage:"), 0, wx.ALL, 5)
            scroll_sizer.Add(self.payment_percentages[i], 0, wx.EXPAND|wx.ALL, 5)

        self.scrolled_window.SetSizer(scroll_sizer)
        
        # 设置主布局
        main_sizer.Add(self.scrolled_window, 1, wx.EXPAND|wx.ALL, 5)
        main_sizer.Add(generate_button, 0, wx.ALL|wx.CENTER, 5)
        main_panel.SetSizer(main_sizer)

        # 计算滚动窗口的虚拟大小
        self.scrolled_window.SetVirtualSize(scroll_sizer.GetMinSize())
        
        self.Show()

    def on_browse(self, event):
        with wx.FileDialog(self, "Choose the template file", wildcard="Word files (*.docx)|*.docx",
                           style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
            if fileDialog.ShowModal() == wx.ID_CANCEL:
                return
            self.template_path.SetValue(fileDialog.GetPath())

    def on_generate(self, event):
        if not os.path.exists(self.template_path.GetValue()):
            wx.MessageBox("Please select a valid template file", "Error", wx.OK | wx.ICON_ERROR)
            return

        # 读取模板文件
        doc = Document(self.template_path.GetValue())

        # 替换内容
        for paragraph in doc.paragraphs:
            paragraph.text = paragraph.text.replace("{PartyA}", self.party_a.GetValue())
            paragraph.text = paragraph.text.replace("{PartyB}", self.party_b.GetValue())
            paragraph.text = paragraph.text.replace("{Date}", self.date.GetValue())
            paragraph.text = paragraph.text.replace("{TotalAmount}", self.total_amount.GetValue())

            for i in range(3):
                paragraph.text = paragraph.text.replace(f"{{PaymentDate{i+1}}}", self.payment_dates[i].GetValue())
                paragraph.text = paragraph.text.replace(f"{{PaymentAmount{i+1}}}", self.payment_amounts[i].GetValue())
                paragraph.text = paragraph.text.replace(f"{{PaymentPercentage{i+1}}}", self.payment_percentages[i].GetValue())

        # 保存新文件
        save_path = f"Contract_{datetime.now().strftime('%Y%m%d_%H%M%S')}.docx"
        doc.save(save_path)
        wx.MessageBox(f"Contract generated and saved as {save_path}", "Success", wx.OK | wx.ICON_INFORMATION)

if __name__ == '__main__':
    app = wx.App()
    frame = ContractFrame()
    app.MainLoop()

步骤1: 设置环境

首先,确保您已经安装了所需的库:

pip install wxPython python-docx

步骤2: 创建基本GUI结构

我们首先创建一个基本的GUI框架,包括一个主窗口和一个滚动面板:

import wx
import os
from docx import Document
from datetime import datetime

class ContractFrame(wx.Frame):
    def __init__(self):
        super().__init__(parent=None, title='Contract Generator', size=(500, 600))
        
        main_panel = wx.Panel(self)
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        
        self.scrolled_window = wx.ScrolledWindow(main_panel)
        self.scrolled_window.SetScrollRate(0, 10)
        
        # 这里将添加更多的控件
        
        self.Show()

if __name__ == '__main__':
    app = wx.App()
    frame = ContractFrame()
    app.MainLoop()

步骤3: 添加输入字段

接下来,我们添加各种输入字段,如模板文件路径、甲方、乙方、日期等:

class ContractFrame(wx.Frame):
    def __init__(self):
        # ... 前面的代码 ...
        
        self.template_path = wx.TextCtrl(self.scrolled_window)
        browse_button = wx.Button(self.scrolled_window, label='Browse')
        browse_button.Bind(wx.EVT_BUTTON, self.on_browse)

        self.party_a = wx.TextCtrl(self.scrolled_window)
        self.party_b = wx.TextCtrl(self.scrolled_window)
        self.date = wx.TextCtrl(self.scrolled_window)
        self.total_amount = wx.TextCtrl(self.scrolled_window)

        self.payment_dates = [wx.TextCtrl(self.scrolled_window) for _ in range(3)]
        self.payment_amounts = [wx.TextCtrl(self.scrolled_window) for _ in range(3)]
        self.payment_percentages = [wx.TextCtrl(self.scrolled_window) for _ in range(3)]

        generate_button = wx.Button(main_panel, label='Generate Contract')
        generate_button.Bind(wx.EVT_BUTTON, self.on_generate)
        
        # 添加到sizer并设置布局
        # ...

步骤4: 实现文件浏览功能

我们需要一个方法来允许用户选择模板文件:

def on_browse(self, event):
    with wx.FileDialog(self, "Choose the template file", wildcard="Word files (*.docx)|*.docx",
                       style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
        if fileDialog.ShowModal() == wx.ID_CANCEL:
            return
        self.template_path.SetValue(fileDialog.GetPath())

步骤5: 实现合同生成功能

这是我们程序的核心,我们将使用Python-docx来读取模板,替换占位符,并生成新的合同文档:

def on_generate(self, event):
    if not os.path.exists(self.template_path.GetValue()):
        wx.MessageBox("Please select a valid template file", "Error", wx.OK | wx.ICON_ERROR)
        return

    doc = Document(self.template_path.GetValue())

    for paragraph in doc.paragraphs:
        paragraph.text = paragraph.text.replace("{PartyA}", self.party_a.GetValue())
        paragraph.text = paragraph.text.replace("{PartyB}", self.party_b.GetValue())
        paragraph.text = paragraph.text.replace("{Date}", self.date.GetValue())
        paragraph.text = paragraph.text.replace("{TotalAmount}", self.total_amount.GetValue())

        for i in range(3):
            paragraph.text = paragraph.text.replace(f"{{PaymentDate{i+1}}}", self.payment_dates[i].GetValue())
            paragraph.text = paragraph.text.replace(f"{{PaymentAmount{i+1}}}", self.payment_amounts[i].GetValue())
            paragraph.text = paragraph.text.replace(f"{{PaymentPercentage{i+1}}}", self.payment_percentages[i].GetValue())

    save_path = f"Contract_{datetime.now().strftime('%Y%m%d_%H%M%S')}.docx"
    doc.save(save_path)
    wx.MessageBox(f"Contract generated and saved as {save_path}", "Success", wx.OK | wx.ICON_INFORMATION)

合同模板

为了使这个程序工作,我们需要一个包含占位符的Word模板。这里是一个简单的示例:

合作协议

本协议由以下双方于{Date}签订:

甲方:{PartyA}
乙方:{PartyB}

...

2.1 本合同总金额为人民币{TotalAmount}元整。

2.2 付款方式如下:

   第一期付款:于{PaymentDate1}支付{PaymentAmount1}元,占总金额的{PaymentPercentage1}。
   第二期付款:于{PaymentDate2}支付{PaymentAmount2}元,占总金额的{PaymentPercentage2}。
   第三期付款:于{PaymentDate3}支付{PaymentAmount3}元,占总金额的{PaymentPercentage3}。

...

结果如下

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

结论

通过这个项目,我们创建了一个实用的合同生成器,它展示了如何:

  1. 使用wxPython创建用户友好的GUI应用程序
  2. 使用Python-docx处理Word文档
  3. 将GUI与文档处理功能结合,创建一个实用的业务工具

这个应用程序可以显著提高合同生成的效率,减少人为错误,并为进一步的自动化和定制提供了基础。

你可以进一步改进这个项目,例如添加更多的输入验证,支持更复杂的模板,或者集成数据库来存储和检索合同信息。

希望这个教程能够帮助你开始使用Python创建实用的业务应用程序。祝编码愉快!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python基础教学之三:函数与模块篇——实现代码重用和模块化

Python基础教学之三:函数与模块篇——实现代码重用和模块化 一、函数的定义与使用 1. 理解函数 函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码块。它可以提高代码的重用性和程序的清晰度。 你可以定义一个由自己想要功能的函数,以下是…

从零写UVC摄像头驱动(一)驱动框架

一、前言 写一个USB摄像头驱动程序1.构造一个usb_driver2.设置video_device probe: 2.1. 分配video_device:video_device_alloc 2.2. 设置 .fops .ioctl_ops (里面需要设置11项) 如果要用内核提供的缓冲区操作函数&#…

Redis基础教程(十六):Redis Stream

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝&#x1f49…

附下载 | 100项能源领域网络与数据安全政策全集(2024版)

能源是工业的粮食,能源安全事关国家根本安全。当今国际局势风云变幻,全球地缘政治、经济、科技体系正经历深刻变化,能源局势将更加错综复杂,威胁能源安全的各种“灰犀牛”“黑天鹅”事件时有发生,促使国际能源版图深刻…

Go泛型详解

官网文档:https://go.dev/blog/intro-generics 泛型为该语言添加了三个新的重要功能: 函数和类型的类型参数。将接口类型定义为类型集,包括没有方法的类型。类型推断,在许多情况下允许在调用函数时省略类型参数。 类型参数&…

二分查找算法——部分OJ题详解

目录 关于二分查找算法 部分OJ题详解 704.二分查找 一,分析题目 二,细节处理 三,题目代码 四,*总结朴素模板 *34.在排序数组中查找元素的第一个和最后一个位置 一,查找左端点 二,处理左端点细…

HTML速成学习总结

一、HTML开始 简介&#xff1a; 超文本标记语言&#xff08;英语&#xff1a;HyperText Markup Language&#xff0c;简称&#xff1a;HTML&#xff09;是一种用于创建网页的标准标记语言。 初始网页&#xff1a; <!doctype html> <html><head><meta …

【Java数据结构】初识线性表之一:顺序表

使用Java简单实现一个顺序表 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构&#xff0c;一般情况下采用数组存储。在数组上完成数据的增删查改。 线性表大致包含如下的一些方法&#xff1a; public class MyArrayList { private int[] array; pri…

FastAPI 学习之路(三十五)项目结构优化

之前我们创建的文件都是在一个目录中&#xff0c;但是在我们的实际开发中&#xff0c;肯定不能这样设计&#xff0c;那么我们去创建一个目录&#xff0c;叫models&#xff0c;大致如下。 主要目录是&#xff1a; __init__.py 是一个空文件&#xff0c;说明models是一个package…

2.线性回归

简化的房价模型 假设1&#xff1a;影响房价的关键因素时卧室个数&#xff0c;卫生间和居住面积&#xff0c;记为 x 1 , x 2 , x 3 x_1,x_2,x_3 x1​,x2​,x3​ 假设2&#xff1a;成交价时关键因素的加权和&#xff1a; y w 1 x 1 w 2 x 2 w 3 x 3 b y w_1x_1w_2x_2w_3x…

【LeetCode:1071. 字符串的最大公因子 + 模拟 + 最大公约数】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

javaweb中的请求与响应--基于postman工具的应用(附带postman的详细安装步骤)

一、前言 后端的第一天感觉难度就上来了&#xff0c;可能是基础太过薄弱了吧。目前看视频已经有点跟不上了&#xff0c;果然15天想要拿下还是太勉强了点。30天还差不多。不知道读者们有没有好好的去学这方面的知识&#xff0c;没有什么是学不会的&#xff0c;关键是坚持。 Po…

# Redis 入门到精通(一)数据类型(3)

Redis 入门到精通&#xff08;一&#xff09;数据类型&#xff08;3&#xff09; 一、redis 数据类型–set 类型介绍与基本操作 1、set 类型 新的存储需求: 存储大量的数据&#xff0c;在查询方面提供更高的效率。需要的存储结构: 能够保存大量的数据&#xff0c;高效的内部…

飞睿智能6公里WiFi图传接收模块,低延迟、抗干扰、高速稳定传输数据,无人机、农田远距离WiFi模块

在科技日新月异的今天&#xff0c;无线通信技术正以前所未有的速度发展&#xff0c;不仅改变了我们的生活方式&#xff0c;还为企业带来了前所未有的商业机遇。今天&#xff0c;我要向大家介绍一款飞睿智能的产品——6公里WiFi图传接收模块&#xff0c;它以其高性能、稳定的传输…

华为od100问持续分享-1

我是一名软件开发培训机构老师&#xff0c;我的学生已经有上百人通过了华为OD机试&#xff0c;学生们每次考完试&#xff0c;会把题目拿出来一起交流分享。 重要&#xff1a;2024年5月份开始&#xff0c;考的都是OD统一考试&#xff08;D卷&#xff09;&#xff0c;题库已经整…

国漫推荐10

玄幻、恋爱 1.《两不疑》古风、恋爱 2.《中国古诗词动漫》 3.《武神主宰》 4.《百妖谱》 5.《灵剑尊》 6.《万界仙踪》 7.《万界神主》 8.《武庚纪》 9.《无上神帝》

全网最适合入门的面向对象编程教程:14 类和对象的 Python 实现-类的静态方法和类方法,你分得清吗?

全网最适合入门的面向对象编程教程&#xff1a;14 类和对象的 Python 实现-类的静态方法和类方法&#xff0c;你分得清吗&#xff1f; 摘要&#xff1a; 本文主要介绍了Python中类和对象中的类方法和静态方法&#xff0c;以及类方法和静态方法的定义、特点、应用场景和使用方…

轻松搭建 VirtualBox + Vagrant + Linux 虚拟机

一、准备工作 首先&#xff0c;我们来了解一下搭建 VirtualBox Vagrant Linux 虚拟机所需的软件准备工作。 VirtualBox 的下载地址&#xff1a;您可以通过访问https://www.virtualbox.org/wiki/Downloads获取适用于您系统的版本。 Vagrant 的下载地址&#xff1a;前往http…

5款常用的漏洞扫描工具,网安人员不能错过!

漏洞扫描是指基于漏洞数据库&#xff0c;通过扫描等手段对指定的远程或者本地计算机系统的安全脆弱性进行检测&#xff0c;发现可利用漏洞的一种安全检测的行为。 在漏洞扫描过程中&#xff0c;我们经常会借助一些漏扫工具&#xff0c;市面上漏扫工具众多&#xff0c;其中有一…

数学建模·Topsis优劣解距离法

Topsis优劣解 一种新的评价方法&#xff0c;特点就是利用原有数据&#xff0c;客观性强。相较于模糊评价和层次评价 更加客观&#xff0c;充分利用原有数据&#xff0c;精确反映方案差距基本原理 离最优解最近&#xff0c;离最劣解越远具体步骤 正向化 代码与原理与熵权法…