1

我想打印一个扩展 Composite 的 GWT 小部件。此小部件由一个网格组成,其单元格是使用 ListDataProvider 构建的。当用户单击按钮打印时,将构建要打印的小部件。完成后,我启动打印:

    Element element = widgetToPrint.getElement();
    String content = element.getInnerHTML();
    print(content);


    public static native boolean print(String content)
    /*-{
    var mywindow = window.open('', 'Printing', '');
    mywindow.document.write('<html><head><title>Test</title>');
    mywindow.document.write('<link rel="stylesheet" href="/public/stylesheets/ToPrintWidget.css" type="text/css" media="all"/></head><body>');
    mywindow.document.write(content);
    mywindow.document.write('</body></html>');
    mywindow.print();
    return true;
    }-*/;

所以,这是我的问题:

此方法打开的窗口包含小部件的核心(由 UI Binder 构建),但缺少一些子...

如果我查看 ListDataProvider 及其相关的 FlowPanel,数据是一致的,即我的列表和 flowPanel 中有几个项目。

因此,它应该在打印窗口上可见......我认为问题可能与用于打印小部件的方法有关,所以我也尝试在启动打印之前将此小部件添加到对话框中,看看是否该小部件已正确构建...确实如此。

所以我的小部件在对话框上显示得很好,但是如果我尝试通过使用 getElement() 将其 innerHTML 提供给打印方法,一些小部件会丢失......我感觉应该在ListDataProvider 更改未在 DOM 中正确设置...当我将小部件添加到常规组件时它以某种方式工作,但是当我必须直接提供其 innerHTML 时它不起作用...

你有什么主意吗 ?

提前致谢。

4

4 回答 4

2

小部件不仅仅是它们元素的总和,DOM 元素不仅仅是它们被序列化的字符串。小部件是元素,所有事件都下沉到 dom 以侦听用户的任何更改或交互。然后,元素具有回调函数或当用户与它们交互时调用的处理程序。

通过对元素进行序列化(即调用getInnerHTML()),您只是读出了 dom 的结构,而不是回调,而且还不是 CSS 设置的样式。可能不应该期望这可以正常工作,并且正如您的经验所证明的那样,事实并非如此。

由于这只是您尝试创建的打印窗口,因此事件处理可能不是问题。您只希望能够查看该组小部件中的内容,但不能与之交互。样式可能是这里的主要问题(尽管您的问题没有指定“缺少一些孩子”并没有告诉我们缺少什么,或者给我们更多关于为什么的线索......) - 您正在添加一个样式表在您的 JSNI 代码中,但 CellTable(我假设您正在使用它,因为您引用了 ListDataProvider)需要额外的 CssResource 实例才能正确显示。我不确定你如何劫持那些在新窗口中绘制。

你只是用它来打印内容,而不是让用户直接与数据交互吗?如果是这样,请考虑另一种方法 - 使用 SafeHtmlBuilder 创建一个巨大的、正确转义的内容字符串以在新窗口中绘制。

于 2012-12-03T23:56:36.047 回答
0

首先感谢您的回答,它帮助我解决了这个问题。我几乎解决了这个问题:

首先,我不再使用 ListDataProvider,因为我不清楚何时以及如何刷新视图。相反,我手动添加了我的小部件,这是有道理的,因为它们无论如何都不会移动。

然后,我使用通用 CSS 样式表定义小部件的样式。但是,为了做到这一点,我不能依赖 CssResource,这是我过去使用 GWT 的方式。我认为这来自被这种样式丢失的 JS 方法......相反,我必须在静态 CSS 样式表中指定所有内容,并将其提供给 JS。

它工作得非常好,即,我有我的小部件,有它们的样式,我可以打印它。

但是......一些小部件的颜色取决于它们所代表的对象的颜色。因此,我无法编写通用 CSS 样式表...正如我所说,我无法使用 CssResource 添加样式...您对处理该问题有什么想法吗?

为了确保我清楚我添加样式的方式,这里有一个例子:

    Label l = new Label("Here is a cell in my grid to be printed");
    l.addStyleName("PrintLineCell-kind_1");

在公共 CSS 样式表中:

    .PrintLineCell-kind_1{
        background-color: red;
    }

我希望有更好的方法,而不是写 300 种样式来涵盖 300 种不同的颜色...

于 2012-12-05T09:19:53.850 回答
0

您可能想要获取外部 HTML而不是内部HTML 。

不幸的是,GWT 没有getOuterHTML,但它比较容易模仿

  • 如果您的小部件是元素中唯一的子元素,则只需获取父元素的内部 HTML ( w.getElement().getParentElement().getInnerHTML())
  • 否则,克隆您的小部件的节点,将其添加到新创建的父元素中,您将能够从中获取内部 HTML:

    DivElement temp = Document.get().createDivElement();
    temp.appendChild(w.getElement().cloneNode(true));
    return temp.getInnerHTML();
    
于 2012-12-04T08:16:16.220 回答
0
String content = element.toString();

这将包括节点中的所有层次结构元素。

提醒一下,所有的 GWT 处理程序都不起作用,您必须使用 DOM 接收所有事件。

于 2012-12-04T08:36:00.117 回答