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使用socket进行简单网络连接的方法
Apr 29 Python
python dict.get()和dict['key']的区别详解
Jun 30 Python
Python常用的内置序列结构(列表、元组、字典)学习笔记
Jul 08 Python
Python实现获取磁盘剩余空间的2种方法
Jun 07 Python
django请求返回不同的类型图片json,xml,html的实例
May 22 Python
python获取当前文件路径以及父文件路径的方法
Jul 10 Python
Django MEDIA的配置及用法详解
Jul 25 Python
django 基于中间件实现限制ip频繁访问过程详解
Jul 30 Python
Python 根据日志级别打印不同颜色的日志的方法示例
Aug 08 Python
python多线程实现TCP服务端
Sep 03 Python
Django高并发负载均衡实现原理详解
Apr 04 Python
通过自学python能找到工作吗
Jun 21 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
PHP配置心得包含MYSQL5乱码解决
2006/11/20 PHP
php+mysqli事务控制实现银行转账实例
2015/01/29 PHP
PHP的时间戳与具体时间转化的简单实现
2016/06/13 PHP
PHP中$GLOBALS与global的区别详解
2019/03/21 PHP
php实现简单的守护进程创建、开启与关闭操作
2019/08/13 PHP
JS 统计时间
2021/03/09 Javascript
javascript常用的正则表达式实例
2014/05/15 Javascript
jQuery实现鼠标滑向当前图片高亮显示并且其它图片变灰的方法
2015/07/27 Javascript
jQuery position() 函数详解以及jQuery中position函数的应用
2015/12/14 Javascript
微信小程序 开发工具快捷键整理
2016/10/31 Javascript
angularjs的select使用及默认选中设置
2017/04/08 Javascript
Bootstrap多级菜单的实现代码
2017/05/23 Javascript
jQuery实现当拉动滚动条到底部加载数据的方法分析
2019/01/24 jQuery
如何利用ES6进行Promise封装总结
2019/02/11 Javascript
解决layui调用自定义方法提示未定义的问题
2019/09/14 Javascript
js仿京东放大镜效果
2020/08/09 Javascript
[49:35]KG vs SECRET 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
Python的string模块中的Template类字符串模板用法
2016/06/27 Python
Python算法之求n个节点不同二叉树个数
2017/10/27 Python
Python数据拟合与广义线性回归算法学习
2017/12/22 Python
python实现壁纸批量下载代码实例
2018/01/25 Python
Python 加密与解密小结
2018/12/06 Python
基于python实现获取网页图片过程解析
2020/05/11 Python
如何表示python中的相对路径
2020/07/08 Python
KIKO MILANO英国官网:意大利知名化妆品和护肤品品牌
2017/09/25 全球购物
独特的礼品和创新的科技产品:The Grommet
2018/02/24 全球购物
精选奢华:THE LIST
2019/09/05 全球购物
外企财务年会演讲稿
2014/01/03 职场文书
幼儿园小班教学反思
2014/02/02 职场文书
党的群众路线教育实践活动宣传标语口号
2014/06/06 职场文书
大学生暑期社会实践证明范本
2014/10/24 职场文书
于丹论语心得观后感
2015/06/15 职场文书
2019公司管理制度
2019/04/19 职场文书
会计工作自我鉴定范文
2019/06/21 职场文书
导游词之南京栖霞山
2019/10/18 职场文书
windows11怎么查看wifi密码? win11查看wifi密码的技巧
2021/11/21 数码科技