如何在单击按钮时打印 React 组件?

IT技术 javascript reactjs
2021-04-06 06:24:50

如何通过单击按钮仅打印一个组件。

我知道这个解决方案:

window.frames["print_frame"].window.focus();
window.frames["print_frame"].window.print();
$('.print_frame').remove();

但是 React 不想使用框架。

任何解决方案?谢谢你。

6个回答

客户端有两种解决方案。一个是像你张贴的框架。不过,您可以使用 iframe:

var content = document.getElementById("divcontents");
var pri = document.getElementById("ifmcontentstoprint").contentWindow;
pri.document.open();
pri.document.write(content.innerHTML);
pri.document.close();
pri.focus();
pri.print();

这期望此 html 存在

<iframe id="ifmcontentstoprint" style="height: 0px; width: 0px; position: absolute"></iframe>

另一种解决方案是使用媒体选择器并在media="print"样式上隐藏您不想打印的所有内容。

<style type="text/css" media="print">
   .no-print { display: none; }
</style>

最后一种方法需要在服务器上做一些工作。您可以将所有 HTML+CSS 发送到服务器,并使用众多组件之一来生成可打印的文档,如 PDF。我已经尝试使用 PhantomJs 进行设置。

我不确定我是否理解。我提到的所有解决方案都不会触发弹出窗口阻止程序。使用 CSS,不会,使用现有的 iframe 不会,使用服务器方法肯定不会。你能解释一下你的意思吗?
2021-06-09 06:24:50
使用 window.open 肯定会触发弹出窗口阻止程序,但使用上面示例中的 iframe,打开文档不应该。
2021-06-09 06:24:50
哪些解决方案会触发此问题?
2021-06-14 06:24:50
它就像一个魅力,感谢@Emil Ingerslev 的解决方案。我正在使用第一个解决方案,唯一的问题是前端可见的一个像素点。
2021-06-20 06:24:50
我检查它是因为我现在正在使用它。但这不是一个好的解决方案,因为它会在大多数浏览器(Firefox 和 Chrome)中被阻止,因为它的行为就像一个弹出窗口。
2021-06-21 06:24:50

我正在寻找一个简单的包来完成同样的任务,但没有找到任何东西,所以我创建了https://github.com/gregnb/react-to-print

你可以像这样使用它:

 <ReactToPrint
   trigger={() => <a href="#">Print this out!</a>}
   content={() => this.componentRef}
 />
 <ComponentToPrint ref={el => (this.componentRef = el)} />
@Gregory Nowakowski - 这个库可以处理 css module传递的 css 吗?如果是这样,如何?
2021-05-22 06:24:50
@VinitKhandelwal 您使用的是引导程序还是其他 css 库?如果是这样,请确保您阅读了如何使用 ref 的文档。一些 lib 使用 innerRef 而不是 ref
2021-05-22 06:24:50
@MuthukumarMarichamy 你可以在给定的参考中的任何内容 <div ref={el => (this.componentRef = el)}> <component-one> <component-two> </div>
2021-06-08 06:24:50
@Gregory Nowakowski,我想通过单击从多个组件打印多个收据。它有效吗?
2021-06-09 06:24:50
我正在尝试使用这个。但是点击什么都没有发生
2021-06-13 06:24:50

您必须@media print {}在 CSS 中设置打印输出的样式,但简单的代码是:

export default class Component extends Component {

    print(){
        window.print();
    }


  render() {

  ...
  <span className="print"
              onClick={this.print}>
    PRINT
    </span>

  } 
}

希望这有帮助!

您的代码在 Chrome 和 Firefox 中运行良好。但是,在我的情况下,在 Safari 中是不是什么都不做?你知道为什么吗?我在这里看到代码是相同的,它在 Safari 中工作...... w3schools.com/jsref/met_win_print.asp
2021-05-22 06:24:50
嗨@AralRoca,我不确定,但这对 Safari 来说可能很奇怪,找到了这个,可能我会尝试:stackoverflow.com/questions/44925902/...
2021-06-03 06:24:50

2017 年 6 月 19 日这对我来说非常有效。

import React, { Component } from 'react'

class PrintThisComponent extends Component {
  render() {
    return (
      <div>
        <button onClick={() => window.print()}>PRINT</button>
        <p>Click above button opens print preview with these words on page</p>
      </div>
    )
  }
}

export default PrintThisComponent
它打印整页而不是一个组件。
2021-06-03 06:24:50
这不适用于此问题 - 您提出的解决方案会打印整个页面,而不是按要求打印单个组件。
2021-06-09 06:24:50
虽然此代码可能会回答问题,但提供有关如何和/或为什么解决问题的附加上下文将提高​​答案的长期value。
2021-06-12 06:24:50

如果您想打印您已经有权访问的特定数据,无论是来自 Store、AJAX 还是其他地方可用的数据,您都可以利用我的库 react-print。

https://github.com/captray/react-print

它使创建打印模板变得更加容易(假设您已经依赖于 react)。您只需要适当地标记您的 HTML。

这个 ID 应该在你的实际 DOM 树中添加到更高的位置,以排除下面除了“打印安装”之外的所有内容。

<div id="react-no-print"> 

这是您的 react-print 组件将安装和包装您创建的模板的地方:

<div id="print-mount"></div>

一个例子看起来像这样:

var PrintTemplate = require('react-print');
var ReactDOM = require('react-dom');
var React = require('react');

var MyTemplate = React.createClass({
    render() {
        return (
            <PrintTemplate>
                <p>Your custom</p>
                <span>print stuff goes</span>
                <h1>Here</h1>
            </PrintTemplate>
        );
    }
});

ReactDOM.render(<MyTemplate/>, document.getElementById('print-mount'));

值得注意的是,您可以在模板中创建新的或利用现有的子组件,并且一切都应该可以很好地进行打印。

@FiddleFreak 不确定我理解你的问题吗?我发布这篇文章已经三年了,所以我可能需要更多的背景信息。
2021-05-23 06:24:50
我的问题是没有反应,所以你只能有一个,document.getElementById()因为它被认为是一个单页应用程序?如果你需要类似的东西怎么办ReactDOM.render(<MyTemplate/>, document.getElementById('print-mount'), document.getElementById('root')),那会起作用吗?
2021-06-07 06:24:50
如果你还需要document.getElementById('root')什么?
2021-06-08 06:24:50
这应该证明它。当您按 Ctrl + P 进行打印时,只需观看结果窗口即可。jsfiddle.net/captray/69z2wepo/68966
2021-06-11 06:24:50
仍然不确定您要做什么,但可以在您的标记中有多个挂载点。此代码也已过时,但您可能希望查看源代码并了解它在做什么,因为我不确定这是否满足您的需求。
2021-06-19 06:24:50