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