image.png


首先需要安装pandoc

python3.8

pip install  pypandoc

import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import pypandoc
import platform

class PandocConverterApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Pandoc 文档转换工具【大象出品—https://daxiang.tech】")
        self.root.geometry("700x550")
        self.root.resizable(True, True)
        
        # 设置中文字体支持
        self.setup_fonts()
        
        # 输入文件路径
        self.input_file = tk.StringVar()
        # 输出文件路径
        self.output_file = tk.StringVar()
        # 输入格式
        self.input_format = tk.StringVar(value="markdown")
        # 输出格式
        self.output_format = tk.StringVar(value="docx")
        # 其他参数
        self.standalone = tk.BooleanVar(value=True)
        self.toc = tk.BooleanVar(value=False)
        self.number_sections = tk.BooleanVar(value=False)
        self.extra_args = tk.StringVar(value="")
        
        # 支持的格式列表(简化版,pandoc支持更多格式)
        self.supported_formats = [
            "markdown", "rst", "html", "latex", "docx", 
            "odt", "pdf", "epub", "txt", "json"
        ]
        
        self.create_widgets()
    
    def setup_fonts(self):
        """设置中文字体支持"""
        system = platform.system()
        if system == "Windows":
            default_font = ("SimHei", 10)
        elif system == "Darwin":  # macOS
            default_font = ("Heiti TC", 10)
        else:  # Linux等其他系统
            default_font = ("WenQuanYi Micro Hei", 10)
            
        # 设置全局字体
        app_style = ttk.Style()
        app_style.configure(".", font=default_font)
    
    def create_widgets(self):
        """创建界面组件"""
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 输入文件选择
        ttk.Label(main_frame, text="输入文件:").grid(row=0, column=0, sticky=tk.W, pady=5)
        ttk.Entry(main_frame, textvariable=self.input_file, width=50).grid(row=0, column=1, sticky=tk.EW, pady=5)
        ttk.Button(main_frame, text="浏览...", command=self.browse_input).grid(row=0, column=2, padx=5, pady=5)
        
        # 输出文件选择
        ttk.Label(main_frame, text="输出文件:").grid(row=1, column=0, sticky=tk.W, pady=5)
        ttk.Entry(main_frame, textvariable=self.output_file, width=50).grid(row=1, column=1, sticky=tk.EW, pady=5)
        ttk.Button(main_frame, text="浏览...", command=self.browse_output).grid(row=1, column=2, padx=5, pady=5)
        
        # 格式选择
        format_frame = ttk.LabelFrame(main_frame, text="格式设置", padding="10")
        format_frame.grid(row=2, column=0, columnspan=3, sticky=tk.NSEW, pady=10)
        
        ttk.Label(format_frame, text="输入格式:").grid(row=0, column=0, sticky=tk.W, pady=5, padx=5)
        input_format_combo = ttk.Combobox(format_frame, textvariable=self.input_format, values=self.supported_formats, width=20)
        input_format_combo.grid(row=0, column=1, sticky=tk.W, pady=5, padx=5)
        
        ttk.Label(format_frame, text="输出格式:").grid(row=0, column=2, sticky=tk.W, pady=5, padx=5)
        output_format_combo = ttk.Combobox(format_frame, textvariable=self.output_format, values=self.supported_formats, width=20)
        output_format_combo.grid(row=0, column=3, sticky=tk.W, pady=5, padx=5)
        
        # 选项设置
        options_frame = ttk.LabelFrame(main_frame, text="转换选项", padding="10")
        options_frame.grid(row=3, column=0, columnspan=3, sticky=tk.NSEW, pady=10)
        
        ttk.Checkbutton(options_frame, text="生成独立文档 (--standalone)", variable=self.standalone).grid(row=0, column=0, sticky=tk.W, pady=2)
        ttk.Checkbutton(options_frame, text="生成目录 (--toc)", variable=self.toc).grid(row=1, column=0, sticky=tk.W, pady=2)
        ttk.Checkbutton(options_frame, text="章节编号 (--number-sections)", variable=self.number_sections).grid(row=2, column=0, sticky=tk.W, pady=2)
        
        # 额外参数
        ttk.Label(options_frame, text="额外参数 (用空格分隔):").grid(row=3, column=0, sticky=tk.W, pady=5)
        ttk.Entry(options_frame, textvariable=self.extra_args, width=50).grid(row=3, column=1, columnspan=2, sticky=tk.EW, pady=5)
        ttk.Label(options_frame, text="例如: -V mainfont=\"SimSun\" -V fontsize=12pt").grid(row=4, column=1, sticky=tk.W, pady=2)
        
        # 转换按钮
        btn_frame = ttk.Frame(main_frame)
        btn_frame.grid(row=4, column=0, columnspan=3, pady=10)
        
        ttk.Button(btn_frame, text="开始转换", command=self.convert_document, width=20).pack(side=tk.LEFT, padx=10)
        ttk.Button(btn_frame, text="退出", command=self.root.quit, width=10).pack(side=tk.LEFT)
        
        # 状态框
        ttk.Label(main_frame, text="状态:").grid(row=5, column=0, sticky=tk.W, pady=5)
        self.status_var = tk.StringVar(value="就绪")
        ttk.Label(main_frame, textvariable=self.status_var, foreground="blue").grid(row=5, column=1, sticky=tk.W, pady=5)
        
        # 配置列权重,使其可以拉伸
        main_frame.columnconfigure(1, weight=1)
        format_frame.columnconfigure(4, weight=1)
        options_frame.columnconfigure(1, weight=1)
        
    def browse_input(self):
        """选择输入文件"""
        filename = filedialog.askopenfilename(
            title="选择输入文件",
            filetypes=[("所有文件", "*.*")]
        )
        if filename:
            self.input_file.set(filename)
            # 自动推断输入格式
            ext = os.path.splitext(filename)[1].lower()[1:]  # 获取扩展名(不带点)
            if ext in self.supported_formats:
                self.input_format.set(ext)
            # 自动生成输出文件名
            self.suggest_output_filename(filename)
    
    def browse_output(self):
        """选择输出文件"""
        filename = filedialog.asksaveasfilename(
            title="保存输出文件",
            defaultextension=f".{self.output_format.get()}"
        )
        if filename:
            self.output_file.set(filename)
    
    def suggest_output_filename(self, input_filename):
        """根据输入文件名自动建议输出文件名"""
        base = os.path.splitext(input_filename)[0]
        output_ext = self.output_format.get()
        suggested_output = f"{base}.{output_ext}"
        self.output_file.set(suggested_output)
    
    def get_pandoc_args(self):
        """构建pandoc参数列表"""
        args = []
        
        if self.standalone.get():
            args.append("--standalone")
        if self.toc.get():
            args.append("--toc")
        if self.number_sections.get():
            args.append("--number-sections")
            
        # 添加额外参数
        extra_args = self.extra_args.get().strip()
        if extra_args:
            args.extend(extra_args.split())
            
        return args
    
    def convert_document(self):
        """执行文档转换"""
        input_path = self.input_file.get()
        output_path = self.output_file.get()
        
        # 验证输入输出文件
        if not input_path or not os.path.exists(input_path):
            messagebox.showerror("错误", "请选择有效的输入文件")
            return
            
        if not output_path:
            messagebox.showerror("错误", "请选择输出文件")
            return
        
        try:
            self.status_var.set("正在转换...")
            self.root.update()  # 更新界面
            
            # 获取转换参数
            extra_args = self.get_pandoc_args()
            
            # 执行转换
            pypandoc.convert_file(
                input_path,
                self.output_format.get(),
                outputfile=output_path,
                format=self.input_format.get(),
                extra_args=extra_args
            )
            
            self.status_var.set("转换成功!")
            messagebox.showinfo("成功", f"文件已转换为: {output_path}")
            
        except Exception as e:
            self.status_var.set("转换失败")
            messagebox.showerror("错误", f"转换过程中发生错误:\n{str(e)}")

if __name__ == "__main__":
    # 检查pandoc是否安装
    try:
        pypandoc.get_pandoc_version()
    except OSError:
        print("未找到pandoc,请先安装pandoc并确保它在系统PATH中。")
        print("pandoc下载地址: https://pandoc.org/installing.html")
        exit(1)
        
    root = tk.Tk()
    app = PandocConverterApp(root)
    root.mainloop()





分类: python源码源码分享 标签: 文档转换源码python文档转换

评论

暂无评论数据

暂无评论数据

目录