繁体   English   中英

在 React 中以 PNG 格式下载图表而不覆盖 DOM

[英]Download chart as PNG format in React without overwriting the DOM

我想下载一个用recharts创建的图表作为 png 图像。 如果我写在 DOM 上,我就让它工作了。 我想改为下载图像。 到目前为止,这就是我所拥有的,这要归功于这篇文章:

将组件重新绘制为 PNG

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

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 中编写它:

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。

我试过这种方法:

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 标签:

<a href={aTag} download="download" >Download as jpeg</a>

其中aTag is

const aTag = `'javascript:${this.state.imageData}.toDataURL('image/jpeg');'`

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

class DownloadChart extends React.Component {
  state = {
    imageData: ''
  }
  async componentDidMount() {
    await this.handleDownload()
  }

我摆脱了document.write指令,所以我只生成画布对象,并将其附加到href属性,无论何时安装组件

<a href={aTag} download="download" >Download as png</a>

关于如何实现 png 图像下载的任何建议? 我无法使用这两种方法中的任何一种。

尝试去掉aTag多余的引号。

IE

const aTag = `javascript:${this.state.imageData}.toDataURL('image/jpeg');`

我一直在试图找出如何完成这个问题,这个问题有 95% 的解决方案,我需要最终使它工作。

您可以使用FileSaver下载 PNG。

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

在 CodeSandbox 中无法下载,因此您必须先打开沙箱,然后单击右上角的“在新窗口中打开”,然后尝试下载:

编辑focused-haze-vmhzg

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM