首页 > 解决方案 > 如何打印 Vaadin Flow 对话框?

问题描述

我在 vaadin 流程中有很多对话框,我想让用户打印它们。我知道如何按以下代码打印整个页面,但我只想打印页面上方的对话框。

Button btnPrint = new Button( "Print…" );
    btnPrint .addClickListener( ( ClickEvent < Button > clickEvent ) ->
    {
         // this Prints the current page
        UI.getCurrent().getPage().executeJs( "print();" );
    } );

我也用java脚本试过这个,但没有成功。

window.printPartOfPage = function (divPrintId) {
console.log("Inside printPartOfPage");
var printContent = document.getElementById(divPrintId);
var WinPrint = window.open('', '', 'letf=100,top=100,width=600,height=600');
WinPrint.document.write(printContent.innerHTML);
WinPrint.document.close();
WinPrint.focus();
WinPrint.print();
WinPrint.close();

}

任何想法如何做到这一点?

标签: javascriptjavavaadinvaadin-flow

解决方案


两者vaadin-dialogvaadin-dialog-overlay都是自定义元素并使用 Shadow DOM。Shadow DOM 的主要特征之一是用新的 DOM(称为“Shadow DOM”)掩盖初始 DOM(称为“Light DOM”)。因此,如果没有某种网络反射,调用innerHTML不会返回您所期望的。此外,如果它确实有效,您将使用outerHTML.

一种解决方案是使用 CSS ...

定义新样式:

.no-print {
  display: none !important;
}

当您要打印时,将该类添加到除vaadin-dialogand之外的所有元素vaadin-dialog-overlay

UI.getCurrent().getPage().executeJs("" +
    "const body = document.body;" +
    "" +
    "for(let child = body.firstChild; child !== null; child = child.nextSibling) {" +
    "  if(child.tagName !== 'vaadin-dialog' && child.id !== 'overlay') {" +
    "    child.classList.add('no-print');" +
    "  }" +
    "  " +
    "}" +
    "" +
    "window.print();" +
    "" +
    "for(let child = body.firstChild; child !== null; child = child.nextSibling) {" +
    "  child.classList.remove('no-print');" +
    "}"
);

显然,这不是最有效的方法。特别是因为其他元素,例如scripts,将获得no-print该类。但希望这能给你一个想法。

我希望这有帮助!


推荐阅读