不写一行代码,编写可用小工具,所以叫言出法随系列。
目前AI编程适用于:软件小工具、浏览器插件开发、文件处理等。
软件名称:EXCEL到MARKDOWN转换器
软件功能:实现复制EXCEL内容转化为MARKDOWN格式,把MARKDOWN内容粘到大模型软件让大模型帮我检查内容。(类型:我会给你markdown格式内容,检查内容一致性指出错误描述。)
开发工具:Trae

开发过程简单描述:
1、输入指令。2、优化指令。3、发送指令。4、发送错误或优化内容给trea修改。5、开发完成后,要求trea打包成exe.

下载地址:https://download.csdn.net/download/bobodadao/92562537 无需积分。
代码如下:
import tkinter as tk
from tkinter import ttk, messagebox
import pandas as pd
import pyperclip
def get_clipboard_excel():
"""从剪贴板读取Excel内容并返回DataFrame"""
try:
# 优先使用pyperclip直接读取剪贴板内容,手动解析以避免pandas自动添加列名后缀
try:
import pyperclip
clipboard_content = pyperclip.paste()
if not clipboard_content:
messagebox.showerror("错误", "剪贴板中没有可读取的内容")
return None
# 处理单元格内换行的情况
# 当从Excel复制时,单元格内的换行通常会被保留为\n
# 我们需要正确处理这种情况,确保多行单元格被视为单个单元格
# 首先按换行符分割
lines = clipboard_content.strip().split('\n')
if not lines:
messagebox.showerror("错误", "剪贴板中没有可读取的内容")
return None
# 解析数据,处理多行单元格和带引号的单元格
data = []
current_row = []
current_cell = []
in_quoted_cell = False
# 首先将所有内容作为一个整体处理,以正确识别带引号的多行单元格
all_content = clipboard_content.strip()
lines = all_content.split('\n')
# 处理每一行
for line in lines:
# 遍历每个字符以正确处理引号和制表符
for char in line:
if char == '"':
in_quoted_cell = not in_quoted_cell
# 如果我们在引号内
if in_quoted_cell:
# 在引号内,所有字符(包括制表符)都属于当前单元格
current_cell.append(char)
else:
# 不在引号内
if char == '\t':
# 制表符表示当前单元格结束
if current_cell:
cell_content = ''.join(current_cell).strip()
current_row.append(cell_content)
current_cell = []
else:
# 空单元格
current_row.append('')
else:
# 普通字符,开始或继续构建单元格
current_cell.append(char)
# 处理行尾
if in_quoted_cell:
# 如果在引号内,行尾表示单元格内的换行
current_cell.append('\n')
else:
# 不在引号内,行尾表示当前行结束
if current_cell:
cell_content = ''.join(current_cell).strip()
current_row.append(cell_content)
current_cell = []
# 保存当前行
if current_row:
data.append(current_row)
current_row = []
# 处理最后一个单元格
if current_cell:
cell_content = ''.join(current_cell).strip('"').strip()
current_row.append(cell_content)
# 处理最后一行
if current_row:
data.append(current_row)
# 计算最大列数
max_cells = 0
for row in data:
max_cells = max(max_cells, len(row))
# 检查是否有合适的表头(在归一化之前)
# 表头应该满足:长度合理,且与大多数行的长度一致
has_header = False
if len(data) > 1:
# 计算每行的长度
row_lengths = [len(row) for row in data]
# 找到最常见的长度
most_common_length = max(set(row_lengths), key=row_lengths.count)
# 如果第一行的长度等于最常见的长度,且不是1(避免将单列数据误判为表头)
# 同时确保第一行不包含引号(避免将带引号的多行单元格误判为表头)
first_row_has_quotes = any('"' in str(cell) for cell in data[0])
if len(data[0]) == most_common_length and most_common_length > 1 and not first_row_has_quotes:
has_header = True
# 第二次遍历:确保所有行都有相同的列数
normalized_data = []
for row in data:
# 如果行长度不足,补充空字符串
if len(row) < max_cells:
row.extend([''] * (max_cells - len(row)))
# 如果行长度超过,截断
elif len(row) > max_cells:
row = row[:max_cells]
normalized_data.append(row)
if has_header:
# 使用第一行作为列名
columns = normalized_data[0]
rows = normalized_data[1:]
# 创建DataFrame,使用原始列名
df = pd.DataFrame(rows)
df.columns = columns
else:
# 没有合适的表头,使用默认列名
columns = [f"列{i+1}" for i in range(max_cells)]
df = pd.DataFrame(normalized_data, columns=columns)
return df
except Exception as e:
# 显示错误信息并继续
messagebox.showinfo("提示", f"pyperclip解析失败,尝试其他方法: {str(e)}")
# 尝试第一种方法:直接使用pd.read_clipboard()
try:
# 设置keep_default_na=False以避免将空字符串识别为NaN
# 设置index_col=None以避免将第一列作为索引
df = pd.read_clipboard(keep_default_na=False, index_col=None)
if not df.empty:
return df
except:
pass
# 尝试第二种方法:设置header=None,手动处理列名
try:
# 设置keep_default_na=False以避免将空字符串识别为NaN
# 设置index_col=None以避免将第一列作为索引
df = pd.read_clipboard(header=None, keep_default_na=False, index_col=None)
if df.empty:
messagebox.showerror("错误", "剪贴板中没有可读取的内容")
return None
# 尝试自动检测列名
try:
# 检查第一行是否全为字符串(可能是列名)
first_row_is_header = all(isinstance(val, str) for val in df.iloc[0])
if first_row_is_header:
# 将第一行设为列名,删除第一行数据
# 使用原始列名,不允许pandas自动添加后缀
columns = df.iloc[0].tolist()
df = df[1:]
# 确保所有数据行的长度与列数一致
max_columns = len(columns)
rows = []
for _, row in df.iterrows():
row_list = row.tolist()
# 如果行长度不足,补充空字符串
if len(row_list) < max_columns:
row_list.extend([''] * (max_columns - len(row_list)))
# 如果行长度超过,截断
elif len(row_list) > max_columns:
row_list = row_list[:max_columns]
rows.append(row_list)
# 重新创建DataFrame,使用原始列名
df = pd.DataFrame(rows)
df.columns = columns
else:
# 如果第一行不是字符串,使用默认列名
df.columns = [f"列{i+1}" for i in range(df.shape[1])]
except:
# 如果检测失败,使用默认列名
df.columns = [f"列{i+1}" for i in range(df.shape[1])]
return df
except:
pass
except Exception as e:
messagebox.showerror("错误", "无法从剪贴板读取Excel内容:\n" + str(e))
return None
def excel_to_markdown(df):
"""将DataFrame转换为MARKDOWN表格格式"""
if df is None:
return ""
# 获取列名
columns = df.columns.tolist()
# 构建表头,处理表头中的换行符
processed_columns = []
for col in columns:
# 处理表头中的换行符
processed_col = str(col).replace("\n", "<br>")
processed_columns.append(processed_col)
markdown = "| " + " | ".join(processed_columns) + " |\n"
# 构建分隔线
markdown += "| " + " | ".join("---" for _ in columns) + " |\n"
# 构建数据行
for _, row in df.iterrows():
row_data = []
for col in columns:
try:
value = row[col]
# 处理NaN值
if pd.isna(value):
row_data.append("")
else:
# 处理单元格内换行的情况
# 在Markdown中,单元格内的换行需要用<br>标签表示
cell_text = str(value).replace("\n", "<br>")
row_data.append(cell_text)
except:
# 如果出现错误(例如列不存在),添加空字符串
row_data.append("")
markdown += "| " + " | ".join(row_data) + " |\n"
return markdown
class ExcelToMarkdownConverter:
def __init__(self, root):
self.root = root
self.root.title("Excel到MARKDOWN转换器")
self.root.geometry("800x600")
# 创建主框架
main_frame = ttk.Frame(root, padding="10")
main_frame.pack(fill=tk.BOTH, expand=True)
# 创建原始内容展示区域
original_frame = ttk.LabelFrame(main_frame, text="原始Excel内容", padding="10")
original_frame.pack(fill=tk.BOTH, expand=True, pady=5)
self.original_text = tk.Text(original_frame, wrap=tk.WORD, height=10)
self.original_text.pack(fill=tk.BOTH, expand=True)
# 创建转换后内容展示区域
markdown_frame = ttk.LabelFrame(main_frame, text="转换后MARKDOWN内容", padding="10")
markdown_frame.pack(fill=tk.BOTH, expand=True, pady=5)
self.markdown_text = tk.Text(markdown_frame, wrap=tk.WORD, height=10)
self.markdown_text.pack(fill=tk.BOTH, expand=True)
# 创建按钮框架
button_frame = ttk.Frame(main_frame, padding="10")
button_frame.pack(fill=tk.X, pady=5)
# 创建复制按钮
self.copy_button = ttk.Button(button_frame, text="复制MARKDOWN内容", command=self.copy_markdown)
self.copy_button.pack(side=tk.LEFT, padx=5)
# 创建重新读取按钮
self.refresh_button = ttk.Button(button_frame, text="重新读取剪贴板", command=self.refresh_content)
self.refresh_button.pack(side=tk.LEFT, padx=5)
# 初始化时读取剪贴板内容
self.refresh_content()
def copy_markdown(self):
"""复制转换后的MARKDOWN内容到剪贴板"""
markdown_content = self.markdown_text.get(1.0, tk.END).strip()
if markdown_content:
pyperclip.copy(markdown_content)
messagebox.showinfo("成功", "MARKDOWN内容已复制到剪贴板")
else:
messagebox.showwarning("警告", "没有可复制的MARKDOWN内容")
def refresh_content(self):
"""重新读取剪贴板中的Excel内容并更新转换后的MARKDOWN内容"""
df = get_clipboard_excel()
if df is not None:
# 更新原始内容展示
self.original_text.delete(1.0, tk.END)
self.original_text.insert(tk.END, df.to_string(index=False))
# 转换为MARKDOWN并更新展示
markdown_content = excel_to_markdown(df)
self.markdown_text.delete(1.0, tk.END)
self.markdown_text.insert(tk.END, markdown_content)
else:
# 清空展示区域
self.original_text.delete(1.0, tk.END)
self.markdown_text.delete(1.0, tk.END)
if __name__ == "__main__":
root = tk.Tk()
app = ExcelToMarkdownConverter(root)
root.mainloop()
我真闲写这篇文章,你也真闲看到这里,我真羡慕咱俩。