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之不要红头文件(2)
Sep 28 Python
Python实现抓取城市的PM2.5浓度和排名
Mar 19 Python
使用Python编写简单的端口扫描器的实例分享
Dec 18 Python
Python中内置的日志模块logging用法详解
Jul 12 Python
python用reduce和map把字符串转为数字的方法
Dec 19 Python
python实现淘宝秒杀聚划算抢购自动提醒源码
Jun 23 Python
python3.4实现邮件发送功能
May 28 Python
Python爬虫获取图片并下载保存至本地的实例
Jun 01 Python
解决Python中list里的中文输出到html模板里的问题
Dec 17 Python
Python迭代器Iterable判断方法解析
Mar 16 Python
Keras 利用sklearn的ROC-AUC建立评价函数详解
Jun 15 Python
python实现简易名片管理系统
Apr 11 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 多行多列显示
2009/08/15 PHP
个人写的PHP验证码生成类分享
2014/08/21 PHP
PHP实现过滤各种HTML标签
2015/05/17 PHP
Prototype使用指南之string.js
2007/01/10 Javascript
JQuery 中几个类选择器的简单使用介绍
2013/03/14 Javascript
jQuery Animation实现CSS3动画示例介绍
2013/08/14 Javascript
图片Slider 带左右按钮的js示例
2013/08/30 Javascript
js实现收缩菜单效果实例代码
2013/10/30 Javascript
javascript实现动态模态绑定grid过程代码
2014/09/22 Javascript
完美兼容多浏览器的js判断图片路径代码汇总
2015/04/17 Javascript
JQuery插件ajaxfileupload.js异步上传文件实例
2015/05/19 Javascript
详解JavaScript设计模式开发中的桥接模式使用
2016/05/18 Javascript
CSS+jQuery实现简单的折叠菜单
2016/12/20 Javascript
看看“疫苗查询”小程序有温度的代码
2018/07/31 Javascript
微信小程序使用wxParse解析html的方法示例
2019/01/17 Javascript
JS原生瀑布流效果实现
2019/04/26 Javascript
解决Vue打包上线之后部分CSS不生效的问题
2019/11/12 Javascript
koa2的中间件功能及应用示例
2020/03/05 Javascript
vue-cli4项目开启eslint保存时自动格式问题
2020/07/13 Javascript
[47:42]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python基础知识小结之集合
2015/11/25 Python
Python字符串特性及常用字符串方法的简单笔记
2016/01/04 Python
Python获取指定文件夹下的文件名的方法
2018/02/06 Python
Python读取二进制文件代码方法解析
2020/06/22 Python
CSS3实现类似翻书效果的过渡动画的示例代码
2019/09/06 HTML / CSS
CSS3 清除浮动的方法示例
2018/06/01 HTML / CSS
美国的Eastbay旗下的运动款子品牌:Final-Score
2018/01/01 全球购物
搞笑爱情保证书
2014/04/29 职场文书
《中国梦我的梦》小学生演讲稿
2014/08/20 职场文书
教师党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
2014年财务部工作总结
2014/11/11 职场文书
机关单位工作失职检讨书
2014/11/20 职场文书
金陵十三钗观后感
2015/06/04 职场文书
红色影片观后感
2015/06/18 职场文书
幼儿园教师读书笔记
2015/06/29 职场文书
浅谈Redis主从复制以及主从复制原理
2021/05/29 Redis