今天替老婆做一个小小的功能:

需求是这样的,她在银行对一个检查事项需要出具几份文档,例如《报告A》,《报告B》,《报告C》等。

但是这几份报告里面其实很多内容是重复的,例如人名,或者一些评价等等若干信息。

她希望可以不重复输入这些东西,而制作一些模板,来批量完成这项工作。这样对于大量的检查来说可以省掉不少工作量。

我隐约记得 word 里面有一插入域的功能,通过不同的 word 模板里面插入一些域作为钩子,然后引用到一个 access 文件,这样来进行批量的更新,但是由于其实我还是不太懂 word,于是浅尝辄止。

然后正好 python 的 office api 也是很快需要派上用场的,而且 python 都比较容易绿化所以干脆就写一个 python 的替换器吧。

简单的设想是这样的,做一个配置文件 conf.xlsx:

模板文件

输出目录

替换字段

替换内容

form1.docx

out

a

a for aster

form2.docx

b

b for bullets

c

c for ceasar

d

d for demon

稍微简单解释一下:

第一列是模板的文件,可以是若干个 word 文件,通过相对路径或者绝对路径指定。word 文件里面可以填写若干个 {{替换字段}} 这样的标签用于匹配替换。

第二列是输出目录,替换之后的文件将会被输出到指定的目录另存,也可以接受相对目录或者绝对路径的目录。

第三第四列是替换的字典,key 是第三列“替换字段”,value 第四列是替换内容。然后对于所有的模板文件中的 {{key}} 将会被全部替换成 value。

这样用起来已经可以省掉相当多的工作了,下面是实施这个脚本。

首先是找一个恰当的 python office api,以前没搞过,但是一下子就找到一个合适的了:

下载合适的版本进行安装,然后具体的使用可以 import win32com 这个包。

为了简化操作,我还在百度文库找到了一个简易版 word 封装:

# easyword.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import win32com.client

import os

#--------------------------------------------------------------------------

class easyWord:

'''

Some convenience methods for Excel documents accessed

through COM.

'''

def __init__(self,visible=False):

self.wdApp = win32com.client.DispatchEx('Word.Application')

self.wdApp.Visible = visible

self.wdApp.DisplayAlerts = False

def new(self,filename=None):

'''

Create a new Word document. If 'filename' specified,

use the file as a template.

'''

if filename:

return self.wdApp.Documents.Add(filename)

else:

return self.wdApp.Documents.Add()

def open(self,filename):

'''

Open an existing Word document for editing.

'''

return self.wdApp.Documents.Open(filename)

def visible(self,visible=True):

self.wdApp.Visible = visible

def find(self,text,MatchWildcards=False):

'''

Find the string

'''

find = self.wdApp.Selection.Find

find.ClearFormatting()

find.Execute(text, False, False, MatchWildcards, False, False, True, 0)

return self.wdApp.Selection.Text

def replaceAll(self,oldStr,newStr):

'''

Find the oldStr and replace with the newStr.

'''

find = self.wdApp.Selection.Find

find.ClearFormatting()

find.Replacement.ClearFormatting()

find.Execute(oldStr, False, False, False, False, False, True, 1, True, newStr, 2)

def updateToc(self):

for tocitem in self.wdApp.ActiveDocument.TablesOfContents:

tocitem.Update()

def save(self):

'''

Save the active document

'''

self.wdApp.ActiveDocument.Save()

def saveAs(self,filename,delete_existing=True):

'''

Save the active document as a different filename.

If 'delete_existing' is specified and the file already

exists, it will be deleted before saving.

'''

if delete_existing and os.path.exists(filename):

os.remove(filename)

self.wdApp.ActiveDocument.SaveAs(FileName=filename)

def close(self):

'''

Close the active workbook.

'''

self.wdApp.ActiveDocument.Close()

def quit(self):

'''

Quit Word

'''

return self.wdApp.Quit()

这个作为一个模块,我们通过 from easyword import easyWord 即可导入这个类,这下就简单了。

然后实现一个方法 replaceWord:

# replace.py

import os

from easyword import easyWord

def replaceWord(data, tmpl_path=[], export_path=['export']):

for path in tmpl_path:

path = os.path.relpath(path)

if os.path.exists(path):

w = easyWord()

w.open(os.path.abspath(path))

print('打开:%s' % os.path.abspath(path))

for k in data:

w.replaceAll('{{%s}}'%k, data[k])

for ex in export_path:

ex = os.path.join(os.path.abspath(ex), path)

if not os.path.exists(os.path.dirname(ex)):

os.makedirs(os.path.dirname(ex))

print('输出:%s' % ex)

w.saveAs(ex)

w.close()

w.quit()

然后我们调用 replaceWord 函数:

data 是替换的字典 {'替换字段': '替换内容', ...}

tmpl_path 是模板文件的列表(支持相对或者绝对路径)

export_path 是输出目录的路径

举个例子:

replaceWord(

{

'a':'a for apple',

'b':'b for bullets',

'c':'c for ceaser',

'd': 'd for damn',

'e': 'e for eclipse',

},

(

'form1.docx',

'form2.docx',

),

(

'a/a',

'b/b',

)

)

这样调用就可以实现一个批量操作。

好了,最后一步,我们需要从指定的 conf.xlsx 来读取这些参数并且按照参数执行这个过程。

同样,在百度轻易找到了一个建议封装的 Excel 类库:

# easyexcel.py

#!/usr/bin/env python

# -*- coding: utf-8 -*-

from win32com.client import Dispatch

import win32com.client

class easyExcel:

"""A utility to make it easier to get at Excel. Remembering

to save the data is your problem, as is error handling.

Operates on one workbook at a time."""

def __init__(self, filename=None):

self.xlApp = win32com.client.DispatchEx('Excel.Application')

if filename:

self.filename = filename

self.xlBook = self.xlApp.Workbooks.Open(filename)

else:

self.xlBook = self.xlApp.Workbooks.Add()

self.filename = ''

def save(self, newfilename=None):

if newfilename:

self.filename = newfilename

self.xlBook.SaveAs(newfilename)

else:

self.xlBook.Save()

def close(self):

self.xlBook.Close(SaveChanges=0)

del self.xlApp

def getCell(self, sheet, row, col):

"Get value of one cell"

sht = self.xlBook.Worksheets(sheet)

return sht.Cells(row, col).Value

def setCell(self, sheet, row, col, value):

"set value of one cell"

sht = self.xlBook.Worksheets(sheet)

sht.Cells(row, col).Value = value

def getRange(self, sheet, row1, col1, row2, col2):

"return a 2d array (i.e. tuple of tuples)"

sht = self.xlBook.Worksheets(sheet)

return sht.Range(sht.Cells(row1, col1), sht.Cells(row2, col2)).Value

def addPicture(self, sheet, pictureName, Left, Top, Width, Height):

"Insert a picture in sheet"

sht = self.xlBook.Worksheets(sheet)

sht.Shapes.AddPicture(pictureName, 1, 1, Left, Top, Width, Height)

def cpSheet(self, before):

"copy sheet"

shts = self.xlBook.Worksheets

shts(1).Copy(None,shts(1))

于是我们可以通过如下方式获取到配置(在 replace.py 的后面加上这一段代码,然后就可以直接跑出结果来了):

# replace.py

from easyexcel import easyExcel

x = easyExcel(os.path.abspath('conf.xlsx'))

tmpl_path = []

while x.getCell('sheet1', len(tmpl_path)+2, 1):

tmpl_path.append(x.getCell('sheet1', len(tmpl_path)+2, 1))

export_path = []

while x.getCell('sheet1', len(export_path)+2, 2):

export_path.append(x.getCell('sheet1', len(export_path)+2, 2))

if not export_path:

export_path = ['export']

data = {}

while x.getCell('sheet1', len(data)+2, 3):

data[x.getCell('sheet1', len(data)+2, 3)] = x.getCell('sheet1', len(data)+2, 4)

x.close()

replaceWord(data, tmpl_path, export_path)

【转载请附】愿以此功德,回向 >&gt

python案例实操_Python 操作 Word 案例相关推荐

  1. python docx 字体大小_Python操作Word的入门教程

    Python操作Word的入门教程 前言 今天来介绍下,如何用 Python 来操作 Word. 再来介绍操作 Word 之前,先来说一个最近看书学到的法则,即 3W 法则. 3W:3W分别指 Wha ...

  2. Azkaban配置Work Flow案例实操

    Work Flow案例实操 目录 Work Flow案例实操 1. Yarm语法简介 2. HelloWorld案例 3. JavaProcess案例 4. 作业依赖案例 5. 自动失败重试案例 6. ...

  3. MapReduce入门(一)—— MapReduce概述 + WordCount案例实操

    MapReduce入门(一)-- MapReduce概述 文章目录 MapReduce入门(一)-- MapReduce概述 1.1 MapReduce 定义 1.2 MapReduce 优缺点 1. ...

  4. 尚硅谷大数据技术Spark教程-笔记09【SparkStreaming(概念、入门、DStream入门、案例实操、总结)】

    尚硅谷大数据技术-教程-学习路线-笔记汇总表[课程资料下载] 视频地址:尚硅谷大数据Spark教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据技术Spark教程-笔记01[SparkCore ...

  5. Spark转换算子大全以及案例实操

    1.RDD 转换算子 RDD转换算子实际上就是换了名称的RDD方法 RDD 根据数据处理方式的不同将算子整体上分为 Value 类型.双 Value 类型和 Key-Value 类型 算子:Opera ...

  6. 数据模型同学看过来|代码案例实操来袭

    去年年底,央行开出反洗钱罚单,多家银行合计被罚1040万元. 当时,中国人民银行石家庄中心支行披露的反洗钱行政处罚信息公示表显示,因涉及未按照规定履行客户身份识别义务等,中行.邮储.浦发三家银行以及阳 ...

  7. 【李刚-21天通关Python-27】之 案例实操:函数装饰器应用

    [李刚-21天通关Python-27]之 案例实操:函数装饰器应用 一.函数装饰器的广泛应用 @staticmethod 和 @classmethod 的本质就是函数装饰器 staticmethod ...

  8. Arduino案例实操 -- 语音播放模块(DY-SV5W)

    案例主控板如不做特殊说明的话,均默认是Arduino UNO控制板. 本次实验以UNO发送串口协议控制语音播放器播放歌曲,语音播放模块选型DY-SV5W. 文章标题导航 一.硬件选择 1. Ardui ...

  9. 51单片机案例实操 -- 倒车雷达

    结合前面学习的流水灯.蜂鸣器.外部中断.超声波和OLED显示,实现51单片机平台的倒车雷达案例 51单片机倒车雷达案例实操 1. 倒车雷达 2. 功能模块回顾 2.1 流水灯 2.2 蜂鸣器多频率 2 ...

  10. 2. WordCount案例实操

    文章目录 WordCount案例实操 1. 官方WordCount源码 2. 常用数据序列化类型 3. MapReduce编程规范 3.1 Mapper阶段 3.2 Reducer阶段 3.3 Dri ...

最新文章

  1. Spring Cloud应用开发(五:API网关服务)
  2. 【讨论】基于WF的流程结构
  3. 缓存伪静态html,伪静态缓存(整站静态化)
  4. Elicpse创建Maven项目
  5. Java虚拟机的功能
  6. apt的通讯信道是如何发现的?
  7. Android 添加 *.arr
  8. 傅里叶变换处理sar图像_SAR和ISAR雷达的基础知识
  9. Java知多少(24)包装类、拆箱和装箱详解
  10. sqlalchemy in查询优化_SQL高级:代码实战 SQL 单表优化
  11. Vscode 如何使用内置浏览器?
  12. 数组中第三大的数 leetcode 414
  13. 软件自动化测试脚本如何编写,编写自动化测试脚本的几点注意事项
  14. GNSS螺旋天线高精度定位
  15. 求出数组最大值的方法
  16. 【算法】1282. 用户分组(多语言实现)
  17. Think twice, code once.
  18. 一个商品SKU是怎么生成的 1
  19. 单片机 c语言 可控硅,单片机控制可控硅.doc
  20. 1905 杨辉三角

热门文章

  1. 乌镇互联网大会:马化腾强势宣布,明年将推“VR微信”
  2. php composer 安装报错 Package fxp/composer-asset-plugin has a PHP requirement incompatible with your PHP
  3. Computer OpenCart 自适应主题模板 ABC-0084
  4. 腾讯地图路线规划 vue
  5. Keys配置及使用说明
  6. 博客园申请开通博客时理由应该怎么写才能通过?
  7. su - root 切换失败
  8. 多个category实现同一个方法调用的顺序
  9. 什么是存储引擎以及不同存储引擎特点
  10. 安卓手机变鼠标图文教程