EPUB转TXT格式转换工具

2026年05月29日15:58:05 发表评论 热度11 ℃

EPUB转TXT格式转换工具是瓜皮猪借助AI编写的一款电子书转换工具,功能非常简单就是将EPUB格式的电子书转TXT格式。

起因是同事找想下载一部小说放到手里观看,并且使用博主推荐的SoNovel-交互式小说下载器已经下载好图书,不过因为他没看说明,没有修改配置文件导致下载的格式是EPUB,网上找的转换软件电子书超过一定大小就需要收费,于是就让我帮他处理。

其实修改一下配置文件,或者换个工具照样能下载到TXT格式的电子书,不过既然有要求咱就解决不是,直接打开AI,丢给AI需求,然后接杯水的功夫,代码就出来了。

运行后还行,就打包分享出来,需要的朋友直接拿去。

EPUB转TXT格式转换工具

使用说明

打开软件,选择EPUB文件和保存目录。调整一下转换选项,一般默认即可,除非出现乱码,需要修改一下编码格式。

然后点击「开始转换」按钮即可。

小说下载工具

如果想直接下载TXT格式的小说,可以尝试下面工具

SoNovel-交互式小说下载器看文章说明修改一下配置文件,很简单)

EhPG小说下载器 (使用时可能间歇抽风,可以多尝试几次)

EPUB转TXT格式转换工具源代码

动手能力强的同学可以对源代码自行修改

  1. import tkinter as tk
  2. from tkinter import filedialog, messagebox
  3. import ttkbootstrap as ttk
  4. from ttkbootstrap.constants import *
  5. import os
  6. import ebooklib
  7. from ebooklib import epub
  8. from bs4 import BeautifulSoup
  9. import threading
  10. import re
  11. from pathlib import Path
  12. import time
  13. class EPUBToTXTConverter:
  14.     def __init__(self, root):
  15.         self.root = root
  16.         self.root.title("EPUB转TXT格式转换工具")
  17.         # 设置窗口大小和位置
  18.         window_width = 1285
  19.         window_height = 815
  20.         screen_width = root.winfo_screenwidth()
  21.         screen_height = root.winfo_screenheight()
  22.         center_x = int(screen_width/2 - window_width/2)
  23.         center_y = int(screen_height/2 - window_height/2)
  24.         self.root.geometry(f'{window_width}x{window_height}+{center_x}+{center_y}')
  25.         # 设置最小窗口大小
  26.         self.root.minsize(700, 600)
  27.         # 变量
  28.         self.input_file = tk.StringVar()
  29.         self.output_dir = tk.StringVar()
  30.         self.status_text = tk.StringVar(value="就绪,等待操作...")
  31.         self.progress_value = tk.DoubleVar(value=0)
  32.         self.file_info = tk.StringVar(value="")
  33.         # 转换设置
  34.         self.encoding_var = tk.StringVar(value="utf-8")
  35.         self.remove_empty_lines = tk.BooleanVar(value=True)
  36.         self.preserve_paragraphs = tk.BooleanVar(value=True)
  37.         self.add_chapter_markers = tk.BooleanVar(value=True)
  38.         self.setup_ui()
  39.         self.setup_styles()
  40.     def setup_styles(self):
  41.         """配置自定义样式"""
  42.         style = ttk.Style()
  43.         # 配置标题样式
  44.         style.configure('Title.TLabel',
  45.                        font=('Microsoft YaHei UI', 18, 'bold'),
  46.                        foreground=style.colors.primary)
  47.         # 配置副标题样式
  48.         style.configure('Subtitle.TLabel',
  49.                        font=('Microsoft YaHei UI', 9),
  50.                        foreground=style.colors.secondary)
  51.         # 配置图标按钮样式
  52.         style.configure('Icon.TButton',
  53.                        font=('Microsoft YaHei UI', 9))
  54.         # 配置转换按钮样式
  55.         style.configure('Convert.TButton',
  56.                        font=('Microsoft YaHei UI', 11, 'bold'),
  57.                        padding=(30, 10))
  58.         # 配置状态标签样式
  59.         style.configure('Status.TLabel',
  60.                        font=('Microsoft YaHei UI', 9))
  61.         style.configure('Success.TLabel',
  62.                        font=('Microsoft YaHei UI', 9),
  63.                        foreground=style.colors.success)
  64.         style.configure('Error.TLabel',
  65.                        font=('Microsoft YaHei UI', 9),
  66.                        foreground=style.colors.danger)
  67.         # 配置Card框架样式
  68.         style.configure('Card.TLabelframe',
  69.                        relief='solid',
  70.                        borderwidth=1)
  71.         style.configure('Card.TLabelframe.Label',
  72.                        font=('Microsoft YaHei UI', 10, 'bold'))
  73.     def setup_ui(self):
  74.         """设置用户界面"""
  75.         # 创建主容器
  76.         main_container = ttk.Frame(self.root, padding=(30, 20))
  77.         main_container.pack(fill=BOTH, expand=YES)
  78.         # 头部区域
  79.         self.create_header(main_container)
  80.         # 分隔线
  81.         separator = ttk.Separator(main_container, bootstyle="primary")
  82.         separator.pack(fill=X, pady=(15, 20))
  83.         # 文件选择区域
  84.         self.create_file_section(main_container)
  85.         # 转换选项区域
  86.         self.create_options_section(main_container)
  87.         # 文件信息显示
  88.         self.create_info_section(main_container)
  89.         # 进度区域
  90.         self.create_progress_section(main_container)
  91.         # 按钮区域
  92.         self.create_button_section(main_container)
  93.         # 底部状态栏
  94.         self.create_status_bar()
  95.     def create_header(self, parent):
  96.         """创建头部区域"""
  97.         header_frame = ttk.Frame(parent)
  98.         header_frame.pack(fill=X, pady=(0, 10))
  99.         # 左侧标题
  100.         left_frame = ttk.Frame(header_frame)
  101.         left_frame.pack(side=LEFT)
  102.         # 图标和标题
  103.         title_container = ttk.Frame(left_frame)
  104.         title_container.pack(fill=X)
  105.         # 使用emoji作为图标
  106.         icon_label = ttk.Label(title_container, text="📚",
  107.                                font=('Microsoft YaHei UI', 24))
  108.         icon_label.pack(side=LEFT, padx=(0, 10))
  109.         title_frame = ttk.Frame(title_container)
  110.         title_frame.pack(side=LEFT)
  111.         title_label = ttk.Label(title_frame, text="EPUB 转 TXT 转换器",
  112.                                style='Title.TLabel')
  113.         title_label.pack(anchor=W)
  114.         subtitle_label = ttk.Label(title_frame,
  115.                                    text="轻松将电子书转换为纯文本格式",
  116.                                    style='Subtitle.TLabel')
  117.         subtitle_label.pack(anchor=W)
  118.         # 右侧主题切换按钮
  119.         theme_frame = ttk.Frame(header_frame)
  120.         theme_frame.pack(side=RIGHT)
  121.         # 主题切换按钮
  122.         self.theme_btn = ttk.Button(theme_frame, text="🌓 切换主题",
  123.                                     command=self.toggle_theme,
  124.                                     style='Icon.TButton',
  125.                                     bootstyle="outline-secondary")
  126.         self.theme_btn.pack(side=RIGHT)
  127.         # 当前主题标识
  128.         self.theme_label = ttk.Label(theme_frame, text="当前: 浅色模式",
  129.                                      font=('Microsoft YaHei UI', 8),
  130.                                      foreground='gray')
  131.         self.theme_label.pack(side=RIGHT, padx=(0, 10))
  132.     def create_file_section(self, parent):
  133.         """创建文件选择区域"""
  134.         # 使用LabelFrame,去掉padding参数
  135.         file_card = ttk.Labelframe(parent, text="📁 文件设置",
  136.                                    bootstyle="primary",
  137.                                    padding=20)
  138.         file_card.pack(fill=X, pady=(0, 15))
  139.         # 输入文件选择
  140.         input_frame = ttk.Frame(file_card)
  141.         input_frame.pack(fill=X, pady=(0, 15))
  142.         input_label = ttk.Label(input_frame, text="选择EPUB文件:",
  143.                                font=('Microsoft YaHei UI', 10, 'bold'))
  144.         input_label.pack(anchor=W, pady=(0, 5))
  145.         input_row = ttk.Frame(input_frame)
  146.         input_row.pack(fill=X)
  147.         self.file_entry = ttk.Entry(input_row, textvariable=self.input_file,
  148.                                     state='readonly',
  149.                                     font=('Microsoft YaHei UI', 9))
  150.         self.file_entry.pack(side=LEFT, fill=X, expand=YES, padx=(0, 10))
  151.         # 文件选择按钮带图标
  152.         browse_file_btn = ttk.Button(input_row, text="📂 浏览文件",
  153.                                      command=self.select_input_file,
  154.                                      style='Icon.TButton',
  155.                                      bootstyle="outline-primary")
  156.         browse_file_btn.pack(side=RIGHT)
  157.         # 文件类型提示
  158.         file_hint = ttk.Label(input_frame, text="支持的格式: .epub",
  159.                              font=('Microsoft YaHei UI', 8),
  160.                              foreground='gray')
  161.         file_hint.pack(anchor=W, pady=(5, 0))
  162.         # 输出目录选择
  163.         output_frame = ttk.Frame(file_card)
  164.         output_frame.pack(fill=X)
  165.         output_label = ttk.Label(output_frame, text="选择保存目录:",
  166.                                 font=('Microsoft YaHei UI', 10, 'bold'))
  167.         output_label.pack(anchor=W, pady=(0, 5))
  168.         output_row = ttk.Frame(output_frame)
  169.         output_row.pack(fill=X)
  170.         self.dir_entry = ttk.Entry(output_row, textvariable=self.output_dir,
  171.                                    state='readonly',
  172.                                    font=('Microsoft YaHei UI', 9))
  173.         self.dir_entry.pack(side=LEFT, fill=X, expand=YES, padx=(0, 10))
  174.         browse_dir_btn = ttk.Button(output_row, text="📁 浏览目录",
  175.                                    command=self.select_output_dir,
  176.                                    style='Icon.TButton',
  177.                                    bootstyle="outline-primary")
  178.         browse_dir_btn.pack(side=RIGHT)
  179.     def create_options_section(self, parent):
  180.         """创建转换选项区域"""
  181.         options_frame = ttk.Labelframe(parent, text="⚙️ 转换选项",
  182.                                        bootstyle="info",
  183.                                        padding=20)
  184.         options_frame.pack(fill=X, pady=(0, 15))
  185.         # 第一行选项
  186.         first_row = ttk.Frame(options_frame)
  187.         first_row.pack(fill=X, pady=(0, 10))
  188.         # 编码选择
  189.         encoding_frame = ttk.Frame(first_row)
  190.         encoding_frame.pack(side=LEFT, padx=(0, 30))
  191.         encoding_label = ttk.Label(encoding_frame, text="输出编码:",
  192.                                   font=('Microsoft YaHei UI', 9))
  193.         encoding_label.pack(side=LEFT, padx=(0, 10))
  194.         encoding_combo = ttk.Combobox(encoding_frame,
  195.                                       textvariable=self.encoding_var,
  196.                                       values=["utf-8", "utf-8-sig", "gbk", "gb2312", "utf-16"],
  197.                                       state="readonly",
  198.                                       width=12,
  199.                                       font=('Microsoft YaHei UI', 9),
  200.                                       bootstyle="primary")
  201.         encoding_combo.pack(side=LEFT)
  202.         # 第二行选项
  203.         second_row = ttk.Frame(options_frame)
  204.         second_row.pack(fill=X)
  205.         # 删除空行选项
  206.         empty_lines_check = ttk.Checkbutton(second_row,
  207.                                            text="🗑️ 删除多余空行",
  208.                                            variable=self.remove_empty_lines,
  209.                                            bootstyle="round-toggle")
  210.         empty_lines_check.pack(side=LEFT, padx=(0, 20))
  211.         # 保留段落格式选项
  212.         paragraphs_check = ttk.Checkbutton(second_row,
  213.                                           text="📝 保留段落格式",
  214.                                           variable=self.preserve_paragraphs,
  215.                                           bootstyle="round-toggle")
  216.         paragraphs_check.pack(side=LEFT, padx=(0, 20))
  217.         # 章节标记选项
  218.         chapters_check = ttk.Checkbutton(second_row,
  219.                                         text="📑 添加章节标记",
  220.                                         variable=self.add_chapter_markers,
  221.                                         bootstyle="round-toggle")
  222.         chapters_check.pack(side=LEFT)
  223.     def create_info_section(self, parent):
  224.         """创建文件信息显示区域"""
  225.         self.info_frame = ttk.Labelframe(parent, text="📊 文件信息",
  226.                                         bootstyle="secondary",
  227.                                         padding=15)
  228.         self.info_frame.pack(fill=X, pady=(0, 15))
  229.         # 信息显示标签
  230.         self.info_label = ttk.Label(self.info_frame,
  231.                                    text="请选择EPUB文件以查看文件信息",
  232.                                    font=('Microsoft YaHei UI', 9),
  233.                                    foreground='gray')
  234.         self.info_label.pack(fill=X)
  235.     def create_progress_section(self, parent):
  236.         """创建进度显示区域"""
  237.         self.progress_frame = ttk.Labelframe(parent, text="🔄 转换进度",
  238.                                             bootstyle="warning",
  239.                                             padding=15)
  240.         self.progress_frame.pack(fill=X, pady=(0, 15))
  241.         # 进度条
  242.         self.progress_bar = ttk.Progressbar(self.progress_frame,
  243.                                             variable=self.progress_value,
  244.                                             mode='determinate',
  245.                                             bootstyle="success-striped")
  246.         self.progress_bar.pack(fill=X, pady=(0, 10))
  247.         # 进度百分比和状态
  248.         progress_info = ttk.Frame(self.progress_frame)
  249.         progress_info.pack(fill=X)
  250.         self.percentage_label = ttk.Label(progress_info,
  251.                                          text="0%",
  252.                                          font=('Microsoft YaHei UI', 12, 'bold'),
  253.                                          bootstyle="primary")
  254.         self.percentage_label.pack(side=LEFT)
  255.         self.status_label = ttk.Label(progress_info,
  256.                                      textvariable=self.status_text,
  257.                                      font=('Microsoft YaHei UI', 9))
  258.         self.status_label.pack(side=RIGHT)
  259.     def create_button_section(self, parent):
  260.         """创建按钮区域"""
  261.         button_frame = ttk.Frame(parent)
  262.         button_frame.pack(fill=X, pady=(10, 0))
  263.         # 左侧按钮
  264.         left_buttons = ttk.Frame(button_frame)
  265.         left_buttons.pack(side=LEFT)
  266.         # 清空按钮
  267.         clear_btn = ttk.Button(left_buttons, text="🔄 清空设置",
  268.                               command=self.clear_settings,
  269.                               style='Icon.TButton',
  270.                               bootstyle="outline-secondary")
  271.         clear_btn.pack(side=LEFT, padx=(0, 10))
  272.         # 右侧按钮
  273.         right_buttons = ttk.Frame(button_frame)
  274.         right_buttons.pack(side=RIGHT)
  275.         # 退出按钮
  276.         exit_btn = ttk.Button(right_buttons, text="❌ 退出程序",
  277.                              command=self.root.quit,
  278.                              style='Icon.TButton',
  279.                              bootstyle="outline-danger")
  280.         exit_btn.pack(side=RIGHT, padx=(10, 0))
  281.         # 转换按钮(居中)
  282.         center_frame = ttk.Frame(button_frame)
  283.         center_frame.pack(side=TOP, expand=YES)
  284.         self.convert_btn = ttk.Button(center_frame, text="🚀 开始转换",
  285.                                       command=self.start_conversion,
  286.                                       style='Convert.TButton',
  287.                                       bootstyle="success")
  288.         self.convert_btn.pack(pady=(0, 15))
  289.     def create_status_bar(self):
  290.         """创建底部状态栏"""
  291.         status_bar = ttk.Frame(self.root, bootstyle="secondary")
  292.         status_bar.pack(side=BOTTOM, fill=X)
  293.         # 左侧状态信息
  294.         status_left = ttk.Label(status_bar,
  295.                                text="  📍 EPUB转换工具 v1.0 | 支持批量处理",
  296.                                font=('Microsoft YaHei UI', 8),
  297.                                padding=(10, 5))
  298.         status_left.pack(side=LEFT)
  299.         # 右侧状态信息
  300.         status_right = ttk.Label(status_bar,
  301.                                 text="💡 提示: 支持中文路径和文件名 ",
  302.                                 font=('Microsoft YaHei UI', 8),
  303.                                 padding=(10, 5))
  304.         status_right.pack(side=RIGHT)
  305.     def toggle_theme(self):
  306.         """切换主题"""
  307.         current_theme = self.root.style.theme_use()
  308.         if 'dark' in current_theme.lower():
  309.             self.root.style.theme_use('flatly')
  310.             self.theme_label.config(text="当前: 浅色模式")
  311.         else:
  312.             self.root.style.theme_use('darkly')
  313.             self.theme_label.config(text="当前: 深色模式")
  314.     def select_input_file(self):
  315.         """选择EPUB文件"""
  316.         filename = filedialog.askopenfilename(
  317.             title="选择EPUB文件",
  318.             filetypes=[("EPUB files", "*.epub"), ("All files", "*.*")]
  319.         )
  320.         if filename:
  321.             self.input_file.set(filename)
  322.             # 自动设置输出目录
  323.             if not self.output_dir.get():
  324.                 self.output_dir.set(os.path.dirname(filename))
  325.             # 显示文件信息
  326.             self.show_file_info(filename)
  327.     def select_output_dir(self):
  328.         """选择输出目录"""
  329.         directory = filedialog.askdirectory(
  330.             title="选择保存目录"
  331.         )
  332.         if directory:
  333.             self.output_dir.set(directory)
  334.     def show_file_info(self, filepath):
  335.         """显示文件信息"""
  336.         try:
  337.             file_size = os.path.getsize(filepath)
  338.             size_str = self.format_file_size(file_size)
  339.             filename = os.path.basename(filepath)
  340.             modified_time = time.strftime('%Y-%m-%d %H:%M:%S',
  341.                                         time.localtime(os.path.getmtime(filepath)))
  342.             info_text = f"📄 文件名: {filename}  |  📦 大小: {size_str}  |  🕒 修改时间: {modified_time}"
  343.             self.info_label.config(text=info_text)
  344.         except Exception as e:
  345.             self.info_label.config(text=f"无法读取文件信息: {str(e)}")
  346.     def format_file_size(self, size):
  347.         """格式化文件大小"""
  348.         for unit in ['B', 'KB', 'MB', 'GB']:
  349.             if size < 1024.0:
  350.                 return f"{size:.2f} {unit}"
  351.             size /= 1024.0
  352.         return f"{size:.2f} TB"
  353.     def clear_settings(self):
  354.         """清空所有设置"""
  355.         self.input_file.set("")
  356.         self.output_dir.set("")
  357.         self.progress_value.set(0)
  358.         self.percentage_label.config(text="0%")
  359.         self.status_text.set("就绪,等待操作...")
  360.         self.info_label.config(text="请选择EPUB文件以查看文件信息")
  361.         self.progress_bar.configure(bootstyle="success-striped")
  362.     def update_progress(self, value, status=""):
  363.         """更新进度条"""
  364.         self.progress_value.set(value)
  365.         self.percentage_label.config(text=f"{int(value)}%")
  366.         if status:
  367.             self.status_text.set(status)
  368.         self.root.update_idletasks()
  369.     def start_conversion(self):
  370.         """开始转换"""
  371.         if not self.input_file.get():
  372.             messagebox.showerror("错误", "❌ 请选择EPUB文件!")
  373.             return
  374.         if not self.output_dir.get():
  375.             messagebox.showerror("错误", "❌ 请选择保存目录!")
  376.             return
  377.         # 禁用转换按钮
  378.         self.convert_btn.config(state='disabled', text="⏳ 转换中...")
  379.         self.progress_bar.configure(bootstyle="warning-striped")
  380.         # 在单独线程中运行转换
  381.         thread = threading.Thread(target=self.convert_epub_to_txt)
  382.         thread.daemon = True
  383.         thread.start()
  384.     def extract_text_from_epub(self, epub_path):
  385.         """从EPUB文件中提取文本内容"""
  386.         try:
  387.             book = epub.read_epub(epub_path)
  388.             all_text = []
  389.             total_items = len(list(book.get_items()))
  390.             processed = 0
  391.             # 获取所有文档项目
  392.             for item in book.get_items():
  393.                 if item.get_type() == ebooklib.ITEM_DOCUMENT:
  394.                     # 更新进度
  395.                     processed += 1
  396.                     progress = (processed / max(total_items, 1)) * 50  # 前50%用于提取
  397.                     self.root.after(0, self.update_progress, progress,
  398.                                   f"正在提取文本内容... ({processed}/{total_items})")
  399.                     # 使用BeautifulSoup解析HTML内容
  400.                     soup = BeautifulSoup(item.get_content(), 'html.parser')
  401.                     # 提取标题(如果启用章节标记)
  402.                     if self.add_chapter_markers.get():
  403.                         for heading in soup.find_all(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']):
  404.                             heading_text = heading.get_text().strip()
  405.                             if heading_text:
  406.                                 level = int(heading.name[1])
  407.                                 prefix = '=' * level + ' '
  408.                                 all_text.append(prefix + heading_text)
  409.                                 all_text.append('')
  410.                     # 提取段落文本
  411.                     for paragraph in soup.find_all('p'):
  412.                         text = paragraph.get_text().strip()
  413.                         if text:
  414.                             all_text.append(text)
  415.                             if self.preserve_paragraphs.get():
  416.                                 all_text.append('')
  417.                     # 提取其他文本元素
  418.                     for element in soup.find_all(['div', 'span', 'li']):
  419.                         if not element.find(['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']):
  420.                             text = element.get_text().strip()
  421.                             if text and len(text) > 20:
  422.                                 all_text.append(text)
  423.                                 if self.preserve_paragraphs.get():
  424.                                     all_text.append('')
  425.             # 更新进度到75%
  426.             self.root.after(0, self.update_progress, 75, "文本提取完成,正在处理格式...")
  427.             return '\n'.join(all_text)
  428.         except Exception as e:
  429.             raise Exception(f"读取EPUB文件失败: {str(e)}")
  430.     def process_text(self, text):
  431.         """处理提取的文本"""
  432.         # 处理空行
  433.         if self.remove_empty_lines.get():
  434.             text = re.sub(r'\n\s*\n', '\n\n', text)
  435.             text = text.strip()
  436.         # 如果不保留段落格式,将所有文本合并
  437.         if not self.preserve_paragraphs.get():
  438.             lines = [line.strip() for line in text.split('\n') if line.strip()]
  439.             text = ' '.join(lines)
  440.         return text
  441.     def convert_epub_to_txt(self):
  442.         """执行EPUB到TXT的转换"""
  443.         try:
  444.             input_path = self.input_file.get()
  445.             output_dir = self.output_dir.get()
  446.             # 重置进度
  447.             self.root.after(0, self.update_progress, 0, "开始转换...")
  448.             time.sleep(0.1)
  449.             # 获取文件名
  450.             base_name = os.path.splitext(os.path.basename(input_path))[0]
  451.             output_path = os.path.join(output_dir, f"{base_name}.txt")
  452.             # 更新进度
  453.             self.root.after(0, self.update_progress, 10, "正在读取EPUB文件...")
  454.             # 提取文本
  455.             text_content = self.extract_text_from_epub(input_path)
  456.             # 处理文本
  457.             self.root.after(0, self.update_progress, 80, "正在处理文本格式...")
  458.             processed_text = self.process_text(text_content)
  459.             # 保存文件
  460.             self.root.after(0, self.update_progress, 90, "正在保存文件...")
  461.             encoding = self.encoding_var.get()
  462.             # 如果选择utf-8-sig,添加BOM以更好地支持中文
  463.             with open(output_path, 'w', encoding=encoding) as f:
  464.                 f.write(processed_text)
  465.             # 获取文件大小
  466.             file_size = os.path.getsize(output_path)
  467.             size_str = self.format_file_size(file_size)
  468.             # 完成
  469.             self.root.after(0, self.update_progress, 100, "转换完成!")
  470.             self.root.after(0, self.conversion_complete, output_path, size_str)
  471.         except Exception as e:
  472.             self.root.after(0, self.conversion_failed, str(e))
  473.     def conversion_complete(self, output_path, size_str):
  474.         """转换完成回调"""
  475.         self.convert_btn.config(state='normal', text="🚀 开始转换")
  476.         self.progress_bar.configure(bootstyle="success-striped")
  477.         # 更新状态标签样式
  478.         self.status_label.configure(style='Success.TLabel')
  479.         # 显示成功消息
  480.         filename = os.path.basename(output_path)
  481.         success_msg = (f"✅ 转换成功!\n\n"
  482.                       f"📄 输出文件: {filename}\n"
  483.                       f"📦 文件大小: {size_str}\n"
  484.                       f"📁 保存位置: {os.path.dirname(output_path)}")
  485.         # 询问是否打开文件所在目录
  486.         result = messagebox.askyesno(
  487.             "转换成功",
  488.             f"{success_msg}\n\n是否打开文件所在目录?",
  489.             icon='info'
  490.         )
  491.         if result:
  492.             try:
  493.                 os.startfile(os.path.dirname(output_path))
  494.             except:
  495.                 import subprocess
  496.                 subprocess.run(['xdg-open', os.path.dirname(output_path)])
  497.     def conversion_failed(self, error_message):
  498.         """转换失败回调"""
  499.         self.convert_btn.config(state='normal', text="🚀 开始转换")
  500.         self.progress_bar.configure(bootstyle="danger-striped")
  501.         self.progress_value.set(0)
  502.         self.percentage_label.config(text="0%")
  503.         # 更新状态标签样式
  504.         self.status_label.configure(style='Error.TLabel')
  505.         self.status_text.set("转换失败")
  506.         messagebox.showerror("转换失败",
  507.                            f"❌ 转换过程中出现错误:\n\n{error_message}\n\n"
  508.                            "请检查EPUB文件是否完整,并重试。")
  509. def main():
  510.     # 创建主窗口,使用flatly主题
  511.     root = ttk.Window(themename="flatly")
  512.     # 设置窗口图标(如果需要)
  513.     try:
  514.         root.iconbitmap('icon.ico')
  515.     except:
  516.         pass
  517.     # 创建应用
  518.     app = EPUBToTXTConverter(root)
  519.     # 运行应用
  520.     root.mainloop()
  521. if __name__ == "__main__":
  522.     # 检查依赖库
  523.     try:
  524.         import ebooklib
  525.         from bs4 import BeautifulSoup
  526.         import ttkbootstrap
  527.     except ImportError as e:
  528.         print("缺少必要的依赖库。请运行以下命令安装:")
  529.         print("pip install ebooklib beautifulsoup4 ttkbootstrap")
  530.         print("\n或运行: pip install -r requirements.txt")
  531.         # 尝试使用tkinter显示错误信息
  532.         try:
  533.             import tkinter as tk
  534.             from tkinter import messagebox
  535.             root = tk.Tk()
  536.             root.withdraw()
  537.             messagebox.showerror("依赖缺失",
  538.                 "缺少必要的依赖库。\n\n请运行以下命令安装:\n"
  539.                 "pip install ebooklib beautifulsoup4 ttkbootstrap\n\n"
  540.                 "或运行: pip install -r requirements.txt")
  541.             root.destroy()
  542.         except:
  543.             pass
  544.     else:
  545.         main()

 

 

文件下载 资源名称:EPUB转TXT格式转换工具 应用平台:Windows 资源版本:v1.0 资源大小:31.3M
下载地址

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: