【tkGo】將Excel裏的圖片鏈接替換爲圖片(Excel嵌入圖片)

1 背景

因爲某些原因,我們的Excel裏會放入一些圖片鏈接,但查看的時候需要一個個點開,通過瀏覽器顯示,非常麻煩。

我們可以通過python的openpyxl這個庫來解決此問題,一鍵替換所有鏈接爲圖片。

2 環境

Python 3.7.3 64-bit

openpyxl 3.0.0 (用於操作Excel)

requests 2.22.0 (用於下載圖片)

validators 0.14.1 (用於校驗文本是否是鏈接)

3 openpyxl

wb = openpyxl.load_workbook(path)  # 加載Excel文件

sheet_names = wb.sheetnames  # 獲取Excel的sheet列表

sheet = wb[sheet_name]  # 指定sheet

row_num = sheet.max_row  # 獲取sheet行數
column_num = sheet.max_column  # 獲取sheet列數

for row in sheet.rows:  # 遍歷sheet所有行
for column in sheet.columns:  # 遍歷sheet所有列

for row in sheet.rows:  # 遍歷sheet數據單元格
    for cell in row:
        cell_value = cell.value  # 單元格值
        cell_row = cell.row  # 單元格所在行索引
        cell_column = cell.column  # 單元格所在列索引
        cell_column_letter = openpyxl.utils.get_column_letter(cell.column)  # 單元格所在列名稱
        cell_coordinate = cell.coordinate  # 單元格座標

sheet.row_dimensions[cell_row].height = IMG_CELL_HEIGHT  # 設置行高
sheet.column_dimensions[cell_column_letter].width = IMG_CELL_WIDTH  # 設置列寬

img = openpyxl.drawing.image.Image(img_path)
sheet.add_image(img, cell_coordinate)  # 往Excel裏嵌入圖片

wb.save(filename=path_excel_with_img)  # 保存Excel

4 主要代碼

def is_img_url(self, value: str):
        """檢測單元格值是否是圖片鏈接
        """
        if value.startswith("=HYPERLINK"): value = value[12:-2]  # 去掉excel超鏈接函數
        is_img_url = False
        if validators.url(value):  # 判斷是否是url
            for img_ext in self.img_ext:
                if value.lower().endswith(img_ext):  # 判斷是否是圖片文件後綴名
                    is_img_url = True
                    break
        return is_img_url, value
def download_img(self, img_url, sheet_name=None, coordinate=None, timeout=15):
        """圖片下載
        
        :param img_url: 圖片鏈接
        :param sheet_name: ExcelSheet名稱
        :param coordinate: Excel單元格座標
        :param timeout: 圖片下載超時時間
        """
        img_path = self.img_url_to_path(img_url)  # 圖片保存地址
        if os.path.exists(img_path):  # 判斷圖片是否已經存在
            self.stdout(sheet_name, coordinate, img_url, self.IMG_DOWNLOAD_EXISTS)
        else:
            self.check_and_mkdir(path=img_path)  # 判斷保存圖片的文件夾是否存在,不存在則創建
            r = requests.get(img_url, timeout=timeout)  # 發起HTTP請求
            if not r.content[:4] == b'\xff\xd8\xff\xe0':  # 判斷返回內容是否是圖片格式
                self.stdout(sheet_name, coordinate, img_url, self.IMG_DOWNLOAD_ERROR, self.IMG_URL_ERROR)
                return False
            with open(img_path, "wb") as f:  # 保存圖片至本地
                f.write(r.content)
            self.stdout(sheet_name, coordinate, img_url, self.IMG_DOWNLOAD_DONE)
        return True
def add_img_of_sheet(self, sheet_name):
        """Excel中添加圖片

        :param sheet_name: Sheet名稱
        """
        sheet = self.wb[sheet_name]  # 指定Sheet
        for row in sheet.rows:  # 遍歷所有行
            for cell in row:  # 遍歷單元格
                cell_value = str(cell.value)  # 單元格值
                is_img_url, img_url = self.is_img_url(cell_value)
                if is_img_url:  # 如果單元格存放的是圖片鏈接
                    img_path = self.img_url_to_path(img_url)  # 獲取圖片本地保存地址
                    if os.path.exists(img_path):  # 判斷本地圖片是否存在
                        try:
                            img = openpyxl.drawing.image.Image(img_path)  # 加載圖片
                            img.height = self.IMG_HEIGHT  # 設置圖片高度
                            img.width = self.IMG_WIDTH  # 設置圖片寬度
                            sheet.add_image(img, cell.coordinate)  # 嵌入圖片
                            sheet.row_dimensions[cell.row].height = self.IMG_CELL_HEIGHT  # 設置行高
                            column_letter = openpyxl.utils.get_column_letter(cell.column)  # 獲取列名
                            sheet.column_dimensions[column_letter].width = self.IMG_CELL_WIDTH  # 設置列寬
                            cell.alignment =  openpyxl.styles.Alignment(wrapText=True)  # 設置單元格屬性 - 自動換行
                        except Exception as e:
                            print_exc()  # 打印詳細錯誤
                            self.img_add_failed[img_url] = (sheet_name + " " + cell.coordinate, str(e))  # 記錄錯誤信息
                            self.stdout(sheet_name, cell.coordinate, img_url, str(e))
                    else:
                        self.img_add_failed[img_url] = (sheet_name + " " + cell.coordinate, self.IMG_DOWNLOAD_NOT_EXISTS)
                        self.stdout(sheet_name, cell.coordinate, img_url, self.IMG_DOWNLOAD_NOT_EXISTS)

5 最終效果

點擊Trans菜單下的IMG to Excel選項,一鍵將Excel中的圖片鏈接轉化爲圖片,首先需要複製Excel文件,否則會報如下錯誤:

正常效果:

6 源碼地址

項目代碼在github上:https://github.com/TheUncleWhoGrowsBeans/tkGo

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章