【转载+自己需求的补充】python实现通配符替换多个word文档中的图片

版权声明:本文为原博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zyc121561/article/details/77879831/
————————————————

摘要:这篇文章介绍了如何使用Python3把PDF文件转换为word文档并替换word文档中的文字内容,这里替换的规则是中英转换或者其它自定义规则。


作者博客地址:http://www.yooongchun.cn/


pdf转换为word

pdf文件由于很难编辑,因而想要通过编程修改内容有些困难【不是不可能,只是代价比较大,特别是要保留原pdf格式的话】,故而这里介绍一个替换pdf文件文字内容的间接解决方案,即:把pdf文件转换为word然后再编程替换word的文字内容,当然替换完成后想把word转为pdf就简单的多了

本文这里转换pdf文件介绍四种方法:

  • 使用第三方工具
  • 使用pdfminer3k 解析pdf然后再把内容写入到word中
  • 使用第三方SDK
  • 使用LibreOffice 开发者库

这里简单说明下几种方法的优劣:

使用第三方工具的话,有这样两种情况:
  • Online版本,大多可以免费使用,但是转换麻烦,不能编程操作,需要手动实现

  • 软件版本,大多可以批量转换,但是大多转换有限制,需付费才能无限制使用,且不能编程处理

    如果上面的情况符合你的实际需要,那再好不过!当然,不能符合的话,接着往下看

使用pdfminer3k解析pdf文件
使用第三方SDK

这个是一个比较好的选择,然而,SDK大多收费!!!这些SDK一般提供完善的开发者API接口,你可以方便而又简单的调用,楼主这里介绍一个叫做easyConvertPDF,他们提供一个pdf2word.py 的API,使用十分简单,转换效果页令人满意,只是,License太贵了,买不起,当然你可以下载试用

使用LibreOffice 开发者库

这个是Micro Office 支持的 Office 开发者库,里面可以实现PDF转换为Word,只是楼主在使用时一致没测试成功,下面给出一段使用代码,你需要先安装LibreOffice 才行

import os
import subprocess

for top, dirs, files in os.walk('/my/pdf/folder'):
    for filename in files:
        if filename.endswith('.pdf'):
            abspath = os.path.join(top, filename)
            subprocess.call('lowriter --invisible --convert-to doc "{}"'
                            .format(abspath), shell=True)

从上面的四种方法中选择一种适合你的方法!

替换word文字内容

  • 替换word使用的是win32com 的包,使用这个包你需要先安装pywin32

    pip install pywin32
    
  • 安装完成后可能会出现如下错误

    ImportError: DLL load failed: win32api, sys, os
    

    这时你可以通过如下方式解决

    C:\Users\yourname\Anaconda3\Lib\site-packages\pypiwin32_system32这个目录下的pythoncom36.dllpywintypes36.dll 拷贝到C:\Users\fanyu\Anaconda3\Lib\site-packages\win32 这个目录下

  • 正常后编写测试程序

import os
import win32com.client

# 处理Word文档的类
class RemoteWord:
    def __init__(self, filename=None):
        self.xlApp=win32com.client.DispatchEx('Word.Application')
        self.xlApp.Visible=0
        self.xlApp.DisplayAlerts=0    #后台运行,不显示,不警告
        if filename:
            self.filename=filename
            if os.path.exists(self.filename):
                self.doc=self.xlApp.Documents.Open(filename)
            else:
                self.doc = self.xlApp.Documents.Add()    #创建新的文档
                self.doc.SaveAs(filename)
        else:
            self.doc=self.xlApp.Documents.Add()
            self.filename=''

    def add_doc_end(self, string):
        '''在文档末尾添加内容'''
        rangee = self.doc.Range()
        rangee.InsertAfter('\n'+string)

    def add_doc_start(self, string):
        '''在文档开头添加内容'''
        rangee = self.doc.Range(0, 0)
        rangee.InsertBefore(string+'\n')

    def insert_doc(self, insertPos, string):
        '''在文档insertPos位置添加内容'''
        rangee = self.doc.Range(0, insertPos)
        if (insertPos == 0):
            rangee.InsertAfter(string)
        else:
            rangee.InsertAfter('\n'+string)

    def replace_doc(self,string,new_string):
        '''替换文字'''
        self.xlApp.Selection.Find.ClearFormatting()
        self.xlApp.Selection.Find.Replacement.ClearFormatting()
        self.xlApp.Selection.Find.Execute(string, False, False, False, False, False, True, 1, True, new_string, 2)

    def save(self):
        '''保存文档'''
        self.doc.Save()

    def save_as(self, filename):
        '''文档另存为'''
        self.doc.SaveAs(filename)

    def close(self):
        '''保存文件、关闭文件'''
        self.save()
        self.xlApp.Documents.Close()
        self.xlApp.Quit()

if __name__ == '__main__':
   doc = RemoteWord(docx)  # 初始化一个doc对象
   # 这里演示替换内容,其他功能自己按照上面类的功能按需使用
   doc.replace_doc('your string','new string')  # 替换文本内容
   doc.close()


好了以上就完成了从pdf到word的完整内容,这里楼主附上一个实例:

楼主需要把pdf文件报表的英文内容替换为中文,也就是等价于翻译,只是翻译是提前做好的,放置在一个match_rule.xlsx的文件中 ,这个文件内容就是两列:原文 译文,然后程序会读取内容并自动替换。

下面楼主给出代码:

# 该程序实现把PDF转换为word然后读取word文件中的文字内容并按照特定的规则替换文字

# -*- encoding: utf8 -*-

__author__ = 'yooongchun'

# 引入所需要的基本包
import os
import re
import xlrd
import win32com.client
import logging
logging.basicConfig(level=logging.INFO)


# 处理Word文档的类
class RemoteWord:
    def __init__(self, filename=None):
        self.xlApp=win32com.client.DispatchEx('Word.Application')
        self.xlApp.Visible=0
        self.xlApp.DisplayAlerts=0    #后台运行,不显示,不警告
        if filename:
            self.filename=filename
            if os.path.exists(self.filename):
                self.doc=self.xlApp.Documents.Open(filename)
            else:
                self.doc = self.xlApp.Documents.Add()    #创建新的文档
                self.doc.SaveAs(filename)
        else:
            self.doc=self.xlApp.Documents.Add()
            self.filename=''

    def add_doc_end(self, string):
        '''在文档末尾添加内容'''
        rangee = self.doc.Range()
        rangee.InsertAfter('\n'+string)

    def add_doc_start(self, string):
        '''在文档开头添加内容'''
        rangee = self.doc.Range(0, 0)
        rangee.InsertBefore(string+'\n')

    def insert_doc(self, insertPos, string):
        '''在文档insertPos位置添加内容'''
        rangee = self.doc.Range(0, insertPos)
        if (insertPos == 0):
            rangee.InsertAfter(string)
        else:
            rangee.InsertAfter('\n'+string)

    def replace_doc(self,string,new_string):
        '''替换文字'''
        self.xlApp.Selection.Find.ClearFormatting()
        self.xlApp.Selection.Find.Replacement.ClearFormatting()
        self.xlApp.Selection.Find.Execute(string, False, False, False, False, False, True, 1, True, new_string, 2)

    def save(self):
        '''保存文档'''
        self.doc.Save()

    def save_as(self, filename):
        '''文档另存为'''
        self.doc.SaveAs(filename)

    def close(self):
        '''保存文件、关闭文件'''
        self.save()
        self.xlApp.Documents.Close()
        self.xlApp.Quit()


# 遍历找到word文件路径
def find_docx(pdf_path):
    file_list=[]
    if os.path.isfile(pdf_path):
        file_list.append(pdf_path)
    else:
        for top, dirs, files in os.walk(pdf_path):
            for filename in files:
                if filename.endswith('.docx')or filename.endswith('.doc'):
                    abspath = os.path.join(top, filename)
                    file_list.append(abspath)
    return file_list


# 替换文本内容
def replace_docx(rule,docx_list):
    len_doc=len(docx_list)
    i=0  # 计数
    for docx in docx_list:
        i+=1
        logging.info('开始替换第 %s/%s 个word文件内容:%s...'%(i,len_doc,os.path.basename(docx)))
        doc = RemoteWord(docx)  # 初始化一个doc对象
        for item in rule:  # 替换
            doc.replace_doc(item[0], item[1])
        doc.close()

    logging.info('完成!')


# 对内容进行排序
# 这里因为在进行文本替换的时候涉及到一个长句里面的部分可能被短句(相同内容)内容替换掉
# 因而必须先把文本按照从长到短的顺序来进行替换
def sort_rule(rule):
    result=[]
    for item, val in rule.items():
        le=len(item)
        flag = True
        if len(result)>0:
            for index, res in enumerate(result):
                if len(item) >= len(res[0]):
                    flag=False
                    result.insert(index, (item, val))
                    break
            if flag:
                result.append((item, val))

        else:
            result.append((item,val))

    return result


# 加载Excel,把取得的内容返回,格式:dict{'原文':'译文'}
def init_excel(excel_path):
    logging.info('加载文本匹配规则的Excel:%s' % os.path.basename(excel_path))
    rule={}  # 储存原文和翻译内容
    pdf_path=''
    try:
        book = xlrd.open_workbook(excel_path)  # 打开一个wordbook
        sheet = book.sheet_by_name('Translation')  # 切换sheet
        rows = sheet.nrows  # 行数
        for row in range(rows - 1):
            text_ori=sheet.cell(row, 0).value  # 取得数据:原文
            text_trans=sheet.cell(row,1).value  # 取得数据:译文
            if not re.match(r'^#.+',text_ori):  # 原文不以#开头
                if text_ori == 'pdf文件(或文件夹)地址':   # 获得pdf文件路径
                    pdf_path=text_trans
                else:
                    rule[text_ori]=text_trans  # 取得值加入text
    except IOError:
        raise IOError
    logging.info('加载Excel完成!')

    return pdf_path, rule

if __name__ == '__main__':

    excel_path = './match_rule.xlsx'    # 替换规则的Excel文件地址
    logging.info('正在打开pdf转换软件,请手动转换你的pdf文件!')
    os.popen(r'"./PDF2Word/pdf2word.exe"')
    flag=input('你已经完成pdf文件转换了吗?(y/n):')
    while not flag == 'y':
        logging.info('请先转换pdf!')
        flag = input('你已经完成pdf文件转换了吗?(y/n):')
    pdf_path, rule = init_excel(excel_path)  # 加载Excel,取得内容
    sorted_rule=sort_rule(rule)  # 排序规则:按照由长到短
    docx_list=find_docx(pdf_path)  # 获取docx文件路径
    replace_docx(sorted_rule,docx_list)  # 替换内容

    logging.info('程序执行完成!')


项目github地址:https://github.com/yooongchun/Python_transPDF


以上是原博主的实现,我需要的是其中打开word文件替换指定部分的功能
需求:需要将大量单个word文件中的图片和双回车(空行)去掉,节省打印成本((lll¬ω¬)

import os
path = input('enter path')  
#输入文件所在的文件夹地址,需要注意其中只能有需要处理的文件,不能有文件夹或其他文件

lists = []  #创建一个列表来存放各个文件的地址
for filename in os.listdir(path):  
    item = os.path.join(path,filename) #通过这一步来得到绝对地址,如果不获取绝对地址的话,通过上面原博主的代码无法找到文件,因为上面代码默认在C:/System32初始化文件
    lists.append(item)
   	#最后得到的lists就是文件夹

最后我直接用的代码如下,没有另存文件,是直接修改源文件,建议替换前备份:

import os
import win32com.client


# 处理Word文档的类

class RemoteWord:
    def __init__(self, filename=None):
        self.xlApp = win32com.client.DispatchEx('Word.Application')
        self.xlApp.Visible = 0
        self.xlApp.DisplayAlerts = 0  # 后台运行,不显示,不警告
        if filename:
            self.filename = filename
            if os.path.exists(self.filename):
                self.doc = self.xlApp.Documents.Open(filename)
            else:
                self.doc = self.xlApp.Documents.Add()  # 创建新的文档
                self.doc.SaveAs(filename)
        else:
            self.doc = self.xlApp.Documents.Add()
            self.filename = ''

    def add_doc_end(self, string):
        '''在文档末尾添加内容'''
        rangee = self.doc.Range()
        rangee.InsertAfter('\n' + string)

    def add_doc_start(self, string):
        '''在文档开头添加内容'''
        rangee = self.doc.Range(0, 0)
        rangee.InsertBefore(string + '\n')

    def insert_doc(self, insertPos, string):
        '''在文档insertPos位置添加内容'''
        rangee = self.doc.Range(0, insertPos)
        if (insertPos == 0):
            rangee.InsertAfter(string)
        else:
            rangee.InsertAfter('\n' + string)

    def replace_doc(self, string, new_string):
        '''替换文字'''
        self.xlApp.Selection.Find.ClearFormatting()
        self.xlApp.Selection.Find.Replacement.ClearFormatting()
        self.xlApp.Selection.Find.Execute(string, False, False, False, False, False, True, 1, True, new_string, 2)

    def save(self):
        '''保存文档'''
        self.doc.Save()

    def save_as(self, filename):
        '''文档另存为'''
        self.doc.SaveAs(filename)

    def close(self):
        '''保存文件、关闭文件'''
        self.save()
        self.xlApp.Documents.Close()
        self.xlApp.Quit()

#版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
#本文链接:https://blog.csdn.net/zyc121561/article/details/77879831/


path = input('dizhi')
lists = []
for filename in os.listdir(path):
    item = os.path.join(path,filename)
    lists.append(item)
for file in lists:
    if __name__ == '__main__':
        doc = RemoteWord(file)  # 初始化一个doc对象
        # 这里演示替换内容,其他功能自己按照上面类的功能按需使用
        doc.replace_doc('^g', 'new string')  # 替换文本内容
        doc.replace_doc('^p^p', 'new string')
        doc.close()
        print(file)  #提示已经处理好的文件
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值