Search code examples
python-imaging-librarypngopenpyxljpegwebp

In Python, how to insert PNG image converted from html WEBP to excel without saving image and appending images in local PC folder?


My target is scraping html data including sorted information and WEBP images and saving to Excel sheet.
WEBP format images cannot be inserted to Excel sheet directly. The only way is converting WEBP to PNG or JPG first. But with bulk images converting image, saving to PC hard disk and inserting saved PNG from local PC to Excel takes time to process.
Is any way that WEBP image is converted to PNG and inserted to excel directly?

# Partial codes below

url = "https://down-aka-tw.img.susercontent.com/tw-11134207-7qul7-lilu03jxchpw3d_tn.webp" 

response = requests.get(url)

img_data = response.content

img_png = Image.open(BytesIO(requests.get(url).content)).convert("RGB") #from PIL import Image as pImage

img_png.save("C:\\temp\\image.png")

img = oImage('C:\\temp\\image.png')  #from openpyxl.drawing.image import Image as oImage

wb = Workbook()
ws = wb.active

# insert images
ws.add_image(img, 'A1')

wb.save("C:\\temp\\export.xlsx")
wb.close()

I did try to insert converted Binary img_png to Excel sheet but it failed. However downloading URL WEBP, converting to PNG then save to PC is workable.
img_png can be print() or show(). If img_png inserted to Excel, it cannot be accepted. So I save PNG to image.png file and open the image using openpyxl(oImage). img can be inserted to Excel.

Is there any way that WEBP image is converted to PNG and inserted to excel directly without saving locally before inserting to Excel.


Solution

  • Save as a PNG BytesIO and open as openpyxl.drawing.image before inserting into the sheet.

    from io import BytesIO
    from openpyxl.drawing.image import Image as oImage
    import requests
    from PIL import Image as pImage
    from openpyxl import Workbook
    
    
    ### Get image from URL
    url = "https://down-aka-tw.img.susercontent.com/tw-11134207-7qul7-lilu03jxchpw3d_tn.webp"
    response = requests.get(url)
    
    img_data = response.content
    img_png = pImage.open(BytesIO(requests.get(url).content)).convert("RGB") #from PIL import Image as pImage
    
    # img_png.save("C:\\temp\\image.png")
    # img = oImage('C:\\temp\\image.png')  #from openpyxl.drawing.image import Image as oImage
    
    ### Create Workbook and Sheet
    wb = Workbook()
    ws = wb.active
    
    ### Convert image to PNG for Openpyxl use
    img_stream = BytesIO()
    img_png.save(img_stream, format='PNG')
    img_openpyxl = oImage(img_stream)
    
    ### Add Image to sheet
    ws.add_image(img_openpyxl, 'A1')
    
    wb.save("C:\\temp\\export.xlsx")
    # wb.close()  #  This line does nothing in your code.