---
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()
```