效果如下:
代码如下:
直接在本机打开即可使用,或放到公网可以访问到的位置,提供外网使用。
<!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 = `\n`; mdInput.value += mdImg; updatePreview(); }; reader.readAsDataURL(file); } </script> </body> </html>