使用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创建实用的业务应用程序。祝编码愉快!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值