You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编程获取monaco-editor的HTML格式高亮内容并合并复制到剪贴板?

实现从Monaco Editor导出带高亮的HTML并合并自定义文本到剪贴板

我刚好做过类似的需求,核心思路是先让Monaco生成带语法高亮的HTML内容,再把它和你的自定义文本拼接成完整的HTML结构,最后按照剪贴板的规范写入内容,这样粘贴到Outlook这类支持HTML的应用时就能保留格式了。下面是具体的步骤和代码:

1. 从Monaco获取带语法高亮的HTML

Monaco提供了generateHtmlForModel这个API,可以直接基于编辑器的模型生成带语法高亮的HTML,连主题样式都会内联进去,非常方便:

// 假设你已经拿到了Monaco Editor的实例(比如通过初始化时的引用)
const editor = monaco.editor.getEditors()[0]; // 或者你自己保存的editor实例
const model = editor.getModel();

// 生成带高亮的HTML,可配置项根据需求调整
const monacoHtml = monaco.editor.generateHtmlForModel(model, {
  theme: editor.getTheme(), // 复用当前编辑器的主题(比如vs-dark)
  lineNumbers: true, // 是否显示行号,可选
  wordWrap: true, // 是否自动换行,可选
  trim: false // 是否裁剪空白,可选
});

2. 拼接自定义文本和Monaco的HTML

把你需要添加的其他文本(Monaco访问不到的部分)和Monaco生成的HTML拼接成一个完整的HTML文档片段,比如:

// 你的自定义前置文本
const preText = `<div style="margin-bottom: 12px; font-size: 16px; font-weight: bold;">
  这是从项目中导出的核心代码片段:
</div>`;

// 你的自定义后置文本
const postText = `<div style="margin-top: 12px; color: #666;">
  注意:这段代码依赖项目中的utils工具类,使用前请确保依赖已引入
</div>`;

// 拼接成完整的HTML内容
const fullHtml = `
<div style="font-family: sans-serif;">
  ${preText}
  ${monacoHtml}
  ${postText}
</div>
`;

3. 将合并后的HTML写入剪贴板

这里要注意:浏览器剪贴板的HTML格式有特定的规范,不能直接把HTML字符串丢进去,需要构造符合要求的格式。同时为了兼容性,最好同时提供纯文本版本作为降级方案:

async function copyFormattedContentToClipboard(html, plainTextFallback) {
  try {
    // 构造符合剪贴板HTML规范的内容
    const clipboardHtmlTemplate = `Version:0.9
StartHTML:0000000000
EndHTML:000000${html.length.toString().padStart(6, '0')}
StartFragment:0000000000
EndFragment:000000${html.length.toString().padStart(6, '0')}
${html}`;

    // 使用现代的Clipboard API写入
    await navigator.clipboard.write([
      new ClipboardItem({
        'text/html': new Blob([clipboardHtmlTemplate], { type: 'text/html' }),
        'text/plain': new Blob([plainTextFallback], { type: 'text/plain' })
      })
    ]);
    console.log('带格式的内容已成功复制到剪贴板!');
  } catch (err) {
    // 降级到旧的execCommand方法,兼容老浏览器
    const tempContainer = document.createElement('div');
    tempContainer.innerHTML = html;
    // 临时添加到页面(否则无法选中)
    document.body.appendChild(tempContainer);
    
    // 选中内容并复制
    const range = document.createRange();
    range.selectNodeContents(tempContainer);
    const selection = window.getSelection();
    selection.removeAllRanges();
    selection.addRange(range);
    document.execCommand('copy');
    
    // 清理临时元素
    document.body.removeChild(tempContainer);
    console.log('已使用兼容模式复制内容');
  }
}

// 调用函数:纯文本 fallback 可以自己拼接
const plainText = `${editor.getValue()}\n\n这是从项目中导出的核心代码片段:\n注意:这段代码依赖项目中的utils工具类,使用前请确保依赖已引入`;
copyFormattedContentToClipboard(fullHtml, plainText);

几个关键注意事项

  • 用户交互触发:浏览器出于安全限制,剪贴板操作必须在用户交互(比如点击按钮)中触发,所以要把这段代码绑定到按钮的click事件里,不能直接在页面加载时执行。
  • 主题样式兼容:generateHtmlForModel生成的HTML已经把主题样式内联了,所以不需要额外引入Monaco的CSS文件,直接用就行。
  • 多应用测试:不同应用对剪贴板HTML的解析略有差异,如果在Outlook里显示有问题,可以微调HTML的结构(比如把外层的div换成table,或者调整内联样式)。

内容的提问来源于stack exchange,提问作者rony l

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:14:04