自动化办公系列1---doc文件内容替换

项目下载github

一、开始之前的准备工作:

环境:操作系统win10,python2.7.15,开发软件为pycharm社区版

问题1:如何在pycharm中切换python版本。

原因:现在有些模块支持的Python版本不一样,所以在开发时经常需要切换版本来开发。

1、点击file->setting

setting设置

2、切换需要的环境

选择Python环境

注意:选择环境前必须安装了对应的python版本,并且添加到环境变量中。


添加到用户环境变量

问题2:如何给不同版本的python导入对应的模块。

导入模块一般两种方式:

1、使用pycharm来导入(推荐)

点击图中+号

搜索想要添加的模块即可

2、使用cmd的pip install xxx 命令方式。

二、开始doc或者docx的替换操作

需求:我需要把文件夹下的所有docx文件即一整套模板,中的某些字符进行替换,然后生成填完后的文件。
参考之前写的:https://www.jianshu.com/p/95bbb29ce3a9

1、创建py文件的时候注意,2.7.15版本默认编码格式不是utf-8,而我们一般操作字符都是以utf-8的方式,故需要添加一些代码把编码格式转为utf-8。python3之后默认格式都是utf-8了。

在文件开头添加如下代码:

#coding=utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

2、操作docx文件需要导入的模块

2.1、python-docx (操作docx文件)
看模块名就知道该模块只能处理docx不能处理doc
2.2、pywin32 (方便Python调用windows的API)

from docx import Document
from docx.shared import Pt #磅数
from docx.oxml.ns import qn #chinese
import os
from win32com import client as wc #导入doc转docx

3、开始编写脚本

#coding=utf-8
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
from docx import Document
from docx.shared import Pt #磅数
from docx.oxml.ns import qn #chinese
import os
from win32com import client as wc #导入doc转docx

#找到文件夹下的所有doxc文件并获得文件名
def file_name(file_dir):
    for root,dirs,files in os.walk(file_dir):
        return files

#遍历刚才找到的所有文件夹然后替换关键字
def change_text(old_text, new_text,document):
    all_paragraphs = document.paragraphs
    for paragraph in all_paragraphs:
        for run in paragraph.runs:
            if old_text in run.text:
                run.text = run.text.replace(old_text, new_text)

    all_tables = document.tables
    for table in all_tables:
        for row in table.rows:
            for cell in row.cells:
                for paragraph in cell.paragraphs:
                    for run in paragraph.runs:
                        if old_text in run.text:
                            run.text = run.text.replace(old_text, new_text)

#把doc文件转为docx文件
def doc_to_docx(file1,file2):
    word = wc.Dispatch("Word.Application") # 打开word应用程序
    doc = word.Documents.Open(file1)       #打开word文件
    doc.SaveAs("{}x".format(file2), 12)    #另存为后缀为".docx"的文件,其中参数12指docx文件
    doc.Close()                            #关闭原来word文件
    word.Quit()
    return "{}x".format(file)              #返回的是一个file对象或者文件名称

#把docx文件转为doc文件
def docx_to_doc(file1,file2):
    word = wc.Dispatch("Word.Application") # 打开word应用程序
    doc = word.Documents.Open(file1)       #打开word文件
    doc.SaveAs("{}".format(file2[:-1]), 0) #另存为后缀为".docx"的文件,其中参数12指docx文件
    doc.Close()                            #关闭原来word文件
    word.Quit()
    return "{}x".format(file)  #返回的是一个file对象或者文件名称

#进行批量替换并生成新文件
#第一个参数传入模板文件夹路径,第二个参数导出结果到某个文件夹路径(请写绝对路径)
def deal_task(importPath,exportPath):
    words = file_name(importPath)   #获取所有文件的文件名
    for words_name in words:
        print words_name            #打印获取的文件名查看是否有错误
        #只有后缀为docx的文件可以继续执行
        if words_name.find('.docx') != -1:
            #PackageNotFoundError,捕获一下该异常
            try:
                document = Document(importPath+'/'+words_name)        #读取当前遍历的文件
                document.styles['Normal'].font.name = u"仿宋_GB2312"
                document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u"仿宋_GB2312")
                document.styles['Normal'].font.size = Pt(12)
                #进行替换操作
                #old_text和new_text都是动态传入
                #遍历entry_list和entry_str来执行动态操作,偶是old奇数是new
                for num in range(0,len(entry_list)-1,2):
                    #输入框任一一栏没有输入内容不会执行替换操作
                    if entry_list[num] != '' and entry_list[num+1] != '':
                        change_text(entry_list[num].strip(),entry_list[num+1].strip(),document)
                        print 'old_text: ' + entry_list[num]
                        print 'new_next: ' + entry_list[num+1]
                document.save(exportPath+"/"+"auto"+words_name)   #默认存储为auto+原文件名的方式
            except Exception as e:
                print '打开docx文件失败'
                print e
    print "完成!"

#进行批量转换并生成转换后的文件到文件夹内
#第一个参数导入的路径,第二个是导出的路径
def docTodocx(importPath,exportPath):
    fileNames = file_name(importPath)  # 获得所有文件名
    # filePath = importPath
    for fileName in fileNames:         # 遍历文件夹下的所有文件
        # 先判断是否有doc然后再判断docx,只要不是doc直接跳过
        # fileName = fileName.decode('gb2312').encode('utf-8')
        if fileName.find('doc') != -1:
            print '进入doc处理循环'
            file1 = importPath + "/" + fileName
            print 'file1:' + file1
            file1 = file1.decode('utf-8').encode('gb2312')
            # print 'gb2312编码的file1: ' + file1
            file2 = exportPath + "/" + fileName
            print 'file2:' + file2
            file2 = file2.decode('utf-8').encode('gb2312')
            doc_to_docx(file1, file2)

#设定自己要替换的数组第一个是old_text,第二个是new_text依次次类推
entry_list = ["X1","2021","X2","2022"]

if __name__ == "__main__":
    #如果模板全是docx只需要调用deal_task()函数就行了,不是的话先调用docTodocx转为docx

    #第一步把doc转为docx
    docTodocx("I:/pythonProject1/docx_operation/importPath","I:/pythonProject1/docx_operation/temporary")
    deal_task("I:/pythonProject1/docx_operation/temporary","I:/pythonProject1/docx_operation/exportPath")

注意:这里docTodocx()和docxTodoc()就是对应doc文件转docx和docx转doc。程序这里只使用docTodocx()函数。

4、使用方式

新建三个文件夹
1exportPath(存放结果)
2importPath(存放模板)
3temporary(存放临时模板如经过转换得到的docx)


文件夹

然后开始执行脚本,即可实现批量替换模板中的文字。如我这里只用两个文件作为演示
展示操作步骤:
1、准备将1.docx和2.docx文件内的X1和X2分别替换成2021和2022


1.docx

2.docx

2、打开脚本进行操作

#设定自己要替换的数组第一个是old_text,第二个是new_text依次次类推
entry_list = ["X1","2021","X2","2022"]

if __name__ == "__main__":
    #如果模板全是docx只需要调用deal_task()函数就行了,不是的话先调用docTodocx转为docx

    #第一步把doc转为docx
    docTodocx("I:/pythonProject1/docx_operation/importPath","I:/pythonProject1/docx_operation/temporary")
    deal_task("I:/pythonProject1/docx_operation/temporary","I:/pythonProject1/docx_operation/exportPath")

注意:把绝对路径中的反斜杠改成斜杆/
3、控制台会显示要替换的内容和替换的内容


显示完成即可.png

4、查看文件是否生成且替换成功


生成

auto1.docx.png

auto2.docx.png

使用的注意事项:

1、复制代码然后安按照规则填入路径在win10,python2.7.15下可正常运行,写之前自己测试过没问题。
2、要替换的字符串必须只能是数字加字母之前文章中也提过。
3、替换的时候必须关闭WPS或者word软件,因为程序运行时候需要打开对应的软件进行操作。
4、文件名或者路径有中文的时候控台会乱码,程序是可以正常执行的。原因是windows中的中文一般编码都是gbk或者gb2312,控制台只能显示utf-8。

注:转载请注明出处
本文如果对你有帮助的话希望能给我点个赞哦~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容