txxcat 发表于 2020-5-28 12:18:43

python在word文档里插入文件对象

本帖最后由 txxcat 于 2020-5-28 12:17 编辑

    工作需要制作每周一次的汇总报表,除了正文以外,还需要把上周的各种报表以附件的方式打包到报表里,有word文档,有excel表格,手工操作是这样的:插入-对象-由文件创建-勾选显示为图标-选择文件-确认,如图:
   
    插入后效果,双击图标可以打开:
   
    看似简单的工作,但是一共有12个文件,目录不全相同,每次选择要选一次目录,费时费力还容易搞错。想用python来解决问题,发现python-docx只能插入图片,不能插入文件对象,在网上泡了几天没能找到方法。
    没办法只好自己动手,我们知道docx实际上是一个压缩文件,解压缩后分析,在word\embeddings找到了这些插入的文件(注意文件名):
   
    那么是否可以替换掉这些文件然后再打包来达到我的目的,经过手工测试后发现行得通,下一步就是写代码了。
    过程就不说了,绕了很多弯,碰了不少壁,现在分享一下心得和代码:
    1.需要先制作word模版文件,要包含插入的文件对象,插入的文件对象可以是空文件,但是对象的文件名不能更改;
    2.根据模版文件写入新word文件;
    3.解压word文件;
    4.替换掉word\embeddings的附件,注意顺序和文件名;
    5.重新压缩还原word文件,这一步需要注意的是压缩格式,python zipfile包默认的格式office不认,要指定格定为DEFLATED。
    下面是3-5步的代码:
    #filename为相关文件列表,filename就是需要处理的主word文件,filename-是12个需要插入的附件
import os,zipfile,shutil       #需要用到的包
azip = zipfile.ZipFile(filename[)          #以压缩格式打开word文件
tempdir=''
while True:
    tempdir= ''.join(random.sample(string.ascii_letters + string.digits, 8))   #生行8位临时文件夹名
    if not os.path.exists(tempdir):
      break
os.mkdir(tempdir)                  #创建临时目录
os.chdir(tempdir)                   #转到临时目录
azip.extractall()                     #解压word文件到临时文件夹
azip.close()                           #关闭word文档,否则后面重新压缩会报错
#把正确文件拷贝覆盖模版文件的空附件
try:
    shutil.copy(filename,'word\\embeddings\\Microsoft_Excel____.xlsx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Excel____1.xlsx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Excel____2.xlsx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Excel____3.xlsx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Excel____4.xlsx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Word___.docx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Word___5.docx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Word___6.docx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Word___7.docx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Word___8.docx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Word___9.docx')
    shutil.copy(filename,'word\\embeddings\\Microsoft_Word___10.docx')
    azip = zipfile.ZipFile(filename, 'w')    #以压缩格式新建word文档
    for i in os.walk('.'):                           #使用os.walk遍历整个目录及子目录,保证原有的目录结构不变
      for j in i:
            azip.write(os.path.join(i,j), compress_type=zipfile.ZIP_DEFLATED)   #将文件逐个打包到word文档中,压缩格式指定为ZIP_DEFLATED
    azip.close()                                       #关闭文件
    os.chdir('..')
    shutil.rmtree(tempdir,ignore_errors=True)    #删除临时文件夹
except:
    pass
    PS:除了word文件,其他的office文档插入的文件对象也可以照这个思路处理。

zwhe 发表于 2020-6-2 10:50:27

{:10_254:}

hanjiang6607 发表于 2020-6-2 11:18:35

高手呀!
页: [1]
查看完整版本: python在word文档里插入文件对象