Python操作Word批量生成合同的实现示例


Posted in Python onAugust 28, 2020

背景:大约有3K家商家需要重新确认信息并签订合同。合同是统一的Word版本。每个供应商需要修改合同内的金额部分。人工处理方式需要每个复制粘贴且金额要生成大写金额。基于重复工作可偷懒。用Python解救一下。

#导入对应数据库
import numpy as np 
import pandas as pd 
import os 
import docx
from docx.shared import Pt
from docx.oxml.ns import qn
#修改项目文件地址
os.chdir(r'C:\Users\WIN7\Desktop\分期账单自动化')
os.getcwd()
'''
人民币数字转大写汉字
'''
# coding: utf-8
import warnings
from decimal import Decimal

def cncurrency(value, capital=True, prefix=False, classical=None):
  '''
  参数:
  capital:  True  大写汉字金额
        False 一般汉字金额
  classical: True  元
        False 圆
  prefix:   True  以'人民币'开头
        False, 无开头
  '''
  if not isinstance(value, (Decimal, str, int)):
    msg = '''
    由于浮点数精度问题,请考虑使用字符串,或者 decimal.Decimal 类。
    因使用浮点数造成误差而带来的可能风险和损失作者概不负责。
    '''
    warnings.warn(msg, UserWarning)
  # 默认大写金额用圆,一般汉字金额用元
  if classical is None:
    classical = True if capital else False
    
  # 汉字金额前缀
  if prefix is True:
    prefix = '人民币'
  else:
    prefix = ''
    
  # 汉字金额字符定义
  dunit = ('角', '分')
  if capital:
    num = ('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖')
    iunit = [None, '拾', '佰', '仟', '万', '拾', '佰', '仟','亿', '拾', '佰', '仟', '万', '拾', '佰', '仟']
  else:
    num = ('?', '一', '二', '三', '四', '五', '六', '七', '八', '九')
    iunit = [None, '十', '百', '千', '万', '十', '百', '千','亿', '十', '百', '千', '万', '十', '百', '千']
  if classical:
    iunit[0] = '元' if classical else '圆'
  # 转换为Decimal,并截断多余小数

  if not isinstance(value, Decimal):
    value = Decimal(value).quantize(Decimal('0.01'))

  # 处理负数
  if value < 0:
    prefix += '负'     # 输出前缀,加负
    value = - value     # 取正数部分,无须过多考虑正负数舍入
                # assert - value + value == 0
  # 转化为字符串
  s = str(value)
  if len(s) > 19:
    raise ValueError('金额太大了,不知道该怎么表达。')
  istr, dstr = s.split('.')      # 小数部分和整数部分分别处理
  istr = istr[::-1]          # 翻转整数部分字符串
  so = []   # 用于记录转换结果
  
  # 零
  if value == 0:
    return prefix + num[0] + iunit[0]
  haszero = False   # 用于标记零的使用
  if dstr == '00':
    haszero = True # 如果无小数部分,则标记加过零,避免出现“圆零整”
    
  # 处理小数部分
  # 分
  if dstr[1] != '0':
    so.append(dunit[1])
    so.append(num[int(dstr[1])])
  else:
    so.append('整')     # 无分,则加“整”
  # 角
  if dstr[0] != '0':
    so.append(dunit[0])
    so.append(num[int(dstr[0])])
  elif dstr[1] != '0':
    so.append(num[0])    # 无角有分,添加“零”
    haszero = True     # 标记加过零了
    
  # 无整数部分
  if istr == '0':
    if haszero:       # 既然无整数部分,那么去掉角位置上的零
      so.pop()
    so.append(prefix)    # 加前缀
    so.reverse()      # 翻转
    return ''.join(so)

  # 处理整数部分
  for i, n in enumerate(istr):
    n = int(n)
    if i % 4 == 0:     # 在圆、万、亿等位上,即使是零,也必须有单位
      if i == 8 and so[-1] == iunit[4]:  # 亿和万之间全部为零的情况
        so.pop()            # 去掉万
      so.append(iunit[i])
      if n == 0:             # 处理这些位上为零的情况
        if not haszero:         # 如果以前没有加过零
          so.insert(-1, num[0])    # 则在单位后面加零
          haszero = True       # 标记加过零了
      else:                # 处理不为零的情况
        so.append(num[n])
        haszero = False         # 重新开始标记加零的情况
    else:                  # 在其他位置上
      if n != 0:             # 不为零的情况
        so.append(iunit[i])
        so.append(num[n])
        haszero = False         # 重新开始标记加零的情况
      else:                # 处理为零的情况
        if not haszero:         # 如果以前没有加过零
          so.append(num[0])
          haszero = True

  # 最终结果
  so.append(prefix)
  so.reverse()
  return ''.join(so)
#数据准备阶段 导入大写
#读取预备好的EXCEL表格
text = pd.read_excel('付款预备表.xlsx')
#print(text)
text['EC总应付额']
list1 = []
for i in text['EC总应付额']:
  list1.append(cncurrency(str(i)))
text.append(list1)
text['大写金额'] = list1
text.shape[0]
print(text.head())
document12 = docx.Document('分期SPM模板(12期).docx')
document24 = docx.Document('分期SPM模板(24期).docx')
supp_num = 0 
for supp_num in range(text.shape[0]):
  paragraph_num = 0
  A = text.iat[supp_num,2]
  B = text.iat[supp_num,5]
  qishu = text.iat[supp_num,3]
  supp_name = text.iat[supp_num,1]
  user_name = text.iat[supp_num,4]
  content = "双方确认,截止至 2020 年 3 月 31 日,扣除原合同和原合作约定到货异常(包括但不仅限于缺货、少货、货损、到货不符)、违约责任、赔偿责任、甲方代乙方垫付等所涉相关费用后,甲方尚欠付乙方货款金额合计人民币{}元(大写:{})。".format(A,B)
  if qishu == "12期":
    p = document12.paragraphs[8].clear()
    run1 = p.add_run(content)
    run1.font.size = Pt(12)
    run1.font.name = '仿宋'
    run1.element.rPr.rFonts.set(qn('w:eastAsia'), '仿宋')
    document12.save("{}.docx".format(supp_name))
  else:
    p = document24.paragraphs[8].clear()
    run1 = p.add_run(content)
    run1.font.size = Pt(12)
    run1.font.name = '仿宋'
    run1.element.rPr.rFonts.set(qn('w:eastAsia'), '仿宋')
    document24.save("{}.docx".format(supp_name))

主要是分成四个板块。
 一:导入相关的包,这个就不说了
 二:数字金额转大写金额。这个网上一大堆的现成的函数,也就不用自己写,Copy测试一下,OK的。
 三:预备自己的数据。
 四:本来想替换指定位置的内容的,但是发现操作相对有点困难,那就思维放大,直接替换整个段落。用个format,把需要替换的内容直接填入。然后用docx包里面的.clear【清除段落】 加 add_run【添加段落】的方式,配合上.font.size 和.font.name 调整字体大小与字体。最后save就OJBK了。

到此这篇关于Python操作Word批量生成合同的实现示例的文章就介绍到这了,更多相关Python批量替换word内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
介绍Python的Django框架中的静态资源管理器django-pipeline
Apr 25 Python
python简单分割文件的方法
Jul 30 Python
Python基于百度AI的文字识别的示例
Apr 21 Python
python字符串常用方法
Jun 14 Python
python整合ffmpeg实现视频文件的批量转换
May 31 Python
感知器基础原理及python实现过程详解
Sep 30 Python
keras获得model中某一层的某一个Tensor的输出维度教程
Jan 24 Python
详解Django3中直接添加Websockets方式
Feb 12 Python
Python爬取新型冠状病毒“谣言”新闻进行数据分析
Feb 16 Python
Django更新models数据库结构步骤
Apr 01 Python
python3检查字典传入函数键是否齐全的实例
Jun 05 Python
python实现简单的tcp 文件下载
Sep 16 Python
Python接口自动化测试的实现
Aug 28 #Python
解决python和pycharm安装gmpy2 出现ERROR的问题
Aug 28 #Python
Python自动登录QQ的实现示例
Aug 28 #Python
python opencv pytesseract 验证码识别的实现
Aug 28 #Python
简单的命令查看安装的python版本号
Aug 28 #Python
python进行OpenCV实战之画图(直线、矩形、圆形)
Aug 27 #Python
python opencv实现简易画图板
Aug 27 #Python
You might like
构建简单的Webmail系统
2006/10/09 PHP
一个显示某段时间内每个月的方法 返回由这些月份组成的数组
2012/05/16 PHP
学习php设计模式 php实现工厂模式(factory)
2015/12/07 PHP
PHP简单获取网站百度搜索和搜狗搜索收录量的方法
2016/08/23 PHP
javascript 利用Image对象实现的埋点(某处的点击数)统计
2012/12/28 Javascript
js获取键盘按键响应事件(兼容各浏览器)
2013/05/16 Javascript
JS获取键盘上任意按键的值(实例代码)
2013/11/12 Javascript
Jquery动态添加及删除页面节点元素示例代码
2014/06/16 Javascript
js实现有时间限制消失的图片方法
2015/02/27 Javascript
jquery的幻灯片图片切换效果代码分享
2015/09/07 Javascript
js图片轮播特效代码分享
2015/09/07 Javascript
JS实现很实用的对联广告代码(可自适应高度)
2015/09/18 Javascript
jQuery+jsp下拉框联动获取本地数据的方法(附源码)
2015/12/03 Javascript
深入理解Ajax的get和post请求
2016/06/02 Javascript
Angular的模块化(代码分享)
2016/12/26 Javascript
解决bootstrap中使用modal加载kindeditor时弹出层文本框不能输入的问题
2017/06/05 Javascript
vue将时间戳转换成自定义时间格式的方法
2018/03/02 Javascript
vue使用keep-alive保持滚动条位置的实现方法
2019/04/09 Javascript
详解jQuery中的getAll()和cleanData()
2019/04/15 jQuery
javascript事件循环event loop的简单模型解释与应用分析
2020/03/14 Javascript
js实现拖拽元素选择和删除
2020/08/25 Javascript
在Python中测试访问同一数据的竞争条件的方法
2015/04/23 Python
用python制作游戏外挂
2018/01/04 Python
JavaScript中的模拟事件和自定义事件实例分析
2018/07/27 Python
python调用外部程序的实操步骤
2019/03/04 Python
解决python3 安装不了PIL的问题
2019/08/16 Python
python 已知三条边求三角形的角度案例
2020/04/12 Python
Spongelle官网:美国的创意护肤洗护品牌
2019/05/15 全球购物
村优秀党员事迹材料
2014/01/15 职场文书
班子四风对照检查材料思想汇报
2014/09/29 职场文书
执法作风整顿剖析材料
2014/10/11 职场文书
2014年教务处工作总结
2014/12/03 职场文书
停电放假通知
2015/04/14 职场文书
读《庄子》有感:美而不自知
2019/11/06 职场文书
Golang的继承模拟实例
2021/06/30 Golang
Python OpenCV超详细讲解读取图像视频和网络摄像头
2022/04/02 Python