python将excel表格里面的url链接转换成图片

背景:

报表里面的图片一般都是不会直接存图片的实体,一般是存图片存放的位置,也就是url,然后报表的使用对象也不是程序相关工作者,只会使用简单的excel功能,于是有了如下对话:

小哥哥,你可以把里面的url变成图片吗?这样我们就可以直接使用啦。

这不就来看看咋弄合适。

可能用到的库:

import io
import requests
import time
import re
from openpyxl import load_workbook
from openpyxl.drawing.image import Image

用户场景分析:

使用对象一般是这种格式的excle:

        很明显第一行是标题,第二行开始就是内容,而我们需要转换的内容在第n(n>=2)行的C(?)列,那么我们想要把图片的url拿出来,那至少要知道url在哪里列,这个url,可能有多个,所以我们可以提取第二行(显然可以肯定要求变更行数)的数据进行清洗。

def urlpoint(data):
    NumTip = []
    if data == []:
        return -1
    for i in range(len(data)):
        strname =str(data[i])
         # 用于匹配至少一个图片形式
        pattern = re.compile(r'(.png|.img|.gif|.jpg|.jpeg)$')    
        m = pattern.search(strname)
        if m == None:
            continue
        else:
            NumTip.append(i)
    # 如果一个图片地址都没有找到就返回-1,不然返回下表的集合
    if  NumTip == []:
        return -1
    else:
        return NumTip

        这样就可以得到我们的目标列的下标了, 在图示中的url是没有带前面的路由地址的,因为一个公司的图片网址是往往是固定的,这样存储可以省一点空间,但是我们要兼容有些直接就是图片地址的情况。于是:

             url = cell.value
             #阻止某些为空
             if url == None:
                 continue
            #事实上这里可以检查一下url是否有前缀http 这样可以兼容一下其他形式的图片
             pattern = re.compile(r'^(https://|http://)')    
                # 用于匹配至少一个数字
             m = pattern.match(url)
             if m == None:
               url ='https://image.baidu.com/' +url

        然后我们需要去通过url获取到图片,将图片存在内存里,然后在写入excel里,这个时候需要对获取的图片按比例进行裁剪,具体函数:

def img_resize(width, height):
    if width > height:
        height = height*200//width
        width = 200
    else:
        width = width*200//height
        height = 200
    return width, height

然后我们将这个写入excel:

             # 删除超链接
             cell.hyperlink = None
             # # 删除内容
             cell.value = ""
             # 设置行高
             ws.row_dimensions[cell.row].height = 200
             # 下载图片到内存
             res = requests.get(url)
             img = Image(io.BytesIO(res.content))
             # 等比例缩放图片
             width, height = img_resize(img.width, img.height)
             img.width = width
             img.height = height
             # 拼接目标单元格   subscript 是替换url     Ccolumns+i+1 是按顺序放后面
             endnum =str(Cnum[subscript]) + str(cell.row)
             print('成功添加到第:',endnum,'列')
             # 添加图片到指定单元格
             ws.add_image(img, endnum)

 这个时候一行的图片就转换好了,然后我们对整个文档进行遍历,就可以完成了。

完整代码如下:



from csv import excel
import io
import requests
import time
import re
from openpyxl import load_workbook
from openpyxl.drawing.image import Image


# 保持图片的比例
def img_resize(width, height):
    if width > height:
        height = height*200//width
        width = 200
    else:
        width = width*200//height
        height = 200
    return width, height
# 获得选中的表的最大行数和最大列数
def getRowsClosNum(self):
        rows = self.max_row
        columns = self.max_column
        return rows,columns

def get_row_value(self, row):
        columns = self.max_column
        row_data = []
        for i in range(1, columns + 1):
            cell_value = self.cell(row=row, column=i).value
            row_data.append(cell_value)
        return row_data


def urlpoint(data):
    NumTip = []
    if data == []:
        return -1
    for i in range(len(data)):
        strname =str(data[i])
         # 用于匹配至少一个图片形式
        pattern = re.compile(r'(.png|.img|.gif|.jpg|.jpeg)$')    
        m = pattern.search(strname)
        if m == None:
            continue
        else:
            NumTip.append(i)
    # 如果一个图片地址都没有找到就返回-1,不然返回下表的集合
    if  NumTip == []:
        return -1
    else:
        return NumTip

def TurnURLPictures(dataname,textname,ExcleSheet=0):
    start = time.clock()
    # 用户下载的位置
    textname ='download/'  +str(dataname)+'.xlsx'
    # 用户上传的位置
    dataname ='files/'+str(dataname)+'.xlsx'
    wb = load_workbook(dataname)
    Sheetnames =wb.sheetnames
    #默认是第一个表
    ws = wb[Sheetnames[ExcleSheet]]
    # 获得第二行的数据,通常来说第一行是标题名,带入get_row_value()里面,
    cData = get_row_value(ws,2)
    #得到这个表的行高
    Crows,Ccolumns= getRowsClosNum(ws)
    #url 所在列
    urlnum =urlpoint(cData)
    if urlnum == -1:
        print ('Its second line does not have a URL')
        return  -1
    #拼接操作的xlsx 文件的行数 一般为2-maxrow   
    Cnum ={1:"A",2:"B",3:"C",4:"D",5:"E",6:"F",7:"G",8:"H",9:"I",10:"J",11:"K",12:"L",13:"M",14:"N","15":"O",16:"P",17:"Q",18:"R",19:"S",20:"T",21:"U",22:"V",23:"W",24:"X",25:"Y"}
    # 
    GroupNum = len(urlnum)
    for  i in range(GroupNum):
         subscript = urlnum[i]+1
         name =str(Cnum[subscript])+'2:'+str(Cnum[subscript])+str(Crows)
         ws.column_dimensions[Cnum[subscript]].width = 50
         for cell, in ws[name]:
             url = cell.value
             #阻止某些为空
             if url == None:
                 continue
            #事实上这里可以检查一下url是否有前缀http 这样可以兼容一下其他形式的图片
             pattern = re.compile(r'^(https://|http://)')     
               # 用于匹配至少一个数字
             m = pattern.match(url)
             if m == None:
               url ='https://image.baidu.com/' +url
             # 删除超链接
             cell.hyperlink = None
             # # 删除内容
             cell.value = ""
             # 设置行高
             ws.row_dimensions[cell.row].height = 200
             # 下载图片到内存
             res = requests.get(url)
             img = Image(io.BytesIO(res.content))
             # 等比例缩放图片
             width, height = img_resize(img.width, img.height)
             img.width = width
             img.height = height
             # 拼接目标单元格   subscript 是替换url     Ccolumns+i+1 是按顺序放后面
             endnum =str(Cnum[subscript]) + str(cell.row)
             print('成功添加到第:',endnum,'列')
             # 添加图片到指定单元格
             ws.add_image(img, endnum)
    start2 = time.clock()
    wb.save(textname)
    print('Running time: %s 毫秒' % (start2*1000-start*1000))
    return Crows/60
    



if __name__=="__main__":
    TurnURLPictures('bbf579f8a4c311ec8f8b1831bf2aef29','测试')

效果如下:

 

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值