PDF操作

#encoding=utf-8
'''
Created on 2019年11月14日

@author: 瞌睡蟲子
'''
import fitz, os, re
import PyPDF2

def GetPagePic(pdfName,password=None,savePath=None, pageStart="begin", pageEnd="end"): 
    '''
    `提取PDF    
    `文件名    需要提取图像的PDF文件名
    `文件密码    PDF文件密码,如果没有密码则为null
    `保存文件名    提取后的文件名
    `页面范围    数组形式,[开始页,结束页],其中"begin"代表第一页,"end"代表最后一页,可以有如下形式["begin",9] 或者 ["begine","end"]
    '''
    # 打开pdf
    doc = fitz.open(pdfName);
    if password is not None:
        doc.authenticate(password);
    # 图片数
    pic_count=0;
    # 默认存pdf目录
    if not savePath:
        savePath = os.path.dirname(pdfName);
    # 文件名
    filName = os.path.basename(pdfName);
    filName = filName.split(".")[0];
    pageSize = [pageStart,pageEnd];
    pageSize=HandlePageSize(pageSize, doc.pageCount);
    for pg in pageSize:
        imglist = doc.getPageImageList(pg);
        for i in imglist:
            pic_count+=1;
            pix = fitz.Pixmap(doc, i[0]);
            fitz.Pixmap(fitz.csRGB, pix).writeImage("%s\%s_%d_%d.%s" % (savePath, filName,(pg+1), pic_count, "png"));
    doc.close();

def GetAllPic(pdfName,password=None,savePath=None,picType="png"):
    '''
    `提取文件中的图像    
    `文件名    需要提取图像的PDF文件名
    `文件密码    PDF文件密码,如果没有密码则为null
    `保存路径    保存图片的路径,图片按照PDF文件名_序号的形式保存
    `保存类型    保存图片文件的类型,支持PNG、JPG、BMP
    '''
    # 打开pdf
    doc = fitz.open(pdfName);
    if password is not None:
        doc.authenticate(password);
    # 图片数
    pic_count=0;
    # 默认存pdf目录
    if not savePath:
        savePath = os.path.dirname(pdfName);
    # 文件名
    filName = os.path.basename(pdfName);
    filName = filName.split(".")[0];
#     pageSize=HandlePageSize(pageSize, doc.pageCount);
    for pg in range(doc.pageCount):
        imglist = doc.getPageImageList(pg);
        for i in imglist:
            pic_count+=1;
            pix = fitz.Pixmap(doc, i[0]);
            fitz.Pixmap(fitz.csRGB, pix).writeImage("%s\%s_%d.%s" % (savePath, filName, pic_count, picType));
    doc.close();
    
    
    # 使用正则表达式来查找图片
    checkXO = r"/Type(?= */XObject)" 
    checkIM = r"/Subtype(?= */Image)"  
    
    # 打开pdf
    doc = fitz.open(pdfName);
    if password is not None:
        doc.authenticate(password);
    # 对象数
    lenXREF = doc._getXrefLength();
    # 图片数
    pic_count=0;
    # 默认存pdf目录
    if not savePath:
        savePath = os.path.dirname(pdfName);
    # 文件名
    filName = os.path.basename(pdfName);
    filName = filName.split(".")[0];
    
    # 遍历每一个对象
    for i in range(1, lenXREF):
        # 定义对象字符串
        text = doc._getXrefString(i);
        isXObject = re.search(checkXO, text);
        # 使用正则表达式查看是否是图片
        isImage = re.search(checkIM, text);
 
        # 如果不是对象也不是图片,则continue
        if not isXObject or not isImage:
            continue;
        pic_count += 1;
        # 根据索引生成图像
        pix = fitz.Pixmap(doc, i);
        # 根据pdf的路径生成图片的名称        
        fitz.Pixmap(fitz.csRGB, pix).writeImage("%s\%s_%d.%s" % (savePath, filName, pic_count, picType));
    pix = None;
    doc.close();
 
def GetPageText(pdfName,password=None, pageStart="begin", pageEnd="end"):
    '''
    `读取文本    
    `输出到    将提取的文本保存到变量(返回值)
    `文件名    需要读取文本的PDF文件名
    `文件密码    PDF文件密码,如果没有密码则为null
    `页面范围    数组形式,[开始页,结束页],其中"begin"代表第一页,"end"代表最后一页,可以有如下形式["begin",9] 或者 ["begine","end"]
    '''
    # 打开一个PDF文件,doc为Document类型,是一个包含每一页PDF文件的列表
    doc = fitz.open(pdfName);
    if password is not None:
        doc.authenticate(password);
    pageSize = [pageStart,pageEnd];
    pageSize=HandlePageSize(pageSize, doc.pageCount);
    pageContent=[];
    for pg in pageSize:
        pageContent.append(fitz.utils.getPageText(doc, pg).strip());
    return pageContent;
    doc.close();
     
def PageSaveToPic(pdfName,password=None,savePath=None, pageStart="begin", pageEnd="end"):
    '''
    `导出页码为图片    
    `文件名    需要导出成图像的PDF文件名
    `文件密码    PDF文件密码,如果没有密码则为null
    `保存文件名    保存图片的路径
    `导出页码    需要导出成图像的页码
    '''
    # 打开一个PDF文件,doc为Document类型,是一个包含每一页PDF文件的列表
    doc = fitz.open(pdfName);
    if password is not None:
        doc.authenticate(password);
    # 设置图片的旋转角度
    # 设置图片相对于PDF文件在X轴上的缩放比例
    trans = fitz.Matrix(2.0, 2.0).preRotate(0);
    # 默认存pdf目录
    if not savePath:
        savePath = os.path.dirname(pdfName);
    # 文件名
    filName = os.path.basename(pdfName);
    filName = filName.split(".")[0];
    pageSize = [pageStart,pageEnd];
    # 页码处理
    pageSize=HandlePageSize(pageSize, doc.pageCount);
    for pg in pageSize: 
        pm = fitz.utils.getPagePixmap(doc, pg, matrix=trans, alpha=False);
        pm.writeImage("%s\%s_%d.%s" % (savePath, filName, (pg+1), "png"));
    doc.close();
 
def PageCount(pdfName,password=None):
    '''
    `获取总页数    
    `输出到    将总页数保存到变量(返回值)
    `文件名    PDF文件名
    `文件密码    PDF文件密码,如果没有密码则为null
    '''
    # 打开一个PDF文件,doc为Document类型,是一个包含每一页PDF文件的列表
    doc = fitz.open(pdfName);
    if password is not None:
        doc.authenticate(password);
    pageCount = doc.pageCount
    doc.close();
    return pageCount;
     
def PdfMerge(pdfPath,saveName):
    '''
    `合并PDF    
    `文件列表    数组类型,需要合并的文件路径列表
    `保存文件名    合并后的文件名
    '''
    if type(pdfPath) == list and len(pdfPath)< 2:
        raise Exception('无法合并单个PDF文件');
    output = PyPDF2.PdfFileWriter()
    outputPages = 0    
    for pdf_file in pdfPath:
        f=open(pdf_file, "rb");
        # 读取源PDF文件
        inp = PyPDF2.PdfFileReader(f);
        # 获得源PDF文件中页面总数
        pageCount = inp.getNumPages();
        outputPages += pageCount;
        # 分别将page添加到输出output中
        for iPage in range(pageCount):
            output.addPage(inp.getPage(iPage));
    # 写入到目标PDF文件
    outputStream = open(saveName, "wb");
    output.write(outputStream);
    outputStream.close();

def HandlePageSize(pageSize, pageCount):
#     if type(pageSize) == int:
#         if pageSize < 1:
#             raise Exception('开始页码从1开始');
#         elif pageSize > pageCount:
#             raise Exception('开始页码必须小于结束页码');
#         return [pageSize-1];
    if type(pageSize) == list and len(pageSize) == 2:
        for i in range(len(pageSize)):
            temp=pageSize[i];
            if type(temp) == str:
                temp = temp.lower();
                if temp == "begin":
                    pageSize[i] = 1;
                elif temp == "end":
                    pageSize[i] = pageCount;
                else:
                    raise Exception('页码必须是数字');
            elif type(temp) == int:
                if temp < 1:
                    raise Exception('页码必须大于1');
            else:
                raise Exception('页码必须是数字');
        if pageSize[0] < 1:
            raise Exception('开始页码从1开始');
        elif pageSize[0] > pageCount:
            raise Exception('开始页码必须小于结束页码');
        if pageSize[1] > pageCount:
            pageSize[1] = pageCount;
        pageSize[0] = pageSize[0] - 1;
        return range(*tuple(pageSize));
    else:
        raise Exception('页码参数错误');
#             return [i-1 for i in pageSize];
#     if type(pageSize) == str and pageSize.lower() == "begin" :
#         return [0];
#     if type(pageSize) == str and pageSize.lower() == "end" :   
#         return [pageCount - 1];     
            
    
if __name__ == '__main__':
    print(type(0))
#     PdfMerge([r"C:\Users\Administrator\Desktop\aa\xxx.pdf",r"C:\Users\Administrator\Desktop\aa\xxxxxx.pdf"], r"C:\Users\Administrator\Desktop\bb\bb.pdf");
#     PageSaveToPic(r"C:\Users\Administrator\Desktop\aa\xxx.pdf",savePath=r"C:\Users\Administrator\Desktop\bb", pageSize=["begin","end"]);
#     GetPagePic(r"C:\Users\Administrator\Desktop\aa\xxx.pdf", savePath=r"C:\Users\Administrator\Desktop\bb", pageSize=["begin","end"])
#     GetAllPic(r"C:\Users\Administrator\Desktop\aa\xxx.pdf",savePath=r"C:\Users\Administrator\Desktop\bb",picType="bmp");
#     text=GetPageText(r"C:\Users\Administrator\Desktop\aa\xxx.pdf", pageSize=[5,1]);
#     print(text);
#     print(PageCount(r"C:\Users\Administrator\Desktop\aa\xxx.pdf"));
#     print(HandlePageSize(1,100));
#     print(HandlePageSize(["begin","end"],100));
#     print(HandlePageSize(["end","begin"],100));
#     print(HandlePageSize([1,3,4,"end",6],100));
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352