markdown转换工具edit icon

创建者:
用户xtysHTsw
Fork(复制)
下载
嵌入
BUG反馈
index.html
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Markdown 转 Word/Excel (极速版+一键复制)</title>
    
    <!-- 1. Markdown 解析 -->
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
    
    <!-- 2. Excel 导出库 -->
    <script src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script>
    
    <!-- 3. 文件保存库 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
    
    <!-- 4. Word 导出库 -->
    <script src="https://unpkg.com/html-docx-js/dist/html-docx.js"></script>

    <!-- 5. KaTeX 公式渲染引擎 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js"></script>

    <style>
        :root { --primary: #2563eb; --word: #2b579a; --excel: #217346; --copy: #f59e0b; }
        body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; margin: 0; padding: 0; background-color: #f3f4f6; height: 100vh; display: flex; flex-direction: column; }
        
        header { background: white; padding: 0 20px; height: 60px; display: flex; align-items: center; justify-content: space-between; box-shadow: 0 1px 3px rgba(0,0,0,0.1); flex-shrink: 0; }
        h1 { font-size: 18px; color: #1f2937; margin: 0; display: flex; align-items: center; gap: 10px; }
        .badge { font-size: 12px; background: #e0f2fe; color: #0369a1; padding: 2px 8px; border-radius: 4px; font-weight: normal; }

        .actions { display: flex; gap: 12px; }
        button { padding: 8px 16px; border: none; border-radius: 6px; cursor: pointer; font-size: 14px; font-weight: 500; color: white; display: flex; align-items: center; gap: 6px; transition: opacity 0.2s; }
        button:hover { opacity: 0.9; }
        button:active { transform: translateY(1px); }
        
        .btn-word { background-color: var(--word); }
        .btn-excel { background-color: var(--excel); }
        .btn-copy { background-color: white; color: #333; border: 1px solid #ddd; }
        .btn-copy:hover { background-color: #f9fafb; }

        .main-area { display: flex; flex: 1; padding: 20px; gap: 20px; overflow: hidden; }
        .editor-box, .preview-box { flex: 1; display: flex; flex-direction: column; background: white; border-radius: 8px; border: 1px solid #e5e7eb; overflow: hidden; }
        
        /* 头部样式调整,以容纳复制按钮 */
        .box-header { padding: 10px 15px; background: #f9fafb; border-bottom: 1px solid #e5e7eb; font-size: 14px; font-weight: 600; color: #374151; display: flex; justify-content: space-between; align-items: center; height: 40px;}
        
        textarea { flex: 1; border: none; padding: 20px; resize: none; outline: none; font-family: 'Consolas', 'Monaco', monospace; font-size: 14px; line-height: 1.6; color: #333; }
        
        #preview { flex: 1; padding: 20px; overflow-y: auto; color: #333; }

        /* 预览区样式 */
        #preview table { border-collapse: collapse; width: 100%; margin: 15px 0; border: 1px solid #ddd; }
        #preview th, #preview td { border: 1px solid #000; padding: 8px 12px; text-align: left; }
        #preview th { background-color: #f3f4f6; font-weight: bold; }
        #preview p { margin: 10px 0; line-height: 1.6; }
        
        /* 隐藏 KaTeX 的辅助 MathML,防止 Excel 导出重复 */
        .katex-mathml { display: none; } 
    </style>
</head>
<body>

<header>
    <h1>Markdown 转换工具 <span class="badge">V3.5 极速版</span></h1>
    <div class="actions">
        <button class="btn-word" onclick="toWord()"><span>📄</span> 导出 Word</button>
        <button class="btn-excel" onclick="toExcel()"><span>📊</span> 导出 Excel</button>
    </div>
</header>

<div class="main-area">
    <div class="editor-box">
        <div class="box-header">Markdown 输入</div>
        <textarea id="input" placeholder="输入内容...

# 财务指标分析

$$\text{可售比} = \frac{\text{地上可售面积} + \text{地下可售面积}}{\text{总建筑面积}}$$

**【案例实证:面积折损分析】**

| 楼栋 | 地上 | 地下 |
| --- | --- | --- |
| 1号楼 | 5000 | 200 |
"></textarea>
    </div>

    <div class="preview-box">
        <div class="box-header">
            <span>实时预览</span>
            <!-- 新增复制按钮 -->
            <button class="btn-copy" onclick="copyPreviewContent()">📋 一键复制</button>
        </div>
        <div id="preview"></div>
    </div>
</div>

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

    // 1. 核心渲染逻辑 (V3 逻辑)
    function render() {
        preview.innerHTML = marked.parse(input.value);
        renderMathInElement(preview, {
            delimiters: [
                {left: '$$', right: '$$', display: true},  // 块级公式
                {left: '$', right: '$', display: false}    // 行内公式
            ],
            throwOnError: false
        });
    }
    input.addEventListener('input', render);
    render();

    // ---------------------------------------------------------
    // 新功能:一键复制预览内容
    // ---------------------------------------------------------
    function copyPreviewContent() {
        // 创建一个选区,选中 preview 里的所有内容
        const range = document.createRange();
        range.selectNodeContents(preview);
        
        const selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);

        try {
            // 执行浏览器原生的复制命令
            const successful = document.execCommand('copy');
            if(successful) {
                // 简单的视觉反馈:更改按钮文字
                const btn = document.querySelector('.btn-copy');
                const originalText = btn.innerText;
                btn.innerText = "✅ 已复制!";
                btn.style.borderColor = "#217346";
                btn.style.color = "#217346";
                
                setTimeout(() => {
                    btn.innerText = originalText;
                    btn.style.borderColor = "#ddd";
                    btn.style.color = "#333";
                }, 1500);
            } else {
                alert('复制失败,请手动全选复制。');
            }
        } catch (err) {
            alert('浏览器不支持自动复制');
        }
        
        // 取消选中,以免干扰视线
        selection.removeAllRanges();
    }

    // ---------------------------------------------------------
    // 导出 Word (V3 逻辑,无截图引擎)
    // ---------------------------------------------------------
    function toWord() {
        const content = `
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="UTF-8">
                <style>
                    body { font-family: 'SimSun', serif; }
                    table { border-collapse: collapse; width: 100%; margin-bottom: 20px; }
                    td, th { border: 1px solid #000; padding: 8px; }
                    .katex { font-size: 1.1em; }
                </style>
            </head>
            <body>
                ${preview.innerHTML}
            </body>
            </html>
        `;
        const converted = htmlDocx.asBlob(content);
        saveAs(converted, '文档导出.docx');
    }

    // ---------------------------------------------------------
    // 导出 Excel (V3 逻辑,智能分行)
    // ---------------------------------------------------------
    function toExcel() {
        const wb = XLSX.utils.book_new();
        let rows = [];
        const nodes = preview.children;

        for (let node of nodes) {
            const tagName = node.tagName.toLowerCase();

            if (tagName === 'table') {
                if(rows.length > 0) rows.push([""]); 
                const tableSheet = XLSX.utils.table_to_sheet(node);
                const tableData = XLSX.utils.sheet_to_json(tableSheet, {header: 1});
                tableData.forEach(r => rows.push(r));
                rows.push([""]);

            } else {
                let text = node.innerText.trim();
                if (text) {
                    rows.push([text]);
                    rows.push([""]); 
                }
            }
        }

        const ws = XLSX.utils.aoa_to_sheet(rows);
        ws['!cols'] = [{ wch: 80 }, { wch: 15 }, { wch: 15 }];
        XLSX.utils.book_append_sheet(wb, ws, "导出数据");
        XLSX.writeFile(wb, '数据导出.xlsx');
    }
</script>

</body>
</html>
        
编辑器加载中
预览
控制台