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中线程编程之threading模块的使用详解
Jun 23 Python
Python使用smtplib模块发送电子邮件的流程详解
Jun 27 Python
Python 私有函数的实例详解
Sep 11 Python
pygame游戏之旅 添加游戏界面按键图形
Nov 20 Python
利用python和百度地图API实现数据地图标注的方法
May 13 Python
Python自定义函数计算给定日期是该年第几天的方法示例
May 30 Python
pyqt5 实现工具栏文字图片同时显示
Jun 13 Python
Python处理mysql特殊字符的问题
Mar 02 Python
python 日志 logging模块详细解析
Mar 31 Python
解决jupyter notebook打不开无反应 浏览器未启动的问题
Apr 10 Python
Python3基于plotly模块保存图片表格
Aug 03 Python
Python-split()函数实例用法讲解
Dec 18 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截取指定图片大小的方法
2014/12/10 PHP
Laravel5.* 打印出执行的sql语句的方法
2017/07/24 PHP
Laravel使用支付宝进行支付的示例代码
2017/08/16 PHP
PHP中使用jQuery+Ajax实现分页查询多功能操作(示例讲解)
2017/09/17 PHP
PHP使用HTML5 FileApi实现Ajax上传文件功能示例
2019/07/01 PHP
JavaScript 字符串连接性能优化
2008/12/20 Javascript
jquery 注意事项与常用语法小结
2010/06/07 Javascript
jQuery之过滤元素操作小结
2013/11/30 Javascript
jquery操作对象数组元素方法详解
2014/11/26 Javascript
js实现完全自定义可带多级目录的网页鼠标右键菜单方法
2015/02/28 Javascript
JS数组操作(数组增加、删除、翻转、转字符串、取索引、截取(切片)slice、剪接splice、数组合并)
2016/05/20 Javascript
Javascript基础_嵌入图像的简单实现
2016/06/14 Javascript
JavaScript中函数声明与函数表达式的区别详解
2016/08/18 Javascript
bootstrap下拉列表与输入框组结合的样式调整
2016/10/08 Javascript
AngularJS指令与指令之间的交互功能示例
2016/12/14 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
2017/04/14 Javascript
Mac系统下Webstorm快捷键整理大全
2017/05/28 Javascript
Vue项目中使用jsonp抓取跨域数据的方法
2019/11/10 Javascript
利用Python为iOS10生成图标和截屏
2016/09/24 Python
详解使用python crontab设置linux定时任务
2016/12/08 Python
使用Python3制作TCP端口扫描器
2017/04/17 Python
Ubuntu安装Jupyter Notebook教程
2017/10/18 Python
Python异常对代码运行性能的影响实例解析
2018/02/08 Python
Python3.6简单的操作Mysql数据库的三个实例
2018/10/17 Python
python3实现逐字输出的方法
2019/01/23 Python
Pycharm 2020最新永久激活码(附最新激活码和插件)
2020/09/17 Python
园林施工员岗位职责
2013/12/11 职场文书
自我介绍演讲稿
2014/01/15 职场文书
校长寄语大全
2014/04/09 职场文书
党校培训自我鉴定范文
2014/04/10 职场文书
产品发布会策划方案
2014/05/12 职场文书
简历中自我评价范文
2015/03/11 职场文书
2015年营业员工作总结
2015/04/23 职场文书
实施意见格式范本
2015/06/05 职场文书
感谢师恩主题班会
2015/08/17 职场文书
MySQL安装失败的原因及解决步骤
2022/06/14 MySQL