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

Javascript 如何在单击按钮时打印React组件?,javascript,reactjs,Javascript,Reactjs,如何在单击按钮时仅打印一个组件 我知道这个解决方案: window.frames["print_frame"].window.focus(); window.frames["print_frame"].window.print(); $('.print_frame').remove(); 但是React不想使用框架 有什么解决办法吗?谢谢。客户机上有两种解决方案。一个是像你贴的框架。但是,您可以使用iframe: var content = document.getElementById("d

如何在单击按钮时仅打印一个组件

我知道这个解决方案:

window.frames["print_frame"].window.focus();
window.frames["print_frame"].window.print();
$('.print_frame').remove();
但是React不想使用框架


有什么解决办法吗?谢谢。

客户机上有两种解决方案。一个是像你贴的框架。但是,您可以使用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>

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

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

导出默认类组件扩展组件{
打印(){
window.print();
}
render(){
...
印刷品
} 
}

希望对你有帮助

如果您希望打印您已经可以访问的特定数据,无论是来自商店、AJAX还是其他地方,您都可以利用我的库react print

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

该ID应该添加到实际DOM树的更高位置,以排除除下面“打印装载”之外的所有内容


这是react打印组件将装载和包装您创建的模板的位置:

<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'));
var PrintTemplate=require('react-print');
var ReactDOM=require('react-dom');
var React=要求('React');
var MyTemplate=React.createClass({
render(){
返回(
你的习惯

打印的东西会消失 在这里 ); } }); render(,document.getElementById('print-mount');

值得注意的是,您可以在模板中创建新的或利用现有的子组件,并且所有内容都可以很好地打印。

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
import React,{Component}来自“React”
类PrintThisComponent扩展组件{
render(){
返回(
window.print()}>print
单击上面的按钮打开打印预览,页面上有这些文字

) } } 导出默认PrintThisComponent
我正在寻找一个简单的包来完成同样的任务,但没有找到任何东西,所以我创建了一个

您可以这样使用它:

 <ReactToPrint
   trigger={() => <a href="#">Print this out!</a>}
   content={() => this.componentRef}
 />
 <ComponentToPrint ref={el => (this.componentRef = el)} />
}
content={()=>this.componentRef}
/>
(this.componentRef=el)}/>

只是分享我的案例,其他人可能会觉得有用。我有一个模态,只是想打印模态的主体,可以是几页纸

我尝试的其他解决方案只打印了一页,只打印屏幕上的内容。埃米尔接受的解决方案对我很有效:

这就是组件最终的样子。它会打印模态体中的所有内容

import React, { Component } from 'react';
import {
    Button,
    Modal,
    ModalBody,
    ModalHeader
} from 'reactstrap';

export default class TestPrint extends Component{
    constructor(props) {
        super(props);
        this.state = {
            modal: false,
            data: [
                'test', 'test', 'test', 'test', 'test', 'test', 
                'test', 'test', 'test', 'test', 'test', 'test', 
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test',
                'test', 'test', 'test', 'test', 'test', 'test'            
            ]
        }
        this.toggle = this.toggle.bind(this);
        this.print = this.print.bind(this);
    }

    print() {
        var content = document.getElementById('printarea');
        var pri = document.getElementById('ifmcontentstoprint').contentWindow;
        pri.document.open();
        pri.document.write(content.innerHTML);
        pri.document.close();
        pri.focus();
        pri.print();
    }

    renderContent() {
        var i = 0;
        return this.state.data.map((d) => {
            return (<p key={d + i++}>{i} - {d}</p>)
        });
    }

    toggle() {
        this.setState({
            modal: !this.state.modal
        })
    }

    render() {
        return (
            <div>
                <Button 
                    style={
                        {
                            'position': 'fixed',
                            'top': '50%',
                            'left': '50%',
                            'transform': 'translate(-50%, -50%)'
                        }
                    } 
                    onClick={this.toggle}
                >
                    Test Modal and Print
                </Button>         
                <Modal 
                    size='lg' 
                    isOpen={this.state.modal} 
                    toggle={this.toggle} 
                    className='results-modal'
                >  
                    <ModalHeader toggle={this.toggle}>
                        Test Printing
                    </ModalHeader>
                    <iframe id="ifmcontentstoprint" style={{
                        height: '0px',
                        width: '0px',
                        position: 'absolute'
                    }}></iframe>      
                    <Button onClick={this.print}>Print</Button>
                    <ModalBody id='printarea'>              
                        {this.renderContent()}
                    </ModalBody>
                </Modal>
            </div>
        )
    }
}
import React,{Component}来自'React';
进口{
按钮
情态动词
ModalBody,
模头
}来自“反应带”;
导出默认类TestPrint扩展组件{
建造师(道具){
超级(道具);
此.state={
莫代尔:错,
数据:[
‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’,
‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’,
‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’,
‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’,
‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’,
‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’,
‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’,
‘测试’、‘测试’、‘测试’、‘测试’、‘测试’、‘测试’
]
}
this.toggle=this.toggle.bind(this);
this.print=this.print.bind(this);
}
打印(){
var content=document.getElementById('printarea');
var pri=document.getElementById('ifmcontentstoprint').contentWindow;
pri.document.open();
pri.document.write(content.innerHTML);
pri.document.close();
pri.focus();
pri.print();
}
renderContent(){
var i=0;
返回此.state.data.map((d)=>{
返回(

{i}-{d}

) }); } 切换(){ 这是我的国家({ 模态:!this.state.modal }) } render(){ 返回( 测试模式和打印 试印 印刷品 {this.renderContent()} ) } }

注意:然而,我很难在
iframe

中反映出风格。首先,我想感谢@emil ingerslev给出了一个很棒的答案。我对它进行了测试,效果非常好。有两件事我想改进

  • 我不喜欢在dom树中已经有
  • 我想创造一种使它可重用的方法
  • 我希望这能让其他人开心,节省几分钟的生命。现在,多花点时间,为别人做点好事

    function printPartOfPage(elementId, uniqueIframeId){
        const content = document.getElementById(elementId)
        let pri
        if (document.getElementById(uniqueIframeId)) {
            pri = document.getElementById(uniqueIframeId).contentWindow
        } else {
            const iframe = document.createElement('iframe')
            iframe.setAttribute('title', uniqueIframeId)
            iframe.setAttribute('id', uniqueIframeId)
            iframe.setAttribute('style', 'height: 0px; width: 0px; position: absolute;')
            document.body.appendChild(iframe)
            pri = iframe.contentWindow
        }
        pri.document.open()
        pri.document.write(content.innerHTML)
        pri.document.close()
        pri.focus()
        pri.print()
    }
    

    编辑2019-7-23:在更多地使用此选项后,它确实有一个缺点,即无法完美地渲染react组件。当样式是内联的,但当由样式化组件或其他一些情况处理时,这对我来说是有效的。如果我想出一个简单的方法,我会更新。

    Emil Ingerslev提供的解决方案运行良好,但CSS不应用于输出。在这里,我找到了一个很好的解决方案。它会打印文件的内容
    import React, { Component } from 'react';
    import {
        Button,
        Modal,
        ModalBody,
        ModalHeader
    } from 'reactstrap';
    
    export default class TestPrint extends Component{
        constructor(props) {
            super(props);
            this.state = {
                modal: false,
                data: [
                    'test', 'test', 'test', 'test', 'test', 'test', 
                    'test', 'test', 'test', 'test', 'test', 'test', 
                    'test', 'test', 'test', 'test', 'test', 'test',
                    'test', 'test', 'test', 'test', 'test', 'test',
                    'test', 'test', 'test', 'test', 'test', 'test',
                    'test', 'test', 'test', 'test', 'test', 'test',
                    'test', 'test', 'test', 'test', 'test', 'test',
                    'test', 'test', 'test', 'test', 'test', 'test'            
                ]
            }
            this.toggle = this.toggle.bind(this);
            this.print = this.print.bind(this);
        }
    
        print() {
            var content = document.getElementById('printarea');
            var pri = document.getElementById('ifmcontentstoprint').contentWindow;
            pri.document.open();
            pri.document.write(content.innerHTML);
            pri.document.close();
            pri.focus();
            pri.print();
        }
    
        renderContent() {
            var i = 0;
            return this.state.data.map((d) => {
                return (<p key={d + i++}>{i} - {d}</p>)
            });
        }
    
        toggle() {
            this.setState({
                modal: !this.state.modal
            })
        }
    
        render() {
            return (
                <div>
                    <Button 
                        style={
                            {
                                'position': 'fixed',
                                'top': '50%',
                                'left': '50%',
                                'transform': 'translate(-50%, -50%)'
                            }
                        } 
                        onClick={this.toggle}
                    >
                        Test Modal and Print
                    </Button>         
                    <Modal 
                        size='lg' 
                        isOpen={this.state.modal} 
                        toggle={this.toggle} 
                        className='results-modal'
                    >  
                        <ModalHeader toggle={this.toggle}>
                            Test Printing
                        </ModalHeader>
                        <iframe id="ifmcontentstoprint" style={{
                            height: '0px',
                            width: '0px',
                            position: 'absolute'
                        }}></iframe>      
                        <Button onClick={this.print}>Print</Button>
                        <ModalBody id='printarea'>              
                            {this.renderContent()}
                        </ModalBody>
                    </Modal>
                </div>
            )
        }
    }
    
    function printPartOfPage(elementId, uniqueIframeId){
        const content = document.getElementById(elementId)
        let pri
        if (document.getElementById(uniqueIframeId)) {
            pri = document.getElementById(uniqueIframeId).contentWindow
        } else {
            const iframe = document.createElement('iframe')
            iframe.setAttribute('title', uniqueIframeId)
            iframe.setAttribute('id', uniqueIframeId)
            iframe.setAttribute('style', 'height: 0px; width: 0px; position: absolute;')
            document.body.appendChild(iframe)
            pri = iframe.contentWindow
        }
        pri.document.open()
        pri.document.write(content.innerHTML)
        pri.document.close()
        pri.focus()
        pri.print()
    }
    
    var printContents = document.getElementById("divcontents").innerHTML;
    var originalContents = document.body.innerHTML;
    document.body.innerHTML = printContents;
    window.print();
    document.body.innerHTML = originalContents;
    
    .printme { display: none;}
    @media print { 
        .no-printme  { display: none;}
        .printme  { display: block;}
    }
    
    <h1 class = "no-printme"> do not print this </h1>    
    <div class='printme'>
      Print this only 
    </div>    
    <button onclick={window.print()}>Print only the above div</button>