使用Python實現(xiàn)簡單的Excel繪圖工具
最近做了一個有趣的小工具:用 Python 把任意圖片“復(fù)刻”成 Excel 表格藝術(shù)。
通過解析圖片像素值,然后在 Excel 單元格中填充對應(yīng)顏色,就能生成一張由無數(shù)小方格組成的“像素畫”。
這個工具不復(fù)雜,適合對圖像處理和自動化感興趣的小伙伴研究。
在這篇圖文教程中,我會一步步帶你了解工具的原理、代碼實現(xiàn)和使用方法。
代碼基于 PyQt5(GUI 界面)、OpenCV(圖像處理)和 openpyxl(Excel 操作),簡單易上手。感興趣的同學(xué)可以直接 fork 代碼試試!
工具效果預(yù)覽
先來看看成品效果吧!左邊是原圖,右邊是生成的 Excel 藝術(shù)(每個單元格就是一個像素)

另一個例子,我換了張貓咪圖片,生成后效果如下:

(截圖說明:工具自動縮放圖片到 320 寬,生成低分辨率 Excel 以節(jié)省資源,但細(xì)節(jié)依然清晰)
手工操作這種效果?想想看,一張 320x240 的圖片就需要 76,800 個單元格手動填色……太恐怖了!用程序,幾秒鐘搞定。
實現(xiàn)原理
核心思路很簡單:
- 讀取圖片:用 OpenCV 加載圖像,獲取每個像素的 RGB 值。
- 縮放處理:為了避免高分辨率圖片占用過多資源,默認(rèn)將寬度固定為 320,高度按比例縮放。
- 生成 Excel:用 openpyxl 創(chuàng)建工作表,每個像素對應(yīng)一個單元格,填充對應(yīng)顏色的 PatternFill。
- GUI 界面:PyQt5 提供簡單界面,選擇圖片和保存路徑,一鍵繪制,還帶進(jìn)度條顯示。
環(huán)境準(zhǔn)備
- Python 3.8+
- 依賴庫:pip install PyQt5 opencv-python openpyxl numpy
- UI 文件:用 Qt Designer 設(shè)計 excel_ui.py(我用的是一個簡單的窗口,包含圖片預(yù)覽、路徑輸入和按鈕)。
如果懶得配置環(huán)境,我還打包了 EXE 可執(zhí)行文件(脫離 Python 環(huán)境)
完整代碼
下面是核心代碼,分為主窗口類和入口。代碼不長,注釋詳盡。
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog, QMessageBox, QProgressDialog
from PyQt5.QtGui import QImage, QPixmap
from excel_ui import Ui_MainWindow # Qt Designer 生成的 UI 文件
from PyQt5.QtCore import Qt, QTimer
import cv2
import numpy as np
import openpyxl
from openpyxl.styles import PatternFill
from openpyxl.utils import get_column_letter
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.img_ori = None # 存儲原始圖像
def select_pic(self):
"""選擇圖片并預(yù)覽"""
file_path, _ = QFileDialog.getOpenFileName(self, "選擇圖片", "", "Image Files(*.png *.jpg *.jpeg *.bmp)")
if file_path:
self.img_ori = cv2.imread(file_path)
img = cv2.cvtColor(self.img_ori, cv2.COLOR_BGR2RGB)
h, w, ch = img.shape
bytes_per_line = ch * w
q_image = QImage(img.data, w, h, bytes_per_line, QImage.Format.Format_RGB888)
q_pixmap = QPixmap.fromImage(q_image)
self.imageLabel.setPixmap(q_pixmap.scaled(
self.imageLabel.width(), self.imageLabel.height(),
Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation
))
def select_excel(self):
"""選擇 Excel 保存路徑"""
file_path, _ = QFileDialog.getSaveFileName(
self,
"設(shè)置 Excel 路徑",
"",
"Excel Files (*.xlsx *.xls)"
)
if file_path:
self.excelPathLineEdit.setText(file_path)
return file_path
else:
return None
def huizhi(self):
"""繪制圖片到 Excel"""
if not hasattr(self, 'img_ori') or self.img_ori is None:
QMessageBox.warning(self, "警告", "請先選擇圖片!")
return
excel_path = self.excelPathLineEdit.text()
if not excel_path:
QMessageBox.warning(self, "警告", "請先選擇 Excel 文件保存路徑!")
return
try:
# 強(qiáng)制縮放寬度為 320,高度按比例計算
min_width = 320
image = self.img_ori
height, width = image.shape[:2]
scale_factor = min_width / width
new_width = min_width
new_height = int(height * scale_factor)
image = cv2.resize(image, (new_width, new_height))
# 創(chuàng)建 Excel 工作簿
workbook = openpyxl.Workbook()
sheet = workbook.active
# 設(shè)置單元格為正方形(寬度 3,高度 17)
for col in range(1, new_width + 1):
sheet.column_dimensions[get_column_letter(col)].width = 3
for row in range(1, new_height + 1):
sheet.row_dimensions[row].height = 17
# 創(chuàng)建進(jìn)度條
progress = QProgressDialog("正在繪制圖片到 Excel...", "取消", 0, new_height, self)
progress.setWindowTitle("進(jìn)度")
progress.setWindowModality(Qt.WindowModal)
progress.setValue(0)
# 遍歷圖片像素并填充 Excel 單元格
for y in range(new_height):
if progress.wasCanceled():
break
for x in range(new_width):
b, g, r = image[y, x] # OpenCV 默認(rèn) BGR 格式
color = "{:02x}{:02x}{:02x}".format(r, g, b) # 轉(zhuǎn)換為 RGB 格式的十六進(jìn)制
if color == "000000":
color = "010101" # 純黑色替換為深灰色
fill = PatternFill(start_color=color, end_color=color, fill_type="solid")
sheet.cell(row=y + 1, column=x + 1).fill = fill
progress.setValue(y + 1)
QApplication.processEvents() # 確保 UI 更新
# 保存 Excel 文件
if not progress.wasCanceled():
workbook.save(excel_path)
QMessageBox.information(self, "成功", "圖片已成功繪制到 Excel 文件!")
progress.close()
except Exception as e:
QMessageBox.critical(self, "錯誤", f"繪制失敗: {str(e)}")
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())代碼亮點解析
- 圖像預(yù)覽:select_pic() 用 QImage 實時顯示選中的圖片,保持寬高比。
- 縮放優(yōu)化:cv2.resize() 固定寬度 320,避免高分辨率卡頓。實際 Excel 文件大小控制在合理范圍內(nèi)。
- 像素填充:雙層循環(huán)遍歷 (y, x),轉(zhuǎn) RGB 十六進(jìn)制,應(yīng)用 PatternFill。進(jìn)度條用 QProgressDialog 實時反饋。
- 異常處理:捕獲保存錯誤,友好提示。

使用步驟
- 運行程序(python main.py 或雙擊 EXE)。
- 點擊“選擇圖片”,挑選一張 PNG/JPG 等格式的圖像,界面會預(yù)覽。
- 點擊“選擇 Excel 路徑”,設(shè)置保存文件名(.xlsx)。
- 點擊“開始繪制”,等待進(jìn)度條完成。
- 打開生成的 Excel,Ctrl + 滾輪縮放查看效果?。ńㄗh全屏查看)

結(jié)語
這個小工具就是下午“無聊”時寫的,編程的樂趣就在于把不可能變可能。
到此這篇關(guān)于使用Python實現(xiàn)簡單的Excel繪圖工具的文章就介紹到這了,更多相關(guān)Python Excel繪圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
keras 自定義loss model.add_loss的使用詳解
這篇文章主要介紹了keras 自定義loss model.add_loss的使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06
使用python將mysql數(shù)據(jù)庫的數(shù)據(jù)轉(zhuǎn)換為json數(shù)據(jù)的方法
這篇文章主要介紹了使用python將mysql數(shù)據(jù)庫的數(shù)據(jù)轉(zhuǎn)換為json數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
pyinstaller打包可執(zhí)行程序過程中的常見錯誤解決
這篇文章主要介紹了pyinstaller打包可執(zhí)行程序過程中的常見錯誤解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11
Python實現(xiàn)實現(xiàn)gltf預(yù)覽圖的示例詳解
隨著3D技術(shù)的不斷發(fā)展,GLTF逐漸成為了Web和移動應(yīng)用程序中最流行的3D文件格式之一,本文將介紹如何使用Python生成GLTF模型的預(yù)覽圖,需要的可以了解下2025-02-02
python自定義函數(shù)實現(xiàn)一個數(shù)的三次方計算方法
今天小編就為大家分享一篇python自定義函數(shù)實現(xiàn)一個數(shù)的三次方計算方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01
Pandas中數(shù)據(jù)表合并的幾種實現(xiàn)方法
Pandas提供了merge()、concat()和join()三種方法來合并數(shù)據(jù)表,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-12-12
Python利用pyreadline模塊實現(xiàn)交互式命令行開發(fā)
交互式命令行是一種方便用戶進(jìn)行交互的工具,能夠使用戶與計算機(jī)進(jìn)行快速的交互操作,提高工作效率。本文主要介紹了如何利用pyreadline模塊實現(xiàn)交互式命令行開發(fā),需要的可以參考一下2023-05-05

