今天使用python的Zipfile模块巧妙地解决word批处理生成问题,我可以参考两个方案。
案例1:使用读取word文件
场景2: zipfile熟练地解决word文档
平台:windows10
解释程序:
工作要求
包含大象数据的现有excel文档必须用指定的word替换其中每一行数据的相应内容,并逐个存储。
任务解散了
首先查看word文档格式,文件后缀为。可以看出是doc,正文部分红色框的英文部分需要更换。
大象数据将excel文档、excel中相应列下的数据替换为word文档。
excel数据比较规则不需要辅助处理,如果列名与word文档不对应或不存在,则必须调整或添加。这样,您只需考虑如何读取doc文件,并用一定的逻辑替换它。
工作方案
方案一:使用读取word文档
这次要求之前,我没有使用过python操作word文档。感谢交流群内大佬们的帮助,在python excel wood上每秒制作100份合同文章中,按照pace编写代码,但在执行时报告有误,目标字符串没有被替换。
问题1:模块安装错误,句子中有import docx,我误以为是pip install docx,调用Document类时发现模块下没有相应的类,然后进行百度,pip install python-docx,I
问题2: python-docx模块不能操作doc文档。如上所述,此次处理的word文档是doc后缀,因此必须转换为docx后缀才能正常工作。事实上,一个文档可以通过word软件存储,但在python编程中不优雅。主要是我太懒,最多。
问题3: Python Excel Word每秒签订了100份合同。这篇文章中,某些文本段正在被替换。在第一次尝试中,发现更换没有成功,而是逐步执行代码来寻找问题。可以想象Document将整个word文档分成多个paragraphs。一个paragraphs有很多行,每行有多个文本块。由于每行文本块的区分不太好理解,以汉英输入法输入的中文/英文可能会导致一个单词分离,或者相应的word文档包含特定格式,因此单词不分离,尝试替换内容,文本可以成功替换,但下划线格式被丢弃,只能用文本块下的text方法替换。在原始word文件中,使用相同的输入法(与excel中的列名相对应)输入英语。确保字符串不出现在word中的其他地方。换句话说,中文也可以。推荐的写法。
逐一解决上述问题后,输入大象文件路径和输入路径即可。源代码:
From copy import deepcopy
From pathlib import Path
from win32 com import client as WC # pip install pypi win32
from docx import document # pip install python-docx
Import pandas as PD
# python-docx无法处理doc文档,并使用win32com将其导出为docx文档
def doc transform 2 docx(doc _ path):
Docx_path=doc_path 'x '
Suffix=doc_(' . '))[1]
Assert 'doc' in suffix,'进入的不是word文档。请重新输入!’
If suffix=='docx':
Return文档(doc _ path)
word=WC . dispatch(' word . application ')
Doc=word。Documen(doc_path)
Doc。SaveAs2(docx_path,16) # docx为16
d
oc.Closeword.Quit
return Document(docx_path)
# 替换docx中的特定字符,由于run方法在有格式的docx文件中展示效果很差,故将docx中的文本的需要填充出英文字符占位
def replace_docx(name, values, wordfile, path_name='Company'):
wordfile_copy = deepcopy(wordfile) # 防止原文件被篡改,deepcopy为副本
for col_name, value in zip(name, values):
if col_name == 'Company':
path_name = str(value)
for paragraphs in word:
for run in :
run.text = run.(col_name, str(value))
# docx文档替换完毕,另存为,一定要用绝对路径
word(f'{save_folder}/{path_name}.docx')
if __name__ == '__main__':
# 定义需处理的文件路径
doc_path = r"D:\solve_path\单位.doc"
excel_path = r"D:\solve_path\信息.xls"
save_folder = Path('D:/docx_save')
(parents=True, exist_ok=True) # 文件夹没有时自动创建
# 获取excel数据
data = (excel_path)
wordfile = doctransform2docx(doc_path)
data_save = da(lambda x: replace_docx, x.values, wordfile), axis=1)
在我以为大功告成之际,问题来了,原文档中的方框没了(漏!!!) 效果图:
解决了格式却解决不了特殊字符问题,秃了啊……,我想python-docx中一定有相应的解决方案,但是我初次尝试,对其中源码部分犹如天书般的存在,在多次调用方法下发现其中的一个参数输出,word:
输出内容让我想起了之前解密excel时看到的文件开头,xml文件,然后首先尝试替换其中文本,原以为会像run.text = run.(col_name, str(value))一样即可,然而报错了,禁止修改。
方案二:zipfile巧解word文档
正当我认为别无他法时,就此作罢时,百度百科帮助了我:
docx文档本质上就是xml文件,emmmm,很妙,之前为了提取xlsx中的图片解压缩过xlsx文件然后提取,果然可行,替换的主体文件就是word文件夹下的document.xml文件
当然在代码编写前首先尝试能不能手动复原为docx,用7z默认参数还原失败,经过多番寻找,用zip类型压缩即可,软件不限,手动解压及替换字符压缩均成功,开始敲代码。除习惯性用pandas读取excel文件外,也不用安装其他包,在现用中均为内置包。使用zipfile对压缩类文件进行解压,文章学习来源:
python中如何压缩和解压缩文件
文章中写得很详细,我仅把os.path改写成pathlib。但在对目录下文件进行压缩还原至docx文档时出现了问题:
问题一:文章中的压缩文件为 zi,对遍历后的所有文件进行压缩至一个目录下,这就出现了还原后的docx内的文件层次不对应,docx读取失败。改用zi方可成功按层次压缩。
问题二:zipfile压缩文件保存时,应当有文件名及其别名,且别名不能为绝对路径,为了能正常还原也应使用原有名称,在代码中为f.write(文件路径, 文件路径别名)
源码:
from shutil import rmtree
import zipfile
from copy import deepcopy
from pathlib import Path
from win32com import client as wc # pip install pypiwin32
import pandas as pd
# doc文档不包含所需xml文件,使用win32com转存为docx文档
def doctransform2docx(doc_path):
docx_path = doc_path + 'x'
suffix = doc_('.')[1]
assert 'doc' in suffix, '传入的不是word文档,请重新输入!'
if suffix == 'docx':
return Path(doc_path)
word = wc.Dispatch('Word.Application')
doc = word.Documen(doc_path)
doc.SaveAs2(docx_path, 16) # docx为16
doc.Close
word.Quit
return Path(docx_path)
# docx文档解压
def docx_unzip(docx_path):
docx_path = Path(docx_path) if isinstance(docx_path, str) else docx_path
upzip_path = docx_)
with zi(docx_path, 'r') as f:
for file in f.namelist:
f.extract(file, path=upzip_path)
xml_path = u('word;)
with xml_(encoding='utf-8') as f:
xml_file = f.read
return upzip_path, xml_path, xml_file
# 讲文件夹中的所有文件压缩成docx文档
def docx_zipped(docx_path, zipped_path):
docx_path = Path(docx_path) if isinstance(docx_path, str) else docx_path
with zi(zipped_path, 'w', zi) as f:
for file in docx_('**/*.*'):
f.write(file, + '/', ''))
# 删除生成的解压文件夹
def remove_folder(path):
path = Path(path) if isinstance(path, str) else path
if :
rmtree(path)
else:
raise "系统找不到指定的文件"
# 替换docx中的特定字符,重新保存document.xml至需要压缩的目录下
def replace_docx(name, values, xml_file, xml_path, unzip_path, path_name='Company'):
xml_path = Path(xml_path) if isinstance(xml_path, str) else xml_path
xml_file_copy = deepcopy(xml_file) # 深复制xml内容
for col_name, value in zip(name, values):
if col_name == 'Company':
path_name = str(value)
xml_file_copy = xml_(col_name, str(value))
with xml_(mode='w', encoding='utf-8') as f:
f.write(xml_file_copy)
# xml文档替换完毕,通过zipfile重新压缩另存为docx文档
docx_zipped(unzip_path, f'{save_folder}/{path_name}.docx')
if __name__ == '__main__':
# 定义需处理的文件路径
doc_path = r"D:\solve_path\单位.doc"
excel_path = r"D:\solve_path\信息.xls"
save_folder = Path('D:/docx_save')
(parents=True, exist_ok=True) # 文件夹没有时自动创建
# 获取excel数据
data = (excel_path)
docx_path = doctransform2docx(doc_path)
unzip_path, xml_path, xml_file = docx_unzip(docx_path)
data_save = da(lambda x: replace_docx, x.values, xml_file, xml_path, unzip_path), axis=1)
remove_folder(unzip_path)
打开生成的文件,方框没有消失,下划线也在。
总结
经过几番尝试后,也是我的学识不深,在跌跌撞撞中找到一种既能替换docx中的字符串也不会改变原有格式的方案,相信一定会有更好的方案,只是此时我没有找到,时间是不停地向前的,我也不应落下,以求共同富贵。如对此有疑问欢迎评论区留言。
PS: 如果电脑安装的是WPS,可以尝试手动转换doc格式为docx格式,再进行批量操作。
于二零二一年十一月二十八日作
版权声明:本文为CSDN博主「宿者朽命」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:
1.《【文件zip格式怎么转word】我将携手教您如何使用python的zipfile模块解决word批处理生成问题。》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《【文件zip格式怎么转word】我将携手教您如何使用python的zipfile模块解决word批处理生成问题。》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/keji/2541339.html