吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2020|回复: 41
收起左侧

[Python 原创] Markdown文本转换成word文件

  [复制链接]
phantomxjc 发表于 2026-2-26 16:08

常见功能:AI生成的Markdown文本转换成word文件,进行一个初排版。文案内容由ai生成,有问题请自行略过哈哈哈
   

告别格式烦恼!一键将Markdown优雅转换为专业Word文档(中文排版友好)

你是否曾为将精心撰写的Markdown笔记、技术文档或博客文章转换成格式规范的Word文档而头疼?手动调整字体、标题、缩进耗时耗力,还容易出错。

今天给大家介绍一款我开发的桌面小工具——Markdown转Word工具 v2.6。它完美解决了Markdown到Word的转换难题,特别针对中文排版进行了深度优化,让你轻松获得专业、规范的Word文档。

工具概览

这是一个基于Python Tkinter开发的图形界面工具,界面简洁直观。它利用强大的pandoc进行核心格式转换,并结合python-docx对输出文档进行精细的美化处理,确保生成的文件既符合通用标准,又满足中文文档的特定要求。

核心目标:让用户专注于Markdown内容创作,将繁琐的格式转换工作完全自动化。

功能亮点详解

  1. 精准的格式转换与保留

    • 完整支持Markdown语法:完美转换标题(1-6级)、列表(有序/无序)、代码块、引用、粗体、斜体、链接、图片等所有常用元素。

    • 表格与复杂结构:正确转换表格等复杂结构,确保信息不丢失。

    • 样式继承:生成的Word文档将严格遵循你在Markdown中定义的文档结构。

  2. 深度中文本地化优化(核心特色)

    这是本工具区别于其他普通转换器的最大亮点,专门解决了中文文档排版的痛点:

    • 智能全角标点转换(可选):

    ◦ 自动将英文半角标点(如 , . ! ? : ; ( ) 等)转换为中文全角标点(如 , 。 ! ? : ; ( ))。

    ◦ 智能保护机制:此转换仅作用于正文文本,会自动跳过Markdown语法符号(如#、-、 ` ``、|等),避免破坏文档结构。你可以在设置中一键开启或关闭此功能。

    • 符合国标的首行缩进:

    ◦ 可为所有正文段落自动应用“首行缩进两个字符”的格式,这是中文文档的标准排版要求。

    ◦ 智能识别:工具能准确区分标题、代码块和正文,只对真正的正文段落应用缩进。

    • 丰富且专业的字体库:

    ◦ 提供包括“微软雅黑”、“宋体”、“黑体”、“楷体”、“仿宋”,以及公文字体“方正小标宋简体”、“华文中宋”在内的多种中文字体选项。

    ◦ 也支持 Arial、Times New Roman 等英文字体,满足多样化需求。

    ◦ 字体设置会应用于文档全文(包括表格内的文字)。

  3. 极致便捷的用户体验

    • 多种内容输入方式:

    ◦ 拖拽上传:直接将 .md 文件拖拽到程序窗口即可加载(需要系统支持)。

    ◦ 文件浏览:点击“加载Markdown文件”按钮进行选择。

    ◦ 直接粘贴:在中央的编辑框内直接粘贴或编辑Markdown文本。

    • 实时字体预览:在选择字体时,旁边的预览区会立即显示效果。

    • 异步转换不卡顿:转换过程在独立线程中进行,界面不会冻结,伴有进度条提示。

    • 转换完成智能提示:成功后会询问是否直接打开输出文件所在的文件夹。

  4. 稳定可靠的技术后端

    • 基于Pandoc:使用文档转换领域的业界标准工具pandoc作为转换引擎,质量与兼容性有保障。

    • 模板化系统:首次运行时会在你的用户目录下自动创建一个精心调校过的Word模板文件(.markdown_converter_template.docx)。该模板预定义了1-6级标题样式、正文行距等,确保每次转换的格式基准一致。

    • 详尽的日志:所有操作和错误都会记录在converter.log文件中,方便排查问题。

让工具处理格式,让你专注于创作本身。希望这款 Markdown转Word工具 能成为你文档工作流中的得力助手,彻底告别手动调整格式的繁琐!



软件界面: 6270ee63-fd20-4825-876b-c06b5413fc5f.png
转换前效果: 523d061b-6923-45e7-bcdd-1df4f00a23e5.png
转换后效果: 12f7632b-7089-41be-947a-5294783e7efd.png
[Asm] 纯文本查看 复制代码
import os
import sys
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
import pypandoc
from docx import Document
from docx.shared import Pt, RGBColor, Inches
from docx.oxml.ns import qn
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import logging
import shutil
from pathlib import Path
import tempfile
import threading
import re


class MarkdownConverterApp:
    def __init__(self, master):
        self.master = master
        self.master.title("Markdown转Word工具 v2.6")
        self.master.geometry("900x700")
        self.master.minsize(800, 600)

        # 初始化变量
        self.current_font = "微软雅黑"
        self.template_path = None
        self.is_converting = False

        self.setup_logging()
        self.setup_template()
        self.setup_ui()

        # 设置正确的拖拽事件绑定
        self.setup_drag_drop()

    def setup_logging(self):
        """配置日志系统"""
        logging.basicConfig(
            level=logging.INFO,
            format='%(asctime)s - %(levelname)s - %(message)s',
            handlers=[
                logging.FileHandler('converter.log', encoding='utf-8'),
                logging.StreamHandler(sys.stdout)
            ]
        )
        self.logger = logging.getLogger(__name__)

    def setup_template(self):
        """创建或验证Word模板"""
        try:
            template_path = Path.home() / ".markdown_converter_template.docx"
            if not template_path.exists():
                self._create_default_template(template_path)
            self.template_path = str(template_path)
            self.logger.info(f"模板路径: {self.template_path}")
        except Exception as e:
            self.logger.error(f"模板设置失败: {str(e)}")
            self.template_path = self._create_temp_template()

    def _create_default_template(self, template_path):
        """创建包含中文排版和首行缩进的Word模板,支持1-6级标题"""
        try:
            doc = Document()

            # 设置正文样式 - 添加首行缩进两个字符
            style = doc.styles['Normal']
            style.font.name = '微软雅黑'
            style.font.size = Pt(10.5)
            # 设置首行缩进为0.3英寸(约两个字符)
            style.paragraph_format.first_line_indent = Inches(0.3)
            style.paragraph_format.line_spacing = 1.5
            style.paragraph_format.space_after = Pt(6)

            if hasattr(style.font, '_element'):
                style.font._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')

            # 配置标题样式(1-6级)
            for level in range(1, 7):  # 扩展为1-6级标题
                heading_style_name = f'Heading {level}'
                try:
                    heading_style = doc.styles[heading_style_name]
                    heading_style.font.name = '微软雅黑'
                    # 设置不同级别的字体大小
                    base_sizes = [16, 14, 12, 11, 10.5, 10]
                    heading_style.font.size = Pt(base_sizes[level - 1] if level <= len(base_sizes) else 10)
                    heading_style.font.bold = True

                    # 设置标题间距
                    heading_style.paragraph_format.space_before = Pt(12 if level == 1 else 8)
                    heading_style.paragraph_format.space_after = Pt(6)

                    # 标题不需要首行缩进
                    heading_style.paragraph_format.first_line_indent = Pt(0)

                    if hasattr(heading_style.font, '_element'):
                        heading_style.font._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')
                except KeyError:
                    # 如果样式不存在,跳过
                    continue

            # 保存模板
            template_path.parent.mkdir(parents=True, exist_ok=True)
            doc.save(template_path)
            self.logger.info("默认模板创建成功,支持1-6级标题")
            return str(template_path)

        except Exception as e:
            self.logger.error(f"创建默认模板失败: {str(e)}")
            return self._create_temp_template()

    def _create_temp_template(self):
        """创建临时模板作为备选"""
        try:
            temp_dir = tempfile.gettempdir()
            template_path = Path(temp_dir) / "markdown_temp_template.docx"
            doc = Document()
            doc.save(template_path)
            self.logger.info(f"临时模板创建于: {template_path}")
            return str(template_path)
        except Exception as e:
            self.logger.error(f"创建临时模板失败: {str(e)}")
            return None

    def setup_drag_drop(self):
        """修复拖拽功能 - 使用Tkinter DnD库"""
        try:
            from tkinterdnd2 import DND_FILES, TkinterDnD
            self.logger.info("TkinterDnD库可用,启用高级拖拽功能")

            def handle_drop(event):
                files = self.master.tk.splitlist(event.data)
                for file in files:
                    if file.lower().endswith(('.md', '.txt', '.markdown')):
                        self.load_markdown_file(file)
                        break

            self.input_area.drop_target_register(DND_FILES)
            self.input_area.dnd_bind('<<Drop>>', handle_drop)

        except ImportError:
            self.logger.warning("TkinterDnD不可用,使用基本文件选择功能")
            if hasattr(self, 'drag_label'):
                self.drag_label.pack_forget()

    def setup_ui(self):
        """构建图形用户界面"""
        # 主框架
        main_frame = ttk.Frame(self.master, padding="10")
        main_frame.pack(fill=tk.BOTH, expand=True)

        # 标题
        title_label = ttk.Label(main_frame, text="Markdown转Word转换器",
                                font=("微软雅黑", 16, "bold"))
        title_label.pack(pady=(0, 10))

        # 输入区域
        input_frame = ttk.LabelFrame(main_frame, text="Markdown输入", padding="5")
        input_frame.pack(fill=tk.BOTH, expand=True, pady=(0, 10))

        # 拖拽提示
        self.drag_label = ttk.Label(input_frame,
                                    text="将Markdown文件拖拽到此处或直接粘贴内容",
                                    font=("微软雅黑", 9), foreground="gray")
        self.drag_label.pack(pady=5)

        self.input_area = scrolledtext.ScrolledText(
            input_frame,
            wrap=tk.WORD,
            width=80,
            height=15,
            font=('微软雅黑', 10),
            padx=10,
            pady=10
        )
        self.input_area.pack(fill=tk.BOTH, expand=True)

        # 配置区域
        config_frame = ttk.LabelFrame(main_frame, text="转换设置", padding="10")
        config_frame.pack(fill=tk.X, pady=(0, 10))

        # 字体选择行
        font_row = ttk.Frame(config_frame)
        font_row.pack(fill=tk.X, pady=5)

        font_label = ttk.Label(font_row, text="输出字体:", width=10)
        font_label.pack(side=tk.LEFT)

        # 扩展字体选项,增加公文字体
        font_options = [
            '微软雅黑', '宋体', '黑体', '楷体', '仿宋',
            '仿宋_GB2312', '方正小标宋简体', '华文楷体', '华文中宋',
            'Arial', 'Times New Roman', 'Calibri'
        ]

        self.font_var = tk.StringVar(value="微软雅黑")
        self.font_combo = ttk.Combobox(
            font_row,
            textvariable=self.font_var,
            values=font_options,
            state="readonly",
            width=15
        )
        self.font_combo.pack(side=tk.LEFT, padx=(0, 20))
        self.font_combo.bind('<<ComboboxSelected>>', self._update_font_preview)

        # 全角标点选项
        self.full_width_punctuation_var = tk.BooleanVar(value=True)
        full_width_cb = ttk.Checkbutton(
            font_row,
            text="转换标点为全角",
            variable=self.full_width_punctuation_var
        )
        full_width_cb.pack(side=tk.LEFT, padx=(0, 20))

        # 首行缩进选项
        self.indent_var = tk.BooleanVar(value=True)
        indent_cb = ttk.Checkbutton(
            font_row,
            text="首行缩进两个字符",
            variable=self.indent_var
        )
        indent_cb.pack(side=tk.LEFT, padx=(0, 20))

        # 预览区域
        preview_frame = ttk.Frame(font_row)
        preview_frame.pack(side=tk.RIGHT, fill=tk.X, expand=True)

        preview_title = ttk.Label(preview_frame, text="预览:")
        preview_title.pack(side=tk.LEFT)

        self.preview_label = ttk.Label(
            preview_frame,
            text="我们秉持的宗旨",
            font=('微软雅黑', 10)
        )
        self.preview_label.pack(side=tk.LEFT, padx=(10, 0))

        # 按钮区域
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=(0, 10))

        self.convert_btn = ttk.Button(
            button_frame,
            text="转换为Word文档",
            command=self.start_conversion,
            width=20
        )
        self.convert_btn.pack(side=tk.LEFT, padx=(0, 10))

        self.clear_btn = ttk.Button(
            button_frame,
            text="清空内容",
            command=self.clear_input,
            width=10
        )
        self.clear_btn.pack(side=tk.LEFT, padx=(0, 10))

        load_file_btn = ttk.Button(
            button_frame,
            text="加载Markdown文件",
            command=self.browse_markdown_file,
            width=15
        )
        load_file_btn.pack(side=tk.LEFT, padx=(0, 10))

        # 进度条
        self.progress = ttk.Progressbar(
            button_frame,
            mode='indeterminate',
            length=100
        )
        self.progress.pack(side=tk.RIGHT, fill=tk.X, expand=True)

        # 状态栏
        self.status = tk.StringVar(value="就绪 - 请输入Markdown内容或拖拽文件")
        status_bar = ttk.Label(
            main_frame,
            textvariable=self.status,
            relief=tk.SUNKEN,
            anchor=tk.W,
            padding=(5, 2)
        )
        status_bar.pack(fill=tk.X)

        # 初始化预览
        self._update_font_preview()

    def _update_font_preview(self, event=None):
        """更新字体预览"""
        selected_font = self.font_var.get()
        self.preview_label.config(font=(selected_font, 10))

    def browse_markdown_file(self):
        """浏览并加载Markdown文件"""
        file_path = filedialog.askopenfilename(
            title="选择Markdown文件",
            filetypes=[
                ("Markdown文件", "*.md"),
                ("文本文件", "*.txt"),
                ("所有文件", "*.*")
            ]
        )

        if file_path:
            self.load_markdown_file(file_path)

    def load_markdown_file(self, file_path):
        """加载Markdown文件内容"""
        try:
            with open(file_path, 'r', encoding='utf-8') as f:
                content = f.read()

            self.input_area.delete('1.0', tk.END)
            self.input_area.insert('1.0', content)

            # 自动滚动到底部
            self.input_area.see(tk.END)

            self.status.set(f"已加载文件: {Path(file_path).name}")
            self.logger.info(f"成功加载Markdown文件: {file_path}")

        except Exception as e:
            error_msg = f"读取文件失败: {str(e)}"
            self.logger.error(error_msg)
            messagebox.showerror("错误", error_msg)

    def start_conversion(self):
        """在单独线程中开始转换过程"""
        if self.is_converting:
            return

        self.is_converting = True
        self.convert_btn.config(state='disabled')
        self.progress.start(10)
        self.status.set("转换中...")

        # 在新线程中运行转换
        thread = threading.Thread(target=self.convert)
        thread.daemon = True
        thread.start()

    def convert(self):
        """执行Markdown到Word的转换,支持1-6级标题"""
        markdown_text = self.input_area.get("1.0", tk.END).strip()

        if not markdown_text:
            self.master.after(0, lambda: messagebox.showwarning("警告", "请输入Markdown内容或选择Markdown文件!"))
            self._conversion_finished()
            return

        try:
            # 选择输出路径
            output_path = filedialog.asksaveasfilename(
                defaultextension=".docx",
                filetypes=[
                    ("Word文档", "*.docx"),
                    ("所有文件", "*.*")
                ],
                title="保存Word文档"
            )

            if not output_path:
                self._conversion_finished()
                return

            # 创建临时目录和文件
            with tempfile.TemporaryDirectory() as temp_dir:
                temp_md = Path(temp_dir) / "temp.md"

                # 处理标点符号转换
                processed_text = self._preprocess_markdown(markdown_text)

                # 保存处理后的Markdown内容到临时文件
                with open(temp_md, 'w', encoding='utf-8') as f:
                    f.write(processed_text)

                # 构建pandoc参数 - 支持1-6级标题
                extra_args = [
                    '--standalone',
                    f'--reference-doc={self.template_path}' if self.template_path else '',
                    '--wrap=auto',
                    # 设置标题级别为6级
                    '--top-level-division=section',
                ]

                # 过滤空参数
                extra_args = [arg for arg in extra_args if arg]

                # 执行转换
                self.logger.info("开始Pandoc转换...")
                pypandoc.convert_file(
                    str(temp_md),
                    'docx',
                    outputfile=output_path,
                    extra_args=extra_args
                )

                # 应用字体和段落设置
                self._apply_document_settings(output_path)

            # 在主线程中更新UI
            self.master.after(0, lambda: self._conversion_success(output_path))

        except Exception as e:
            error_msg = f"转换失败: {str(e)}"
            self.logger.error(error_msg, exc_info=True)
            self.master.after(0, lambda: self._conversion_error(error_msg))

    def _preprocess_markdown(self, text):
        """预处理Markdown文本:转换标点符号为全角"""
        if not self.full_width_punctuation_var.get():
            return text

        # 半角到全角的标点映射
        half_to_full = {
            ',': ',',
            '.': '。',
            '!': '!',
            '?': '?',
            ':': ':',
            ';': ';',
            '(': '(',
            ')': ')',
            '[': '【',
            ']': '】',
            '<': '《',
            '>': '》',
            '"': '"',
            "'": ''',
            '`': '`',
            '~': '~',
            '@': '@',
            '#': '#',
            '$': '$',
            '%': '%',
            '^': '^',
            '&': '&',
            '*': '*',
            '-': '-',
            '=': '=',
            '+': '+',
            '\\': '\',
            '|': '|'
        }

        # 保护Markdown语法符号,只转换文本内容中的标点
        lines = text.split('\n')
        processed_lines = []

        for line in lines:
            # 如果是Markdown语法行(标题、列表、代码块等),跳过转换
            if (line.strip().startswith('#') or
                    line.strip().startswith('-') or
                    line.strip().startswith('*') or
                    line.strip().startswith('>') or
                    line.strip().startswith('`') or
                    '```' in line or
                    line.strip().startswith('|') or  # 表格
                    line.strip().startswith('+') or  # 列表
                    re.match(r'^\s*\d+\.', line.strip()) or  # 有序列表
                    re.match(r'^\s*\d+\)', line.strip())):  # 有序列表
                processed_lines.append(line)
                continue

            # 转换普通文本行中的标点
            processed_line = ''
            for char in line:
                if char in half_to_full and self.full_width_punctuation_var.get():
                    processed_line += half_to_full[char]
                else:
                    processed_line += char
            processed_lines.append(processed_line)

        return '\n'.join(processed_lines)

    def _is_paragraph_text(self, paragraph):
        """判断段落是否为正文文本段落"""
        # 空段落不是正文
        if not paragraph.text.strip():
            return False

        # 获取段落样式名称
        style_name = paragraph.style.name.lower() if paragraph.style and paragraph.style.name else ""

        # 排除标题段落(支持1-6级标题)
        if ('heading' in style_name or
                any(paragraph.text.strip().startswith('#' * i) for i in range(1, 7))):
            return False

        # 排除代码块
        if paragraph.style.name and 'code' in paragraph.style.name.lower():
            return False

        # 检查段落是否包含代码格式
        for run in paragraph.runs:
            if run.font.name and 'consolas' in run.font.name.lower():
                return False
            if run.style and run.style.name and 'code' in run.style.name.lower():
                return False

        return True

    def _apply_document_settings(self, doc_path):
        """应用字体、段落和标点设置到Word文档"""
        try:
            doc = Document(doc_path)
            selected_font = self.font_var.get()
            use_indent = self.indent_var.get()

            # 处理所有段落
            for paragraph in doc.paragraphs:
                # 更准确地判断正文段落
                if self._is_paragraph_text(paragraph):
                    if use_indent:
                        # 设置首行缩进两个字符(0.3英寸)
                        paragraph.paragraph_format.first_line_indent = Inches(0.3)
                        self.logger.debug(f"应用首行缩进到段落: {paragraph.text[:50]}...")

                # 设置字体
                for run in paragraph.runs:
                    run.font.name = selected_font
                    if hasattr(run.font, '_element'):
                        run.font._element.rPr.rFonts.set(qn('w:eastAsia'), selected_font)

            # 处理表格中的字体和段落
            for table in doc.tables:
                for row in table.rows:
                    for cell in row.cells:
                        for paragraph in cell.paragraphs:
                            if use_indent and self._is_paragraph_text(paragraph):
                                paragraph.paragraph_format.first_line_indent = Inches(0.3)
                            for run in paragraph.runs:
                                run.font.name = selected_font
                                if hasattr(run.font, '_element'):
                                    run.font._element.rPr.rFonts.set(qn('w:eastAsia'), selected_font)

            doc.save(doc_path)
            self.logger.info("文档设置应用成功")

        except Exception as e:
            self.logger.warning(f"文档设置应用失败: {str(e)}")

    def _conversion_success(self, output_path):
        """转换成功后的处理"""
        self._conversion_finished()
        self.status.set("转换完成!")
        self.logger.info(f"转换成功: {output_path}")

        if messagebox.askyesno("完成", "文件转换成功!是否打开所在文件夹?"):
            try:
                os.startfile(str(Path(output_path).parent))
            except:
                try:
                    import subprocess
                    subprocess.run(['open', str(Path(output_path).parent)])
                except:
                    pass

    def _conversion_error(self, error_msg):
        """转换失败后的处理"""
        self._conversion_finished()
        messagebox.showerror("错误", error_msg)
        self.status.set("转换失败")

    def _conversion_finished(self):
        """转换完成后的清理工作"""
        self.is_converting = False
        self.convert_btn.config(state='normal')
        self.progress.stop()

    def clear_input(self):
        """清空输入区域"""
        self.input_area.delete('1.0', tk.END)
        self.status.set("已清空")
        self.logger.info("输入区域已清空")


def check_dependencies():
    """检查必要的依赖"""
    try:
        pypandoc.get_pandoc_version()
        return True
    except OSError:
        messagebox.showerror(
            "依赖错误"
        )
        return False
    except Exception as e:
        messagebox.showerror("错误", f"初始化失败: {str(e)}")
        return False


if __name__ == "__main__":
    if not check_dependencies():
        sys.exit(1)

    root = tk.Tk()
    try:
        app = MarkdownConverterApp(root)
        root.mainloop()
    except Exception as e:
        messagebox.showerror("致命错误", f"应用程序启动失败: {str(e)}")
        sys.exit(1)

免费评分

参与人数 7吾爱币 +9 热心值 +6 收起 理由
苏紫方璇 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
DDD7799 + 1 我很赞同!
onceok + 1 + 1 谢谢@Thanks!
fjplfjpl + 1 + 1 用心讨论,共获提升!
laozhang4201 + 1 + 1 热心回复!
绝世大嘴 + 1 + 1 我很赞同!
helian147 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| phantomxjc 发表于 2026-2-27 09:46
不想打包,上次因为上传打包链接 已经违规了 有能力的自行打包  不然我多打包两次可能就被封号了
michealzh 发表于 2026-2-26 16:20
sinolong2533UL 发表于 2026-2-27 15:00
绝世大嘴 发表于 2026-2-26 23:11
求EXE文件,希望能挂出来,大家会更感谢
baqycl 发表于 2026-2-26 16:36
感谢楼主分享!楼主可以帮忙编译成可执行档发出来吗?不是搞开发的,没有编译环境。
SU150228 发表于 2026-2-26 17:00
michealzh 发表于 2026-2-26 16:20
pandoc就可以转换吧

还差tex图形转换成word文档中的图形不会转换
15881 发表于 2026-2-26 17:09
michealzh 发表于 2026-2-26 16:20
pandoc就可以转换吧

我刚刚也想说,不过楼主的执行力精神值得被传承

免费评分

参与人数 1热心值 +1 收起 理由
Skyisland + 1 我很赞同!

查看全部评分

ysjd22 发表于 2026-2-26 17:15
好厉害的样子。
moonalong8 发表于 2026-2-26 17:16
加油 希望增加更有趣的功能 ~
Henglie 发表于 2026-2-26 17:43
这个好诶,把这个功能从全家桶独立出来了
s466692282 发表于 2026-2-26 18:28
只有代码,没有exe文件啊
ibrucekong 发表于 2026-2-26 18:36
厉害,下一步就是图片、表格都无损转换了
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-4-18 03:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表