用Python操控Word

4月底,我带着自己水的一篇文章,从深圳奔赴美帝西雅图参加了一个制药行业软件用户组2018年年会(PharmaSUG 2018)。听了一些报告,收获不少。在众多报告中,有一篇题目为Why SAS Programmers Should Learn Python Too的报告有点意思。不过在我看来,文章中的例子并没有很好地体现出Python的强大,因为那几个例子用Linux Shell脚本实现也很简单。不可否认,如果你想选择一种语言来入门编程,那么Python绝对是首选!但是对于SAS程序猿/媛来说,我觉得现阶段没有太多必要去学Python,因为行业的原因,Python对SAS程序猿/媛日常的编程工作几乎没有什么用。除非你和我一样,喜欢折腾代码,或者你想转行业做深度码农,那Python是必须掌握的语言,因为Python有各种强大的库。下面就让我们来感受下python-docx库的强大之处吧!

我们知道,带项目的SAS程序猿/媛在交项目时候需要准备一个时间戳的文件(假定这个文件是行业都要用到的),用来证明各项工作是有序进行的,如下图(注:因为是公司内部文件,所以单元格内容有做删减):

Checklist

在没有程序实现的情况下,我们每次交项目更新这个文件只能是一个一个地复制和粘贴。虽然要更新的单元格不多,但是手动更新还是有点费时。我能想象到用SAS实现(我不会,囧)肯定要比Python麻烦,所以我就用Python来实现。简单介绍一下用Python实现的思路:首先我们要找出需要更新单元格左边一列的位置。代码如下:

# coding=utf-8

from docx import Document

chklst = Document('C:\\Users\\Xianhua\\Documents\\Python\\Checklist.docx')

table = chklst.tables[2] # 第三个表格

for i in range(1,len(table.rows)): # 限定从表格第二行开始循环读取数据
    for j in range(1,2): # 限定只读取表格第二列数据
        # 输出单元格的位置
        print(i, j)
        # 输出单元格的内容
        print(table.rows[i].cells[j].text)

当然你也可以通过直接打开文档查看来获取位置,比如上图中的第一行第二列的单元格的坐标就是(1,1)。代码执行结果如下图:

Position

然后赋值给所获取位置的右边一列。以下代码有一个前提:即各个时间戳已经被获取并保存在一个TXT文件中(可以通过FILENAME PIPE获取最新时间戳,例子在这里),如下图:

Time

更新时间戳的代码如下:

# coding=utf-8

from docx import Document
import re
from datetime import datetime
from docx.shared import Pt
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

timestamp = open('C:\\Users\\Xianhua\\Documents\\Python\\Checklist.txt', 'r')

# 将TXT转化为字典
mydic = dict() 

for line in timestamp:
    matchObj = re.match( r'(\w+?)\s+(.+)', line)
    if matchObj:
        mydic[matchObj.group(1).rstrip()] = matchObj.group(2)
    
timestamp.close()

chklist = Document('C:\\Users\\Xianhua\\Documents\\Python\\Checklist.docx')

table = chklist.tables[0] # 第一个表格

for i in range(1, len(table.rows)): # 限定从表格第二行开始循环读取数据
    # Transfer date
    if i == 3:
        table.rows[i].cells[2].text = datetime.now().date().strftime('%d %b %Y')

table = chklist.tables[2] # 第三个表格

for i in range(1, 6):
    # Raw data
    if i == 1:
        table.rows[i].cells[2].text = mydic['raw']
        
    # Vendor data
    if i == 2:
        table.rows[i].cells[2].text = mydic['edat']
        
    # Transfer datasets
    if i == 3:
        table.rows[i].cells[2].text = mydic['transfer']
        
    # Logcheck
    if i == 4:
        table.rows[i].cells[2].text = mydic['logcheck']
        
    # Spec and Define
    if i == 5:
        table.rows[i].cells[2].text = mydic['spec'] + '\n' + mydic['define']
        
    # 更改字体 
    run = table.rows[i].cells[2].paragraphs[0].runs
    font = run[0].font
    font.name = 'Courier New'

    # 居中单元格
    table.rows[i].cells[2].paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

chklist.save('C:\\Users\\Xianhua\\Documents\\Python\\Checklist '+ datetime.now().date().strftime('%Y%m%d')+'.docx')

更新后的文件截图如下:

Checklist 20180618

曾宪华 /
本文采用 署名-非商业性使用-相同方式共享 3.0许可协议 属于 程序人生 分类, 被贴了 Python python-docx PharmaSUG PharmaSUG 2018 FILENAME PIPE 书签

上一篇 SAS统计一篇文章中各字母的出现频率
下一篇 Python脚本转exe文件