Компонент React теряет форматирование, связанное с className, при печати, запускаемой с кнопки, но сохраняет его, когда выполняется встроенным - PullRequest
0 голосов
/ 26 апреля 2018

Проблема React и печати не давала мне покоя в течение последних полутора недель, и я не чувствую, что я чего-то добиваюсь.

Я нашел это полезное ПО, но ни одно из решенийработать полностью для меня:

Как напечатать компонент React одним нажатием кнопки?

Результат в основном один и тот же каждый раз: стили не отражаются, когда вынажмите кнопку «Печать», и появится диалоговое окно печати.Я практически исчерпал все возможные варианты и настройки.

Вот мое репо по этой проблеме:

https://github.com/ishraqiyun77/react-print-iframe-issue

В этом примере япросто пытаюсь сделать текст красным с помощью color: red.Это форматирование отображается на экране, но исчезает, когда нажимается кнопка «Печать» и появляется предварительный просмотр.Так не должно быть.@media print не влияет на это.

Кнопка «Печать» должна работать правильно, а не просто печатать в браузере или CTRL + P, потому что многие из наших пользователей не разбираются в этом ... вообще.

В репо включена измененная версия bootstrap.css, в которой удалены все @media print.

Итак, что здесь происходит и почему стили из внешнего файла назначаются черезclassName не работает, но встроенный CSS работает?Любая помощь приветствуется.(Встроенный не вариант, так как это будет беспорядок).

// component.jsx
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {
    Button,
    Modal,
    ModalBody,
    ModalHeader
} from 'reactstrap';

import styles from '../assets/scss/app.scss';

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) => {
            i++
            return (<p className='printtest' key={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>
        )
    }
}

ReactDOM.render(<TestPrint />, document.getElementById('app'));

.printtest {
    color: red !important;
}

Затем, если вы измените метод renderContent() на следующий, стили будут работать при печати (носнова нежелательно, так как это будет беспорядок):

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

РЕДАКТИРОВАТЬ

И я попытался CTRL + P, печать из браузера, печать окна с JS,и используя CSS, как показано ниже:

@media print {
    body * {
        visibility: hidden;
    }

    .printtest, .printtest* {
        visibility: visible;
    }

    .printtest {
        position: absolute;
        left: 0;
        top: 0;
        overflow: scroll/visible/auto;
    }
}

Проблема с этим, хотя он печатает только одну страницу и то, что в данный момент на экране, а не все данные, загруженные в модальное пространство.

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

Исходя из того, что предложил Аль Фарнсворт, мне пришлось сделать следующее, и теперь это работает:

    var content = document.getElementById('print');
    var pri = document.getElementById('ifmcontentstoprint').contentWindow;
    pri.document.open();
    pri.document.write(content.innerHTML);

    // generate CSS links
    var bootstrap = document.createElement('link');
    bootstrap.href = '/static/css/bootstrap.css';
    bootstrap.rel = 'stylesheet';
    pri.document.head.appendChild(bootstrap);

    var app = document.createElement('link');
    app.href = '/static/css/bq_print.css';
    app.rel = 'stylesheet';
    pri.document.head.appendChild(app);
0 голосов
/ 29 апреля 2018

Глядя на ваш пример, я не вижу CSS внутри вашего iframe.Стили из родительского документа не применяются к элементам внутри <iframe>.Если вы хотите этого, вам нужно будет вручную вставить ссылки CSS в iframe.

Вы сможете увидеть, что происходит, просто сделав фрейм и проверив его с помощью devtools.Возьмите ширину: 0 высоту,: 0 выкл.У меня такое чувство, что вы увидите, что даже в экранной версии отсутствуют CSS-файлы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...