跳至主要内容

從手動到自動:數份電子簽名處理的最佳實務

問題意識與情境

那天,在工作的諮商所遇到了一個實際又棘手的狀況。由於過往部分心理師的諮商紀錄檔案中,未附上正式的電子簽名,因此我們必須協助補齊心理師的簽名檔案,才能符合衛生局的要求。

一開始,我們採取最直觀的方式:逐一打開 PDF 檔案,手動加入心理師的簽名。然而,當我們發現需要處理的紀錄橫跨 2020 年到 2025 年,累積上萬筆檔案 時,這個方法幾乎是不可能完成的任務,光是打開檔案就足以讓人崩潰。原本我們使用的是 Adobe PDF 來加入簽名檔,但實際操作後發現速度非常慢,效率極低。於是我開始思考:

是否有辦法一次性替某一位心理師的所有紀錄加上電子簽名?

但問題並沒有這麼單純。不同的紀錄,簽名欄位的位置並不固定

有些在第一頁,有些在第二頁,甚至格式略有差異,無法單純用「固定頁數」處理。也因此,我開始研究是否能有一種方式,讓系統自動判斷簽名欄位的位置,並正確地將電子簽名加上去。在這個過程中,我開始與 Claude AI 討論可能的解法,也逐漸整理出一條可行的處理流程,於是便有了這篇紀錄文。

這套工具最大的好處在於:

  • 可在本機端一次處理大量 PDF 檔案,不需逐一手動開啟
  • 系統能自動辨識簽名位置(通常會有簽名欄位),並正確放置電子簽名
  • 全程在自己的電腦上完成,符合諮商專業對於隱私與資料保護的要求

對於需要大量補齊電子簽名、又無法將檔案上傳至雲端或第三方服務的情境來說,這是一個非常實用的解法。

操作流程

重要申明:以下皆為本人自己製作檔案與模擬測試,皆無使用任何諮商紀錄!

一、安裝 Python

1.前往 Python 官網:https://www.python.org/downloads/
2.點選Or get the standalone installer for Python XXX(最新版本),即開始下載Python
3.下載完後,開始執行安裝檔。在安裝第一個畫面的最下方,必須勾選: ☑ Add python.exe to PATH
4.驗證安裝是否成功:Window系統開啟「命令提示字元」或「終端機」(可直接在電腦搜尋)

並執行:

python --version`

或是

python -V

應該顯示類似:Python xxx(版本號碼)或是他是空白的,都代表安裝成功。

二、安裝 Python 套件

1.在命令提示字元或終端機輸入:

python -m pip install --upgrade pip
python -m pip install PyPDF2 reportlab pillow

2.驗證安裝,並確認清單包含:PyPDF2、reportlab、pillow

python -m pip list

三、準備工作環境

  1. 建立資料夾結構:(可以改成自己習慣或編排的模式)
    📁 實作程式/
📄 pdf_signature.py ← 程式檔案
🖼️ 簽名01.png ← 簽名圖片(PNG格式,建議背景透明)
📁 原始PDF資料夾/ ← 放入要處理的PDF
📄 記錄001.pdf
📄 記錄002.pdf
📄 記錄003.pdf
...
📁 已簽名PDF
  1. 打開程式編輯器(推薦使用:VS Codenotepad++),並將以下程式碼貼上(詳細要修改程式碼內容可以參見底下附錄一)

    A. 程式結構

    程式結構:
    ├── find_signature_page() → 找到「請簽名:」在哪一頁
    ├── add_signature_to_pdf() → 在PDF上加簽名
    ├── batch_process_pdfs() → 批次處理多個PDF
    └── 主程式 (if __name__ == "__main__") → 程式入口,設定參數

    B. 完整程式碼

    資訊

    以下此程式邏輯為:
    系統自動會去抓「請簽名:」字樣,並且依據您設定的貼上簽名空間分布(x,y)軸來抓位置。
    然而,後來發現工作時候發現,PDF檔案中的簽名欄位他沒有OCR光學字元辨識(簡單來說他複製文字時,會變成其他文字亂碼)。
    所以最後我就把系統抓取「請簽名:」字樣拿掉,畢竟都是在最後一頁做簽名,所以其實沒有差異。底下仍保留有請簽名字樣,若不知道如何修正,可以拿給Claude請他修改你想要的版本。

    # -*- coding: utf-8 -*-
    # PDF 自動簽名程式
    # 請先安裝需要的套件: pip install PyPDF2 reportlab pillow

    import os
    from PyPDF2 import PdfReader, PdfWriter
    from reportlab.pdfgen import canvas
    from reportlab.lib.pagesizes import letter
    from PIL import Image
    import io

    def find_signature_page(pdf_path, keyword="請簽名:"):
    """尋找包含簽名關鍵字的頁面"""
    try:
    reader = PdfReader(pdf_path)
    for page_num, page in enumerate(reader.pages):
    text = page.extract_text()
    if keyword in text:
    return page_num
    return None
    except Exception as e:
    print(f"讀取 {pdf_path} 時發生錯誤: {e}")
    return None

    def add_signature_to_pdf(input_pdf, output_pdf, signature_image, x=100, y=100, width=150, height=50):
    """在PDF指定位置加入簽名圖片"""
    try:
    reader = PdfReader(input_pdf)
    writer = PdfWriter()

    signature_page_num = find_signature_page(input_pdf)

    if signature_page_num is None:
    print(f"警告: {input_pdf} 找不到「請簽名:」字樣,跳過此檔案")
    return False

    packet = io.BytesIO()
    can = canvas.Canvas(packet, pagesize=letter)
    can.drawImage(signature_image, x, y, width=width, height=height, mask='auto', preserveAspectRatio=True)
    can.save()

    packet.seek(0)
    signature_pdf = PdfReader(packet)

    for page_num, page in enumerate(reader.pages):
    if page_num == signature_page_num:
    page.merge_page(signature_pdf.pages[0])
    writer.add_page(page)

    with open(output_pdf, 'wb') as output_file:
    writer.write(output_file)

    print(f"完成: {input_pdf} -> 簽名加在第 {signature_page_num + 1} 頁")
    return True

    except Exception as e:
    print(f"處理 {input_pdf} 時發生錯誤: {e}")
    return False

    def batch_process_pdfs(input_folder, output_folder, signature_image):
    """批次處理資料夾內所有PDF"""

    if not os.path.exists(output_folder):
    os.makedirs(output_folder)

    pdf_files = [f for f in os.listdir(input_folder) if f.endswith('.pdf')]

    if not pdf_files:
    print("錯誤: 找不到任何PDF檔案")
    return

    print(f"找到 {len(pdf_files)} 個PDF檔案")
    print("開始處理...")
    print("")

    success_count = 0
    fail_count = 0

    for pdf_file in pdf_files:
    input_path = os.path.join(input_folder, pdf_file)
    output_path = os.path.join(output_folder, f"已簽名_{pdf_file}")

    if add_signature_to_pdf(input_path, output_path, signature_image):
    success_count += 1
    else:
    fail_count += 1

    print("")
    print("處理完成!")
    print(f"成功: {success_count} 個檔案")
    print(f"失敗: {fail_count} 個檔案")

    if __name__ == "__main__":
    # ===== 設定參數(可依需求修改)=====
    INPUT_FOLDER = "原始PDF資料夾" # 原始PDF所在資料夾
    OUTPUT_FOLDER = "已簽名PDF" # 輸出資料夾
    SIGNATURE_IMAGE = "簽名.png" # 簽名圖片檔名

    # 簽名位置與大小(可調整)
    SIGNATURE_X = 350 # X座標(左右位置,數字越大越右)
    SIGNATURE_Y = 150 # Y座標(上下位置,數字越大越上)
    SIGNATURE_WIDTH = 120 # 簽名寬度
    SIGNATURE_HEIGHT = 40 # 簽名高度

    print("PDF 自動簽名程式")
    print("=" * 50)

    # 檢查簽名圖片
    if not os.path.exists(SIGNATURE_IMAGE):
    print(f"錯誤: 找不到簽名圖片 {SIGNATURE_IMAGE}")
    print("請確保簽名圖片與程式在同一個資料夾")
    input("按 Enter 鍵結束...")
    exit()

    # 檢查輸入資料夾
    if not os.path.exists(INPUT_FOLDER):
    print(f"錯誤: 找不到資料夾 {INPUT_FOLDER}")
    print("請建立資料夾並放入要處理的PDF檔案")
    input("按 Enter 鍵結束...")
    exit()

    # 執行批次處理
    batch_process_pdfs(INPUT_FOLDER, OUTPUT_FOLDER, SIGNATURE_IMAGE)

    print("")
    input("按 Enter 鍵結束...")

四、執行程式

1.開啟命令提示字元或終端機,並切換到工作資料夾(請依實際建立的位置調整路徑),以下範例為存在桌面中有個「實作程式」的資料夾。 cd desktop/實作程式>

資訊

▶️知識+:什麼是cd?

cdChange Directory 的縮寫,中文意思是「切換目錄」或「更改資料夾」。 舉例:當你打開命令提示字元時,通常會看到:C:\Users\袋鼠>

這表示您現在「站在」C:\Users\袋鼠 這個資料夾裡。

如果不想要那麼麻煩去找他在哪,可以點選資料夾上排,按右鍵「複製位置」即可找到資料夾在那了。

2.執行程式:

python pdf_signature.py

3.完成的檔案呈現

附錄一:舉一反三修改程式-簽名位置與簽名關鍵字設定指南

(一)如何修改千名關鍵字

1.在程式的第 10 行:

def find_signature_page(pdf_path, keyword="請簽名:"):

(1)程式會在PDF中搜尋這個關鍵字
(2)找到關鍵字的那一頁,就是要加簽名的頁面
(3)無論關鍵字在第1頁、第2頁或任何頁,程式都會自動找到

2.修改範例:
(1)範例 1:改成「簽章:」
def find_signature_page(pdf_path, keyword="簽章:"):

(2)範例 2:改成英文
def find_signature_page(pdf_path, keyword="Signature:"):

(3)如果有多種可能的關鍵字-修改程式的第 16 行:

# 原本:
if keyword in text:

# 改成(可接受多種關鍵字):
if keyword in text or "簽章:" in text or "請蓋章:" in text:

(二)如何調整簽名位置與大小

1.在程式的第 101-104 行:

SIGNATURE_X = 350      # X座標(左右位置)
SIGNATURE_Y = 150 # Y座標(上下位置)
SIGNATURE_WIDTH = 120 # 簽名寬度
SIGNATURE_HEIGHT = 40 # 簽名高度

2.PDF 座標系統說明-座標原點在「左下角」

PDF頁面示意圖:

Y軸越大越上 ↑
|
(0, 800) | (600, 800) ← 頁面上方
|
|
(0, 400) | (600, 400) ← 頁面中間
|
|
(0, 0) |________→ X軸越大越右
左下角原點 (600, 0)
參數說明效果
X 增加數字變大簽名往右移
X 減少數字變小簽名往左移
Y 增加數字變大簽名往上移
Y 減少數字變小簽名往下移
WIDTH 增加寬度變大簽名變寬
HEIGHT 增加高度變大簽名變高

(1)步驟 1:用預設值測試-先用預設值處理 1個PDF,看看簽名在哪裡
(2)步驟 2:判斷要往哪個方向調整

簽名位置問題調整方法範例
太左邊增加 X350 → 400
太右邊減少 X350 → 300
太下面增加 Y150 → 200
太上面減少 Y150 → 100
太小增加 WIDTH 和 HEIGHT120 → 150
太大減少 WIDTH 和 HEIGHT120 → 80

(3)步驟 3:每次調整 50 左右-不要一次調太多,建議每次調整 30-50 的幅度

總結

回頭看這個問題,其實它並不只是「怎麼把簽名加上去」那麼單純,而是反映了許多助人工作現場正在面對的現實:行政符合規範的壓力,往往會在不知不覺中吞噬大量專業人力。當制度要求被一條一條補齊時,如果只能依靠人工處理,最終消耗的,往往是工作者本就有限的時間與心力。

這次嘗試用程式解決問題,是希望把那些可以被自動化的工作交給工具處理,讓人能夠回到真正需要人去承接的地方。

如果你也正面臨大量文件處理、卻又受限於隱私與合規無法使用雲端服務,或許這個做法能成為一個參考起點。技術不一定要很炫,只要能實際減輕現場負擔,它就已經完成了它最重要的任務。