【自研】python结合pandoc实现文档转换

首先需要安装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文档转换
版权申明
文章由大象博客原创,转载引用需注明出处:大象博客(https://daxiang.tech)
暂无评论数据