---
# System prepended metadata

title: Xlsx資料表轉HTML Table
tags: [Python系統設計]

---

---
tags: Python系統設計
---
建立時間：20240813
更新時間：20240813
[Python安裝](https://hackmd.io/@1MgXZJtMQgOudU366MROaw/SJpFrHucR)
# Xlsx資料表轉HTML Table
Excel Xlsx To HTML Table
一、操作步驟：
1.1：建立一個新的資料夾 命名為 XlsxToHTMLTable。
(以下步驟都在 XlsxToHTMLTable 資料夾中操作，所有檔案都放在同一個資料夾XlsxToHTMLTable中。)
1.2：建立一個新記事本 命名為 XlsxToHTMLTable.txt。
1.3：將下面程式碼複製到記事本內，存檔。
1.4：將記事本 XlsxToHTMLTable.txt 副檔名修改成 XlsxToHTMLTable.py。
1.5：在建立一個新的記事本 命名為 123.txt。
1.6：將Xlsx檔的內容全選-複製-貼上到123.txt 中，然後存檔。
1.7：雙擊執行XlsxToHTMLTable.py，輸入檔案名 123.txt ，Enter ，輸入分割符號 按下Tab鍵 ，Enter ，等待 123.txt 轉換成 HTML Table 網頁。
(想要執行.py檔案，要先安裝Python程式，請參考置頂連結 [Python安裝](https://hackmd.io/@1MgXZJtMQgOudU366MROaw/SJpFrHucR)，並在安裝時建立PATH路徑，如安裝時沒有建立，請手動建立，手動建立相關資訊，請Google搜尋關鍵字，Python PATH路徑 建立。)
1.8：備註-是將Xlsx檔的內容轉移儲存到Txt中，在透過.py轉換成HTML Tabel網頁。
1.9：適合內容小於6萬筆資料表資料做轉換，幾十萬筆資料以上，建議使用資料庫系統重新設計網頁。
1.10：本程式，暫時不支援插入圖片與連結等其他功能，僅做純文字內容轉換HTML Table網頁。
二、Python程式碼：
```python=
import os
import sys
import re
import tkinter as tk
from tkinter import filedialog

def select_files():
    # 创建主窗口
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口

    # 弹出文件选择对话框
    file_paths = filedialog.askopenfilenames(
        title="选择文件",
        filetypes=[("所有文件", "*.*")],  # 可以根据需要设置文件类型过滤
        initialdir=os.path.dirname(os.path.abspath(__file__))  # 预设路径为脚本所在目录
    )

    # 返回选择的文件路径列表
    return file_paths
    
def extract_file_names(file_name_Input):
    # 使用正则表达式匹配文件名，包括可能没有扩展名的情况
    file_names = re.findall(r'[A-Za-z]:\\[^"]+?\.txt|[^"]+?\.txt|[^"]+', file_name_Input)
    print(file_names)
    # 用于保存符号分割后的结果
    split_file_names = []

    # 检查是否所有文件名都包含 .txt 扩展名
    all_txt_files = all(file.lower().endswith('.txt') for file in file_names)

    # 如果所有文件名都包含 .txt 扩展名或符号分割符号为空，则跳过符号分割
    if not all_txt_files:
        # 手动输入符号分割符号
        symbol_delimiter = input("请输入符号分割符号（例如：制表符 \\t 或空格）：")
        if symbol_delimiter:
            # 对不带 .txt 的部分进行符号分割，其他部分保持不变
            for file in file_names:
                if not file.lower().endswith('.txt'):
                    split_file_names.extend(re.split(symbol_delimiter, file))
                else:
                    split_file_names.append(file)
            # 处理符号分割后的文件名，确保每个文件名都有 .txt 扩展名
            file_names = [f if f.lower().endswith('.txt') else f + '.txt' for f in split_file_names]
        else:
            file_names = [f if f.lower().endswith('.txt') else f + '.txt' for f in file_names]
    
    return file_names

def convert_txt_to_html():
    # 获取.py脚本所在的目录
    script_directory = os.path.dirname(os.path.abspath(__file__))

    # 手动输入TXT文件名称，并检查是否有.txt扩展名
    file_name_Input = input("请输入文件名（例如：C:\\path\\to\\file1.txt,C:\\path\\to\\file2,C:\\path\\to\\file3.txt）。\n输入 '(Select File)&(SF)' 以弹出文件选择对话框：")

    # 处理特殊关键字以弹出文件选择对话框
    if file_name_Input.lower() == '(select file)' or file_name_Input.lower() == '(sf)':
        # 调用文件选择对话框
        file_paths = select_files()
        file_names = list(file_paths)  # 使用选择的文件路径
    else:
        # 处理输入内容，提取文件名
        file_names = extract_file_names(file_name_Input)
        
    # 输出处理后的文件名
    print(file_names)
        
    # 手动输入TXT文件中的数据分隔符
    data_delimiter = input("请输入TXT文件中的数据分隔符号（例如：逗号,）：")

    for file_name in file_names:
        try:
            # 确定文件路径
            if os.path.isabs(file_name):
                file_path = file_name
            else:
                file_path = os.path.join(script_directory, file_name)

            print(f"读取文件路径: {file_path}")

            # 读取指定的TXT文件内容
            with open(file_path, 'r', encoding='utf-8') as file:
                lines = file.readlines()

            # 将TXT内容转换为HTML表格
            html_table = "<table id='datatable' border='1'>\n"
            header = True
            for line in lines:
                cells = line.strip().split(data_delimiter)
                if header:
                    html_table += "  <tr>\n"
                    for cell in cells:
                        html_table += f"    <th>{cell}</th>\n"
                    html_table += "  </tr>\n"
                    header = False
                else:
                    html_table += "  <tr>\n"
                    for cell in cells:
                        html_table += f"    <td>{cell}</td>\n"
                    html_table += "  </tr>\n"
            html_table += "</table>"

            # 提取文件名部分，去掉路径和扩展名
            base_name = os.path.splitext(os.path.basename(file_name))[0]
            output_file_name = base_name + '.html'

            # 确定输出文件的路径
            output_file_path = os.path.join(os.path.dirname(file_path), output_file_name)

            # 构建完整的HTML页面内容
            html_content = f"""
            <html>
        <head>
            <title>{base_name}</title>
            <style>
                table {{ width: 100%; border-collapse: collapse; }}
                th, td {{ border: 1px solid black; padding: 8px; text-align: left; }}
                th {{ background-color: var(--th-bg-color); color: var(--th-font-color); font-weight: bold; }}
                # tr:nth-child(even) td {{ background-color: var(--odd-color); color: var(--odd-font-color); }}
                # tr:nth-child(odd) td {{ background-color: var(--even-color); color: var(--even-font-color); }}
            </style>
            <script>
            
				function filterTable() {{
					var input = document.getElementById('search-input').value.toLowerCase();
					var rows = document.getElementById('datatable').getElementsByTagName('tr');
					var filterGroups = input.split(' '); // 以空格分隔的筛选条件
					var matchCount = 0; // 记录符合条件的行数

					for (var i = 1; i < rows.length; i++) {{
						var cells = rows[i].getElementsByTagName('td');
						var cellText = Array.from(cells).map(cell => cell.innerText.toLowerCase());
						var match = false; // 是否符合条件
						var exclude = false; // 是否符合排除条件

						// 遍历每个条件组
						for (var group of filterGroups) {{
							var isExclusion = group.startsWith('!'); // 判断是否为排除条件
							var conditions = isExclusion ? group.substring(1).split('-') : group.split('-'); // 处理排除条件

							if (isExclusion) {{
								// 处理排除条件
								if (conditions.length > 0 && conditions[0] !== "") {{
									// 判断排除条件是否都匹配
									if (conditions.every(condition => cellText.some(text => text.includes(condition)))) {{
										exclude = true; // 符合排除条件
									}}
								}}
							}} else {{
								// 处理普通条件
								if (conditions.length === 1) {{
									if (cellText.some(text => text.includes(conditions[0]))) {{
										match = true; // 符合条件
									}}
								}} else {{
									if (conditions.every(condition => cellText.some(text => text.includes(condition)))) {{
										match = true; // 符合所有条件
									}}
								}}
							}}
						}}

						// 根据是否符合排除条件以及其他条件来显示或隐藏行
						rows[i].style.display = (match && !exclude) ? '' : 'none';
						if (match && !exclude) {{
							matchCount++;
						}}
					}}

					// 更新显示的颜色
					applyRowColors();

					// 显示符合条件的行数
					document.getElementById('result-count').innerText = '符合条件的行数: ' + matchCount;
				}}

                function showAll() {{
                    var rows = document.getElementById('datatable').getElementsByTagName('tr');
                    for (var i = 1; i < rows.length; i++) {{
                        rows[i].style.display = '';
                    }}

                    // 恢復原始顏色
                    applyRowColors();

                    // 清除結果顯示
                    document.getElementById('result-count').innerText = '';
                }}

                function applyRowColors() {{
                    var table = document.getElementById('datatable');
                    var rows = table.getElementsByTagName('tr');
                    
                    var evenRow = true; // 用於記錄當前行是奇數行還是偶數行
                    for (var i = 1; i < rows.length; i++) {{
                        if (rows[i].style.display !== 'none') {{
                            rows[i].style.backgroundColor = evenRow 
                                ? document.getElementById('evenColor').value
                                : document.getElementById('oddColor').value;
                            rows[i].style.color = evenRow 
                                ? document.getElementById('evenFontColor').value
                                : document.getElementById('oddFontColor').value;
                            evenRow = !evenRow; // 切換行的顏色
                        }}
                    }}
                }}  


                // 設置顏色選擇器的事件處理器
                function setupColorPickers() {{
                    var thBgColorPicker = document.getElementById('thBgColor');
                    var thFontColorPicker = document.getElementById('thFontColor');
                    var oddColorPicker = document.getElementById('oddColor');
                    var evenColorPicker = document.getElementById('evenColor');
                    var oddFontColorPicker = document.getElementById('oddFontColor');
                    var evenFontColorPicker = document.getElementById('evenFontColor');
                    
                    // 初始化顏色變量
                    document.documentElement.style.setProperty('--th-bg-color', thBgColorPicker.value);
                    document.documentElement.style.setProperty('--th-font-color', thFontColorPicker.value);
                    document.documentElement.style.setProperty('--odd-color', oddColorPicker.value);
                    document.documentElement.style.setProperty('--even-color', evenColorPicker.value);
                    document.documentElement.style.setProperty('--odd-font-color', oddFontColorPicker.value);
                    document.documentElement.style.setProperty('--even-font-color', evenFontColorPicker.value);
                    
                    thBgColorPicker.oninput = function() {{
                        document.documentElement.style.setProperty('--th-bg-color', thBgColorPicker.value);
                    }};
                    
                    thFontColorPicker.oninput = function() {{
                        document.documentElement.style.setProperty('--th-font-color', thFontColorPicker.value);
                    }};
                    
                    oddColorPicker.oninput = function() {{
                        document.documentElement.style.setProperty('--odd-color', oddColorPicker.value);
                        applyRowColors();
                    }};
                    
                    evenColorPicker.oninput = function() {{
                        document.documentElement.style.setProperty('--even-color', evenColorPicker.value);
                        applyRowColors();
                    }};
                    
                    oddFontColorPicker.oninput = function() {{
                        document.documentElement.style.setProperty('--odd-font-color', oddFontColorPicker.value);
                        applyRowColors();
                    }};
                    
                    evenFontColorPicker.oninput = function() {{
                        document.documentElement.style.setProperty('--even-font-color', evenFontColorPicker.value);
                        applyRowColors();
                    }};
                }}

                // window.onload = setupColorPickers;
                // 在頁面加載時執行
                window.onload = function() {{
                    setupColorPickers();
                    showAll(); // 在頁面加載時自動執行showAll以應用顏色
                    
                    const input = document.getElementById('search-input');
                    input.style.width = (input.placeholder.length + 17) + 'ch'; // 根據 placeholder 長度設置寬度
                }};
            </script>
        </head>
        <body>
            <h1>{base_name}</h1>
            <input type="text" id="search-input" placeholder="輸入條件以空格分隔，連字符組合如：A B-C-D !E" onkeyup="filterTable()">
            <button onclick="showAll()">顯示完整資料</button>
            <p id="result-count"></p>
            <label for="thBgColor">表頭背景色:</label>
            <input type="color" id="thBgColor" value="#000000">
            <label for="thFontColor">表頭字體色:</label>
            <input type="color" id="thFontColor" value="#ffffff">
            <label for="evenColor">奇數行背景色:</label>
            <input type="color" id="evenColor" value="#ffffff">
            <label for="evenFontColor">奇數行字體色:</label>
            <input type="color" id="evenFontColor" value="#000000">
            <label for="oddColor">偶數行背景色:</label>
            <input type="color" id="oddColor" value="#f2f2f2">
            <label for="oddFontColor">偶數行字體色:</label>
            <input type="color" id="oddFontColor" value="#000000">
            {html_table}
        </body>
        </html>
        """

            # 打印 HTML 内容进行调试
            # print(html_content)

            # 将HTML内容写入输出文件
            with open(output_file_path, 'w', encoding='utf-8') as file:
                file.write(html_content)

            print(f"HTML 文件已保存到: {output_file_path}")

        except Exception as e:
            print(f"处理文件 {file_name} 时发生错误: {e}")

# 调用函数进行转换
convert_txt_to_html()

input()

```