首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在React中下载PNG格式的图表,无需覆盖DOM

在React中下载PNG格式的图表,无需覆盖DOM
EN

Stack Overflow用户
提问于 2019-07-26 00:36:22
回答 2查看 1.6K关注 0票数 2

我想下载一个用recharts创建的图表作为png图像。如果我在DOM上写东西,我就能让它工作。我想要下载该图像。这是我到目前为止所拥有的,感谢这篇文章:

Recharts component to PNG

我有一个可点击的元素来下载png和一个组件中的图表:

代码语言:javascript
复制
return (
      <div>
        <h1
          onClick={() => this.handleDownload()}
        >
          Download chart
        </h1>
        <LineChart
          ref={(chart) => this.currentChart = chart}
          width={500}
          height={300}
          data={data}
          margin={{
            top: 5, right: 30, left: 20, bottom: 5,
          }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey="name" />
          <YAxis />
          <Tooltip />
          <Legend />
          <Line type="monotone" dataKey="pv" stroke="#8884d8" activeDot={{ r: 8 }} />
          <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
        </LineChart>
      </div>

    )

每当我单击时,我都会生成一个画布。多亏了画布,一旦我有了图像,我就可以把它写在DOM中:

代码语言:javascript
复制
svgToPng = (svg, width, height) => {
    return new Promise((resolve, reject) => {

      let canvas = document.createElement('canvas');
      canvas.width = width;
      canvas.height = height;
      let ctx = canvas.getContext('2d');

      // Set background to white
      ctx.fillStyle = '#ffffff';
      ctx.fillRect(0, 0, width, height);

      let xml = new XMLSerializer().serializeToString(svg);
      let dataUrl = 'data:image/svg+xml;utf8,' + encodeURIComponent(xml);
      let img = new Image(width, height);

      img.onload = () => {
        ctx.drawImage(img, 0, 0);
        let imageData = canvas.toDataURL('image/png', 1.0);

        resolve(imageData)
      }

      img.onerror = () => reject();

      img.src = dataUrl;
    });
  };

  handleDownload = async () => {
    const chart = this.currentChart
    let chartSVG = ReactDOM.findDOMNode(chart).children[0]

    const pngData = await this.svgToPng(chartSVG, 400, 500)
    document.write('<img src="'+pngData+'"/>') // <------
  }

我想下载图像,而不是将其附加到DOM。

我尝试过这种方法:

代码语言:javascript
复制
to download the image you can place it in an <a> tag using download attribute (html5) : <a href="javascript:canvas.toDataURL('image/jpeg');" download="download" >Download as jpeg</a>

我在DOM中放置了一个a标记:

代码语言:javascript
复制
<a href={aTag} download="download" >Download as jpeg</a>

where aTag is

代码语言:javascript
复制
const aTag = `'javascript:${this.state.imageData}.toDataURL('image/jpeg');'`

基本上,在我的组件中,我使用canvas对象设置了一个状态:

代码语言:javascript
复制
class DownloadChart extends React.Component {
  state = {
    imageData: ''
  }
  async componentDidMount() {
    await this.handleDownload()
  }

我去掉了document.write指令,所以每当挂载组件时,我只生成canvas对象,并将其附加到href属性

代码语言:javascript
复制
<a href={aTag} download="download" >Download as png</a>

关于如何实现png镜像的下载有什么建议吗?我不能让它在两种方法中的任何一种下工作。

EN

回答 2

Stack Overflow用户

发布于 2019-07-26 07:49:21

试着去掉aTag中的多余引号。

代码语言:javascript
复制
const aTag = `javascript:${this.state.imageData}.toDataURL('image/jpeg');`
票数 0
EN

Stack Overflow用户

发布于 2020-07-18 23:58:49

我一直在努力找出如何做到这一点,这个问题有95%的解决方案,我需要最终让它工作。

您可以使用FileSaver下载PNG。

handleDownload中,将document.write('<img src="'+pngData+'"/>')替换为FileSaver.saveAs(pngData, "test.png")

下载不能在CodeSandbox中工作,所以你必须先打开沙箱,点击右上角的“在新窗口中打开”,然后尝试下载:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57206626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档