#javascript #html #reactjs #printing
#javascript #HTML #reactjs #печать
Вопрос:
Мне нужно распечатать список элементов одним нажатием кнопки. У меня есть данные в моем серверном интерфейсе, и я создаю таблицу элементов с 5 элементами в каждой строке с помощью следующего:
const labelDataHTML = (values) => (
<table id="dataTable" style={{ width: "100%" }}>
<caption>Labels</caption>
{_.chunk(values, 5).map((item, index) => (
<tr key={`row-${index}`} className={`row`}>
{index % 5 !== 0
? item.map((obj) => <td>{obj}</td>)
: item.map((obj) => <td>{obj}</td>)}
</tr>
))}
</table>
);
Я извлекаю HTML-объект в другой функции, которую запускаю нажатием кнопки (нашел этот блок кода на других страницах SO):
const printData = (domElement) => {
var printContents = document.querySelector("table").innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
};
С этим связано 2 проблемы. 1 заключается в том, что я теряю все элементы таблицы HTML при нажатии кнопки печати, и это просто становится длинным списком без пробелов. Во-вторых, как только я нажимаю на это, все остальные элементы на моей странице перестают отвечать. Я также прикрепил [песочницу][1].
Я новичок в React и javascript в целом. Ценю любую помощь!
ОБНОВЛЕНИЕ: Вот как я решил проблему: я нашел это решение на основе тонны других вопросов, которые я нашел на SO:
const labelDataHTML = values =>
ReactDOMServer.renderToString(
<table id="dataTable" style={{ width: "100%" }}>
<caption>Labels</caption>
{_.chunk(values, 5).map((item, index) => {
return (
<tr className={`row`}>
{index % 5 !== 0
? item.map(obj => <td>{obj}</td>)
: item.map(obj => <td>{obj}</td>)
}
</tr>
);
})}
</table>
);
const PrintLabels = labelData => {
let domElement = labelDataHTML(labelData)
let windowInstance = window.open("");
windowInstance.document.write(domElement);
windowInstance.print();
windowInstance.close();
};
Ответ №1:
Для вашей первой проблемы вам нужно обернуть свой тег printContents
в html table
.
`<table>${printContents}</table>`
Для вашей второй проблемы вам нужно создать экземпляр window и открыть диалоговое окно печати в новом окне, а затем закрыть экземпляр. Вы можете реорганизовать свою функцию примерно так:
const printData = (domElement) => {
let printContents = document.querySelector("table").innerHTML;
let windowInstance= window.open("");
windowInstance.document.write(`<table>${printContents}</table>`);
windowInstance.print();
windowInstance.close();
};
Комментарии:
1. Привет! Принимаю ваш ответ как правильный. Хотя это было не совсем то, что я искал, это вывело меня на правильный путь! Спасибо, что так быстро ответили!
Ответ №2:
Вы временно изменяете содержимое страницы способом, который я нахожу очень хакерским для достижения этой цели.
Лучшим способом было бы скрыть все остальные элементы на странице только для печати с помощью css:
@media print {
body * {
visibility: hidden;
}
#dataTable,
#dataTable * {
visibility: visible;
}
#dataTable {
position: absolute;
left: 0;
top: 0;
}
}
Затем вы можете просто распечатать таблицу с помощью:
window.print();
Комментарии:
1. Я должен был объяснить это лучше. У меня возникла таблица запросов. К каждому запросу прикреплено несколько меток (которые генерируются при создании запроса). Я помещаю кнопку печати в последний столбец этой таблицы, чтобы распечатать метки. Этот пример предназначен для печати этих меток, поэтому я не могу использовать CSS для их печати, поскольку они никогда не отображаются на моей странице, а только сохраняются в state . Я не собирался изменять содержимое страницы. Пытаюсь найти способ использовать сгенерированный HTML-код и передать его в функцию печати onClick