发布于: 阅读时间: 0 分, 41 秒

效果如下:


image.png

代码如下:



md2doc.rar


直接在本机打开即可使用,或放到公网可以访问到的位置,提供外网使用。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Markdown 转 Word</title>
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/html-docx-js/dist/html-docx.js"></script>
  <style>
    * { box-sizing: border-box; }
    body {
      margin: 0;
      font-family: sans-serif;
      height: 100vh;
      display: flex;
      flex-direction: column;
    }
    #topbar {
      background: #f0f0f0;
      padding: 10px;
      border-bottom: 1px solid #ccc;
      display: flex;
      align-items: center;
      gap: 10px;
    }
    #main {
      flex: 1;
      display: flex;
      height: 100%;
    }
    textarea {
      width: 50%;
      padding: 10px;
      border: none;
      font-family: monospace;
      font-size: 16px;
      resize: none;
      outline: none;
    }
    #preview {
      width: 50%;
      padding: 10px;
      overflow-y: auto;
      border-left: 1px solid #ccc;
      background: #fafafa;
    }
    button, input[type="file"] {
      padding: 6px 12px;
      font-size: 14px;
    }
  </style>
</head>
<body>

<div id="topbar">
  <input type="file" id="fileInput" accept=".md" onchange="loadFile(event)">
  <button onclick="copyToClipboard()">复制格式内容</button>
  <button onclick="downloadWord()">下载为 Word</button>
</div>

<div id="main">
  <textarea id="markdown" placeholder="请输入 Markdown 内容..."></textarea>
  <div id="preview" contenteditable="true" ondrop="handleDrop(event)" onpaste="handlePaste(event)"></div>
</div>

<script>
  const mdInput = document.getElementById('markdown');
  const preview = document.getElementById('preview');

  function updatePreview() {
    const html = marked.parse(mdInput.value);
    preview.innerHTML = html;
  }

  mdInput.addEventListener('input', updatePreview);
  window.onload = updatePreview;

  function copyToClipboard() {
    const range = document.createRange();
    range.selectNode(preview);
    const sel = window.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
    document.execCommand("copy");
    alert("已复制格式内容!");
  }

  function downloadWord() {
    const content = `<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>${preview.innerHTML}</body></html>`;
    const blob = htmlDocx.asBlob(content);
    const url = URL.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = url;
    a.download = 'markdown.docx';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }

  function loadFile(event) {
    const file = event.target.files[0];
    if (file && file.name.endsWith(".md")) {
      const reader = new FileReader();
      reader.onload = e => {
        mdInput.value = e.target.result;
        updatePreview();
      };
      reader.readAsText(file);
    } else {
      alert("请选择 .md 文件");
    }
  }

  function handlePaste(e) {
    const items = e.clipboardData.items;
    for (let item of items) {
      if (item.type.indexOf("image") !== -1) {
        const file = item.getAsFile();
        embedImage(file);
        e.preventDefault();
      }
    }
  }

  function handleDrop(e) {
    e.preventDefault();
    const files = e.dataTransfer.files;
    for (let file of files) {
      if (file.type.startsWith("image/")) {
        embedImage(file);
      }
    }
  }

  function embedImage(file) {
    const reader = new FileReader();
    reader.onload = e => {
      const base64 = e.target.result;
      const alt = file.name;
      const mdImg = `![${alt}](${base64})\n`;
      mdInput.value += mdImg;
      updatePreview();
    };
    reader.readAsDataURL(file);
  }
</script>

</body>
</html>