从浏览器复制SVG图像到剪贴板

26

我正在开发一个Web应用程序,它接受用户输入,进行工程计算,然后显示格式化的报告或图形。这些图形是工程图表,不总是像饼图那样的标准图表。这个应用程序的主要功能是使用户能够从浏览器将这些图表复制到Word或Excel文档中。

我需要选择使用客户端生成的SVG还是服务器端生成的位图。我更喜欢SVG方法,并且原型看起来不错,但是,在不同的浏览器上,特别是在div中显示图形时(即整个页面不是.svg),复制SVG图形似乎支持不一致。例如,IE在下拉菜单中显示“复制”,但仅将SVG图形的一部分复制到剪贴板。如果我在Chrome中右键单击SVG图形,则没有复制选项。

如果我在谷歌上搜索,惊讶地发现有关在Web应用程序中将SVG映像复制到剪贴板的问题的信息很少。

我的问题是针对已经解决过这个问题的读者:

  1. 是否有一种一致的方法可以使用JavaScript将作为较大DOM的一部分的SVG元素复制到剪贴板上;

  2. 考虑到我需要从浏览器将图形复制到剪贴板,是否有其他建议?

4个回答

16

不要将svg显示为svg元素,而是使用img标签显示。这有一些限制(您无法显示自定义字体或嵌入脚本,但似乎这不是您的用例)。好处是它的行为与图像完全一致(您可以拖放、右键单击复制等)。

要做到这一点,您需要使用base64进行编码。您可以在服务器端或客户端使用js进行编码。您的图像标记最终看起来像...

<img src="data:image/svg;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolf" width="..." height="..." alt="diagram" />

将你的base64编码的svg放在R0lGODlhEAAQAMQ...的位置。


感谢Duopixel的建议。看起来这可能解决我的问题。请给我一两天时间去探索,如果它像我希望的那样工作,我会将您的建议标记为答案。感谢您花时间帮助! - Fritz45

2

Javascript和剪贴板真是个麻烦事。

我知道一个解决方法:

如果这是一个真正的SVG文件,在Chrome浏览器中,右键单击图像,选择“检查元素”。 浏览器控制台将打开,并应该打开到您可以在检查器中选择的SVG元素。 在检查器中右键单击svg标记,然后选择“复制”或“复制为HTML”(我无法准确回想起这些选项)。

将文本粘贴到文本文件中,然后使用SVG扩展名保存文件。它可以在任何浏览器或SVG编辑程序中打开。Inkscape是编辑和调试的好选择,因为你可以在XML样式编辑器中查看和编辑整个SVG文件。

**对不起 - 我错过了您请求的第一部分。那会很棘手。但是复制和粘贴可能不是最佳选择。有PHP类可以处理SVG和Excel文件,这可能是解决问题的方法。


另外,你可以调查一下raphael.js - http://www.raphaeljs.com。我之前没有使用过它,但它似乎可能有解决你问题的方案,如果不行的话,肯定会为你提供其他与js一起工作的选项。 - dgo
我担心Raphael会让OP陷入现在的困境:一个无法复制到剪贴板的SVG元素。 - methodofaction
感谢user1167442的建议。我认为它们都是值得探索的有效途径。然而,最终还是用户需要进行复制和粘贴操作,因为他们只是工程师(开个玩笑),所以我不能要求他们做更多的事情,只能让他们右键点击并选择复制。我会研究下面Duopixel提供的答案。感谢你花时间帮助! - Fritz45

2
我成功地将SVG内容复制到剪贴板中作为纯XML文本,但对我来说似乎毫无用处,因为我使用的Inkscape(用于处理SVG)不能将剪贴板中的文本识别为SVG。出现这种情况是因为仅仅复制SVG文本是不够的,浏览器还应该设置mime-typeimage/svg+xml
我尝试了几个HTML5剪贴板API技巧,但最终遇到了Chrome无法将mime-type导出到系统剪贴板的问题。有关此问题的相关bug报告和jsfiddle链接可以在这里找到。

1

我在一个项目中遇到了同样的问题。客户需要一个相当复杂的图表。我们决定使用svg来开发它。工作非常完美,但是客户想要能够将图形下载为图片。在互联网上搜索后,我们找到了saveSvgAsPng(https://www.npmjs.com/package/save-svg-as-png)。这对我们很有帮助。

该图表在页面中如下所示:

<svg id="graph1" style="width: 700px; height: 700px">
....
.....
...
</svg>

图表已显示,但无法下载或复制。因此,这是我所采取的步骤:
  1. 我安装了上述提到的软件包。
<script src="/path/to/lib/save-svg-as-png/lib/saveSvgAsPng.js"></script>
  1. 将“display: none:”添加到svg代码中,否则我们将拥有两个相同图像的实例:
<svg id="graph1" style="width: 700px; height: 700px; display: none">

 <!-- // code goes here  -->


</svg>

在svg图形声明之后,我添加了一个新的图像。这张图片是svg图像的新png图像表示的占位符。一开始我将其隐藏,以防止图片在加载时闪烁。初始时源未指定:
<img id="graph1_as_png" src="" width="700" height="700" style="display: none">

在新添加的图片之后,我添加了一些代码行,用于进行转换操作:
<script>

    svgAsPngUri(document.getElementById("graph1")).then(uri => {
      $("#graph1_as_png").attr('src', uri).show();
    });

</script>

第二张图片的源代码被填充了一个BASE64编码版本的svg。转换后,图像将显示出来。现在我们有了与svg图像完全相同的图像,但可以下载或复制该图像。
我希望这也能对您有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接