2026年6月29日 星期一

Windows 11 建立本地端 AI (Ollama + qwen2.5-coder:7B + docker + webui)

0.自己本地端設備環境:Ultra 7 155H + 32G RAM + Intel Arc Pro Graphics 128M 

1.ollama 下載 ->下載後點兩下進行安裝

或是 以系統管理員身分開啟 PowerShell 進行安裝
安裝指令:irm https://ollama.com/install.ps1 | iex
  (1).測試是否安裝成功:ollama --version
  (2).檢查有多少模型:ollama list   (3).下載模型指令:ollama pull qwen2.5-coder:7B (4).安裝模型指令:ollama run qwen2.5-coder:7B

2. docker 安裝前,要先安裝 WSL
    (1). 以系統管理員身分開啟 PowerShell 
        安裝指令:wsl --install
    (2). 重啟電腦
    (3). 確認是否安裝成功指令:wsl --version

3.下載 docker desktop ->下載後點兩下進行安裝

或是 以系統管理員身分開啟 PowerShell 進行安裝-> 重啟電腦
安裝指令:winget install -e --id Docker.DockerDesktop
確認是否安裝成功指令:docker --version

4.下 powershell 指令啟動 Open WebUI:
docker run -d ^
--name open-webui ^
-p 3000:8080 ^
-e OLLAMA_BASE_URL=http://host.docker.internal:11434 ^
-v open-webui:/app/backend/data ^
--restart unless-stopped ^
ghcr.io/open-webui/open-webui:main

安裝完後,重開機。該如何啟動本地端AI?
    (1)由於重開機後,ollama 會開機後啟動。所以無需另行啟動。
    (2)只要啟動 docker desktop 即可。
    (3)打開瀏覽器 http://localhost:3000

2026年6月25日 星期四

彰化縣學校資通安全稽核計畫網站相關備忘事項

彰化縣學校資通安全稽核網站:https://audit.mychc.site/
彰化縣學校資通安全稽核網站管理登入:https://audit.mychc.site/admin/
登入之後的設定:
1.稽核設定->年度稽核學校->新增學校

完成之後,就可以有四個選項可以選擇,其中比較重要的是
1.指派稽核員:

2.訪客稽核員邀請:

其中
1.指派稽核員->選擇稽核員(現有帳號)->新增
2.訪客稽核員邀請->掃描QRcode->邀請訪客稽核員->立即開始

值得注意的是1.指派稽核員完成之後,才能開始與建立稽核報告

建立稽核報告完成之後,只能選擇儲存。定稿之後,才能使用QRcode簽核
就可以選擇稽核身份進行簽核

實際經驗分享:
1.稽核員 與受稽核學校人員 都會加入 一個群組。所以可以將相關連結 貼到群組即可。

只要點兩下,就能將input資料夾內所有PDF進行容量壓縮-版本02

系列文章:
01.python 不管何時何地,只要點兩下,資料夾內的所有pdf都會合併成一個pdf
https://skjhcreator.blogspot.com/2022/06/pythonpdfpdf.html
02.python 只要點兩下,分別對各資料夾內的pdf合併,合併後的檔名要讓人知道來自哪個資料夾 
https://skjhcreator.blogspot.com/2022/06/python-pdf.html
03. 只要點兩下,就能將一堆的Doc與Docx 轉成 PDF
03.https://skjhcreator.blogspot.com/2023/05/docdocx-pdf.html
04.只要點兩下,就能將一堆的JPG轉成一個PDF,並以JPG所在的資料夾名稱為PDF的檔名
04.https://skjhcreator.blogspot.com/2023/06/jpgpdfjpgpdf.html
05.只要點兩下,就能將放進input的一堆PDF轉成各自的WORD
05.https://skjhcreator.blogspot.com/2023/10/inputpdfword.html
06.只要點兩下,就能將放進input的一堆PDF轉成在ouput資料夾內的各自的WORD 
06.https://skjhcreator.blogspot.com/2023/10/inputpdfouputword.html
07.只要點兩下,就能夠將InputAndOutput資料夾底下的子子孫孫資料夾內所有Word通通轉成PDF
07.https://skjhcreator.blogspot.com/2024/09/word-word-pdf.html
08.只要點兩下,就可以將資料夾input內的所有Word通通轉成一個PDF
08.https://skjhcreator.blogspot.com/2025/07/inputwordpdf.html
09.只要點兩下兩次,就能依照設定拆分指定PDF頁數並合併成設定好的一個PDF
09.https://skjhcreator.blogspot.com/2025/09/pdfpdf.html
10.只要點兩下,就能將input資料夾內所有PDF進行容量壓縮-版本01
10.https://skjhcreator.blogspot.com/2026/04/inputpdf.html
11.只要點兩下,就能將input資料夾內所有PDF進行容量壓縮-版本02
11.https://skjhcreator.blogspot.com/2026/06/inputpdf-02.html

Just double-click to compress the file size of all PDFs in the input folder – Version 02.
        PDF 壓縮設定為:
screen = 最小檔案,適合螢幕閱讀
ebook = 一般文件,推薦使用
printer = 列印品質
prepress = 印刷品質
        由於版本01 將壓縮設定 固定在 ebook,也就是一般文件,推薦使用。當想要提高壓縮比,版本01就無法滿足。所以版本02就將壓縮設定寫進 setting.ini,若 setting.ini 不見了,版本02還可以生成。讓使用者可以修改 setting.ini,來滿足其需求。

PDF Compression Settings:

  • screen = Smallest file size, suitable for on-screen reading
  • ebook = Standard document quality, recommended for most uses
  • printer = Printer-quality output
  • prepress = Prepress quality for professional printing

In Version 01, the compression setting was fixed to ebook (standard document quality), which is recommended for general use. However, when a higher compression ratio is required, Version 01 cannot meet that need.

To address this limitation, Version 02 stores the compression setting in setting.ini. Users can modify the setting in setting.ini to suit their specific requirements. In addition, if setting.ini is missing, Version 02 can automatically regenerate it, ensuring the program continues to function properly.


下載檔案解壓密碼:demo1234
Here is the website where you can download the program and find instructions:
Download。Extraction Password: demo1234
使用教學(Instructional videos):


方法:Python + Ghostscript
一、下載與安裝 Ghostscript
https://www.ghostscript.com/download/gsdnld.html 下載後,點兩下進行安裝

二、Python 程式碼
檔案:pyPdfCompress01.py
檔案內容:

import os
import subprocess
import shutil
import webbrowser
import sys
import argparse
import platform
import configparser

INPUT_DIR = "input"
OUTPUT_DIR = "output"
SETTINGS_FILE = "settings.ini"

QUALITY_SETTINGS = {
    "screen": "/screen",
    "ebook": "/ebook",
    "printer": "/printer",
    "prepress": "/prepress"
}


def create_default_settings():
    config_content =
"""
; ==========================================
; PDF 壓縮設定
; ==========================================
;
; 可用品質:
;
; screen   = 最小檔案,適合螢幕閱讀
; ebook    = 一般文件,推薦使用
; printer  = 列印品質
; prepress = 印刷品質
;
; 修改 quality 的值即可
;
; ==========================================

[default]
quality = ebook

; quality = screen
; quality = printer
; quality = prepress
"""

    with open(SETTINGS_FILE, "w", encoding="utf-8") as f:
        f.write(config_content)


def load_settings():
    if not os.path.exists(SETTINGS_FILE):
        create_default_settings()
        print(f"📄 已建立預設設定檔: {SETTINGS_FILE}")

    config = configparser.ConfigParser()
    config.read(SETTINGS_FILE, encoding="utf-8")

    quality = config.get(
        "default",
        "quality",
        fallback="ebook"
    ).lower()

    if quality not in QUALITY_SETTINGS:
        print(
            f"⚠ settings.ini 中的 quality='{quality}' 無效"
        )
        print("⚠ 已自動改用 ebook")
        quality = "ebook"

    return quality


def check_ghostscript():
    gs = shutil.which("gswin64c") or shutil.which("gs")

    if gs is None:
        print("❌ [未安裝 Ghostscript]")

        if platform.system() == "Windows":
            print("👉 請下載 Windows 版本 (gswin64)")
        else:
            print("👉 請下載對應系統版本")

        print("👉 即將開啟下載頁面...")

        webbrowser.open(
            "https://www.ghostscript.com/download/gsdnld.html"
        )

        print("⚠ 若已安裝,請確認 Ghostscript 已加入 PATH")

        sys.exit(1)

    return gs


def compress_pdf(
    gs_command,
    input_path,
    output_path,
    quality
):
    cmd = [
        gs_command,
        "-sDEVICE=pdfwrite",
        "-dCompatibilityLevel=1.4",
        f"-dPDFSETTINGS={QUALITY_SETTINGS[quality]}",
        "-dNOPAUSE",
        "-dQUIET",
        "-dBATCH",
        f"-sOutputFile={output_path}",
        input_path
    ]

    result = subprocess.run(
        cmd,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.PIPE,
        text=True
    )

    if result.returncode != 0:
        raise RuntimeError(result.stderr)


def process_file(
    gs_command,
    file,
    quality
):
    input_path = os.path.join(INPUT_DIR, file)

    name, ext = os.path.splitext(file)

    output_path = os.path.join(
        OUTPUT_DIR,
        f"{name}_compressed{ext}"
    )

    compress_pdf(
        gs_command,
        input_path,
        output_path,
        quality
    )

    original_size = os.path.getsize(input_path)
    compressed_size = os.path.getsize(output_path)

    print(f"✔ {file}")
    print(f"   原始: {original_size / 1024:.2f} KB")
    print(f"   壓縮: {compressed_size / 1024:.2f} KB")

    if compressed_size >= original_size:
        print("   ⚠ 壓縮後反而變大,已刪除壓縮檔\n")
        os.remove(output_path)
        return original_size, original_size

    reduction = original_size - compressed_size
    ratio = reduction / original_size * 100

    print(f"   減少: {reduction / 1024:.2f} KB")
    print(f"   壓縮率: {ratio:.2f}%\n")

    return original_size, compressed_size


def main():
    default_quality = load_settings()

    parser = argparse.ArgumentParser(
        description="PDF 批次壓縮工具"
    )

    parser.add_argument(
        "--quality",
        choices=QUALITY_SETTINGS.keys(),
        default=default_quality,
        help=f"壓縮品質 (預設: {default_quality})"
    )

    args = parser.parse_args()

    print(f"🔧 壓縮模式: {args.quality}")
    print()

    gs_command = check_ghostscript()

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

        print(
            f"📁 已建立資料夾: {INPUT_DIR}"
        )
        print("請放入 PDF 後重新執行")

        return

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

    files = [
        f for f in os.listdir(INPUT_DIR)
        if f.lower().endswith(".pdf")
    ]

    if not files:
        print("📂 input 資料夾內沒有 PDF")
        return

    total_original = 0
    total_compressed = 0

    for file in files:
        try:
            original, compressed = process_file(
                gs_command,
                file,
                args.quality
            )

            total_original += original
            total_compressed += compressed

        except Exception as e:
            print(f"✖ 失敗: {file}")
            print(e)
            print()

    print("================================")

    if total_original > 0:
        reduction = total_original - total_compressed
        ratio = reduction / total_original * 100

        print(
            f"原始總大小: "
            f"{total_original / 1024 / 1024:.2f} MB"
        )

        print(
            f"壓縮總大小: "
            f"{total_compressed / 1024 / 1024:.2f} MB"
        )

        print(
            f"節省空間: "
            f"{reduction / 1024 / 1024:.2f} MB"
        )

        print(
            f"總壓縮率: "
            f"{ratio:.2f}%"
        )

    print("================================")
    os.system("PAUSE")


if __name__ == "__main__":
    main()

















2026年5月19日 星期二

只要點兩下,就能將input資料夾內所有m4a 轉檔為 mp3

         最近需要將m4a檔案轉檔為mp3,所以寫python程式來處理。希望將很多的m4a放進input資料夾內,只要點兩下滑鼠就能將這些m4a 通通轉檔為 mp3。
         Recently, I needed to convert M4A files into MP3 format, so I wrote a Python program to handle it. The idea is to place multiple M4A files into an input folder, then simply double-click the program to automatically convert all the M4A files into MP3 files.

下載檔案解壓密碼:demo1234
Here is the website where you can download the program and find instructions:
Download。Extraction Password: demo1234
使用教學(Instructional videos):


以下是開發過程與原始碼 (Development process and code):
01.安裝 python 套件(Install Python packages.)
pip install pydub

02.下載 ffmpeg 並加入 PATH (Download FFmpeg and add it to the system PATH.)
程式名稱(Program name):install_ffmpeg.bat
程式內容(Code):
@echo off
:: 檢查是否為系統管理員
net session >nul 2>&1
if %errorLevel% neq 0 (
    echo 正在要求系統管理員權限...
    powershell -Command "Start-Process '%~f0' -Verb RunAs"
    exit /b
)

setlocal

echo.
echo ===== 安裝 FFmpeg =====
echo.

REM 建立 ffmpeg 資料夾
if not exist C:\ffmpeg (
    mkdir C:\ffmpeg
)

REM 下載 ffmpeg
echo 下載 FFmpeg...
powershell -Command ^
"Invoke-WebRequest -Uri https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-essentials.zip -OutFile C:\ffmpeg\ffmpeg.zip"

REM 解壓縮
echo 解壓縮中...
powershell -Command ^
"Expand-Archive -Path C:\ffmpeg\ffmpeg.zip -DestinationPath C:\ffmpeg -Force"

REM 找到 bin 路徑
for /d %%i in (C:\ffmpeg\ffmpeg-*) do (
    set "FFMPEG_BIN=%%i\bin"
)

REM 加入系統 PATH
echo 加入 PATH...
setx PATH "%PATH%;%FFMPEG_BIN%" /M

echo.
echo ===== FFmpeg 安裝完成 =====
echo.
echo 請重新開啟 CMD 或 PowerShell
echo 測試指令:
echo ffmpeg -version
echo.

pause

03.python 程式名稱(Python script filename.):pyM4a2Mp3.py
程式內容(Code):
from pydub import AudioSegment
import os

input_folder = "input"
output_folder = "output"

# 如果 output_folder 不存在就建立
if not os.path.exists(output_folder):
    os.makedirs(output_folder)

for file in os.listdir(input_folder):
    if file.endswith(".m4a"):
        m4a_path = os.path.join(input_folder, file)

        mp3_filename = os.path.splitext(file)[0] + ".mp3"
        mp3_path = os.path.join(output_folder, mp3_filename)

        # 讀取 m4a
        audio = AudioSegment.from_file(m4a_path, format="m4a")

        # 輸出 mp3
        audio.export(mp3_path, format="mp3")

        print(f"已轉換: {file} -> {mp3_filename}")

print("全部轉換完成")

2026年5月16日 星期六

只要點兩下,就能依據文字檔內容,創建對應的資料夾

         最近針對書本的目錄,需要創建相對應的資料夾。過去要找到該書的目錄網頁,一行一行地複製網頁文字,再一行一行地創建資料夾、重新命名、貼上。或是直接依據該書的紙本目錄,一行一行地看,創建資料夾、重新命名、一行一行地打字。
        Recently, I often need to create corresponding folders based on a book’s table of contents. In the past, I had to find the webpage containing the book’s contents, copy the text line by line, and then create folders one by one, rename them, and paste the titles manually. Another method was to look at the printed table of contents and type each line manually while creating and renaming folders one at a time.
         總覺得速度很慢,希望能夠將目錄網頁內容複製(或打入)到一個文字檔,程式依據該文字檔內容,一行一行地創建對應的資料夾。
         I always felt this process was too slow. I hope to be able to copy the contents from a webpage (or type them in) into a text file, and then have a program automatically create the corresponding folders line by line according to the contents of that text file.


下載檔案解壓密碼:demo1234
Here is the website where you can download the program and find instructions:
Download。Extraction Password: demo1234
使用教學(Instructional videos):








以下是開發過程與原始碼 (Development process and code):
程式名稱(Program name):pyTxt2Folder.py
程式內容(Code):
import os

# 開啟 input.txt,逐行讀取內容
for folder_name in open("InputFileName.txt", encoding="utf-8"):

    # 移除前後空白與換行符號
    folder_name = folder_name.strip()

    # 如果該行不是空白
    if folder_name:

        # 建立資料夾
        # exist_ok=True 表示資料夾已存在時不會報錯
        os.makedirs(folder_name, exist_ok=True)

        # 顯示建立成功訊息
        print(f"已建立資料夾:{folder_name}")

2026年4月28日 星期二

只要點兩下,就能將input資料夾內所有PDF進行容量壓縮-版本01

系列文章:
01.python 不管何時何地,只要點兩下,資料夾內的所有pdf都會合併成一個pdf
https://skjhcreator.blogspot.com/2022/06/pythonpdfpdf.html
02.python 只要點兩下,分別對各資料夾內的pdf合併,合併後的檔名要讓人知道來自哪個資料夾 
https://skjhcreator.blogspot.com/2022/06/python-pdf.html
03. 只要點兩下,就能將一堆的Doc與Docx 轉成 PDF
03.https://skjhcreator.blogspot.com/2023/05/docdocx-pdf.html
04.只要點兩下,就能將一堆的JPG轉成一個PDF,並以JPG所在的資料夾名稱為PDF的檔名
04.https://skjhcreator.blogspot.com/2023/06/jpgpdfjpgpdf.html
05.只要點兩下,就能將放進input的一堆PDF轉成各自的WORD
05.https://skjhcreator.blogspot.com/2023/10/inputpdfword.html
06.只要點兩下,就能將放進input的一堆PDF轉成在ouput資料夾內的各自的WORD 
06.https://skjhcreator.blogspot.com/2023/10/inputpdfouputword.html
07.只要點兩下,就能夠將InputAndOutput資料夾底下的子子孫孫資料夾內所有Word通通轉成PDF
07.https://skjhcreator.blogspot.com/2024/09/word-word-pdf.html
08.只要點兩下,就可以將資料夾input內的所有Word通通轉成一個PDF
08.https://skjhcreator.blogspot.com/2025/07/inputwordpdf.html
09.只要點兩下兩次,就能依照設定拆分指定PDF頁數並合併成設定好的一個PDF
09.https://skjhcreator.blogspot.com/2025/09/pdfpdf.html
10.只要點兩下,就能將input資料夾內所有PDF進行容量壓縮-版本01
10.https://skjhcreator.blogspot.com/2026/04/inputpdf.html

Just double-click to compress all PDFs in the input folder.

        最近要上傳一大堆的PDF,常常因為PDF內的照片未經壓縮,導致整體容量過大。上傳時又因容量過大,導致無法上傳。上傳網站要求多少容量內的PDF才能上傳。問題是PDF不是我做的,偏偏又要發回或通知原主,要做PDF壓縮,才能上傳。如此的一來一往,浪費很多時間。能不能有個程式,讓我點個兩下就能將這些PDF進行壓縮,而不用再跟原主溝通?

        Recently, I’ve had to upload a large number of PDFs, but they’re often too big because the images inside them haven’t been compressed. As a result, the files exceed the upload size limit and can’t be uploaded. The website requires PDFs to be under a certain size, but the problem is that I didn’t create these PDFs. I end up having to send them back or notify the original creator to compress them before I can upload them. This back-and-forth wastes a lot of time.

        Is there a program that would let me simply double-click and compress these PDFs myself, without needing to communicate with the original creator?

下載檔案解壓密碼:demo1234
Here is the website where you can download the program and find instructions:
Download。Extraction Password: demo1234
使用教學(Instructional videos):




方法:Python + Ghostscript
一、下載與安裝 Ghostscript
到 https://www.ghostscript.com/download/gsdnld.html 下載後,點兩下進行安裝

二、Python 程式碼
檔案:pyPdfCompress.py
檔案內容:import os
import subprocess
import shutil
import webbrowser
import sys
import argparse
import platform

INPUT_DIR = "input"
OUTPUT_DIR = "output"

quality_settings = {
    "screen": "/screen",
    "ebook": "/ebook",
    "printer": "/printer",
    "prepress": "/prepress"
}


def check_ghostscript():
    gs = shutil.which("gswin64c") or shutil.which("gs")

    if gs is None:
        print("[未安裝Ghostscript]")

        if platform.system() == "Windows":
            print("請下載 Windows 版本 (gswin64)")
        else:
            print("請下載對應系統版本")

        print("即將開啟下載頁面...")

        webbrowser.open("https://www.ghostscript.com/download/gsdnld.html")

        print("若已安裝,請確認 Ghostscript 已加入 PATH")

        sys.exit(1)

    return gs


def compress_pdf(gs_command, input_path, output_path, quality):
    cmd = [
        gs_command,
        "-sDEVICE=pdfwrite",
        "-dCompatibilityLevel=1.4",
        f"-dPDFSETTINGS={quality_settings.get(quality, '/ebook')}",
        "-dNOPAUSE",
        "-dQUIET",
        "-dBATCH",
        f"-sOutputFile={output_path}",
        input_path
    ]

    result = subprocess.run(cmd, capture_output=True, text=True)

    if result.returncode != 0:
        raise RuntimeError(result.stderr)


def process_file(gs_command, file, quality):
    input_path = os.path.join(INPUT_DIR, file)

    name, ext = os.path.splitext(file)
    output_path = os.path.join(OUTPUT_DIR, f"{name}_compressed{ext}")

    compress_pdf(gs_command, input_path, output_path, quality)

    original_size = os.path.getsize(input_path) / 1024
    compressed_size = os.path.getsize(output_path) / 1024

    print(f"✔ {file}")
    print(f"   原始: {original_size:.2f} KB")
    print(f"   壓縮: {compressed_size:.2f} KB")

    if compressed_size >= original_size:
        print(" 壓縮後反而變大,已刪除壓縮檔\n")
        os.remove(output_path)
        return

    reduction = original_size - compressed_size
    ratio = (1 - compressed_size / original_size) * 100

    print(f"   減少: {reduction:.2f} KB")
    print(f"   壓縮率: {ratio:.2f}%\n")


def main():
    parser = argparse.ArgumentParser(description="PDF 批次壓縮工具")
    parser.add_argument(
        "--quality",
        choices=quality_settings.keys(),
        default="ebook",
        help="壓縮品質 (預設: ebook)"
    )
    args = parser.parse_args()

    gs_command = check_ghostscript()

    if not os.path.exists(INPUT_DIR):
        os.makedirs(INPUT_DIR)
        print(f"📁 已建立資料夾: {INPUT_DIR},請放入 PDF 後重新執行")
        return

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

    files = [f for f in os.listdir(INPUT_DIR) if f.lower().endswith(".pdf")]

    if not files:
        print("📂 input 資料夾內沒有 PDF")
        return

    for file in files:
        try:
            process_file(gs_command, file, args.quality)
        except Exception as e:
            print(f"✖ 失敗: {file}")
            print(e)
            print()


if __name__ == "__main__":
    main()

Windows 11 建立本地端 AI (Ollama + qwen2.5-coder:7B + docker + webui)

0.自己本地端設備環境:Ultra 7 155H + 32G RAM + Intel Arc Pro Graphics 128M  1. ollama 下載  ->下載後點兩下進行安裝 或是 以系統管理員身分開啟 PowerShell 進行安裝 安裝指令: irm http...