Skip to content

Markdown转world

Pandoc 是一个强大的文档转换工具,支持在多种标记语言和文档格式之间进行转换。它可以将 Markdown、HTML、LaTeX、reStructuredText 等格式转换为 PDF、Word、HTML、EPUB 等多种输出格式。Pandoc 特别擅长处理学术文档,支持数学公式、引用、脚注等复杂元素,是文档格式转换的瑞士军刀。不过 Pandoc 超过 250MB,对于简单的转换需求显得过于臃肿。

问题记录

  • WPS 不支持自定义表格样式,所以使用通过 WPS 保存后的文件当作模板最终文件表格样式无效
  • Lua 过滤器
#ifndef MD2DOCCONVERTER_H
#define MD2DOCCONVERTER_H

#include <QString>
#include <QProcess>
#include <QMessageBox>
#include <QFileDialog>
#include <QStandardPaths>
#include <QFile>
#include <QTextStream>

#define TEST

#ifdef TEST
#include <QVBoxLayout>
#include <QTextEdit>
#include <QPushButton>
#endif

class Md2DocConverter
{
public:
    static void ConvertMarkdownToDocx(const QString & mdContent, const QString & outputFile)
    {
        QString tempMdFile = outputFile + ".md";
        QFile file(tempMdFile);
        file.open(QIODevice::WriteOnly | QIODevice::Text);
        QTextStream out(&file);
        out << mdContent;
        file.close();

        QString templateFile = "./模板.docx";
        if (!QFile::exists(templateFile)) {
            QProcess createTemplateProcess;
            QStringList templateArgs;
            templateArgs << "--print-default-data-file" << "reference.docx";
            createTemplateProcess.start("./md2doc/pandoc.exe", templateArgs);
            createTemplateProcess.waitForFinished(-1);

            QFile templateOutput(templateFile);
            templateOutput.open(QIODevice::WriteOnly);
            templateOutput.write(createTemplateProcess.readAllStandardOutput());
            templateOutput.close();
        }

        QProcess pandocProcess;
        QStringList args;
        args << tempMdFile
             << "--to" << "docx" << "--output" << outputFile
             << "--reference-doc" << "./模板.docx" << "--standalone" << "--default-image-extension" << "png";

        pandocProcess.start("./md2doc/pandoc.exe", args);
        pandocProcess.waitForFinished(-1);

        QFile::remove(tempMdFile);

        if (pandocProcess.exitCode() != 0) {
            QMessageBox::critical(nullptr, u8"转换失败",
                                  QString::fromUtf8(pandocProcess.readAllStandardError()));
        }
    }

    static void Test()
    {
#ifdef TEST
        QWidget * testWindow = new QWidget;
        testWindow->setWindowTitle(u8"Markdown 转 Word 测试");
        testWindow->resize(600, 400);

        QVBoxLayout * layout = new QVBoxLayout(testWindow);

        QTextEdit * textEdit = new QTextEdit;
        textEdit->setPlainText(u8"");

        QPushButton * convertBtn = new QPushButton(u8"转换为 Word");

        layout->addWidget(textEdit);
        layout->addWidget(convertBtn);

        QObject::connect(convertBtn, &QPushButton::clicked, [textEdit]() {
            QString outputFile = QFileDialog::getSaveFileName(
              nullptr,
              u8"保存 Word 文档",
              QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/输出.docx",
              u8"Word 文档 (*.docx)");

            if (outputFile.isEmpty()) {
                return;
            }
            ConvertMarkdownToDocx(textEdit->toPlainText(), outputFile);
        });

        testWindow->show();
#endif
    }
};

#endif // MD2DOCCONVERTER_H