aboutsummaryrefslogtreecommitdiffstats
path: root/documentation/advanced/advanced-printing.asciidoc
blob: 22f0ed2ca2c83e8f08e64641eedbeb37ad70e921 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
---
title: Printing
order: 6
layout: page
---

[[advanced.printing]]
= Printing

((("printing", id="term.advanced.printing", range="startofrange")))


Vaadin does not have any special support for printing. There are two basic ways
to print - in a printer controlled by the application server or by the user from
the web browser. Printing in the application server is largely independent of
the UI, you just have to take care that printing commands do not block server
requests, possibly by running the print commands in another thread.

((("[methodname]#print()#", id="term.advanced.printing.print",
range="startofrange")))


((("JavaScript", "[methodname]#print()#",
id="term.advanced.printing.JavaScript.print",
range="startofrange")))


For client-side printing, most browsers support printing the web page. You can
either print the current or a special print page that you open. The page can be
styled for printing with special CSS rules, and you can hide unwanted elements.
You can also print other than Vaadin UI content, such as HTML or PDF.

[[advanced.printing.browserwindow]]
== Printing the Browser Window

Vaadin does not have special support for launching the printing in browser, but
you can easily use the JavaScript [methodname]#print()# method that opens the
print window of the browser.

((("JavaScript", "[methodname]#execute()#")))

[source, java]
----
Button print = new Button("Print This Page");
print.addClickListener(new Button.ClickListener() {
    public void buttonClick(ClickEvent event) {
        // Print the current page
        JavaScript.getCurrent().execute("print();");
    }
});
----

The button in the above example would print the current page, including the
button itself. You can hide such elements in CSS, as well as otherwise style the
page for printing. Style definitions for printing are defined inside a
[literal]#++@media print {}++# block in CSS.


[[advanced.printing.opening]]
== Opening a Print Window

You can open a browser window with a special UI for print content and
automatically launch printing the content.


[source, java]
----
public static class PrintUI extends UI {
    @Override
    protected void init(VaadinRequest request) {
        // Have some content to print
        setContent(new Label(
            "<h1>Here's some dynamic content</h1>\n" +
            "<p>This is to be printed.</p>",
            ContentMode.HTML));
        
        // Print automatically when the window opens
        JavaScript.getCurrent().execute(
            "setTimeout(function() {" +
            "  print(); self.close();}, 0);");
    }
}
...

// Create an opener extension
BrowserWindowOpener opener =
        new BrowserWindowOpener(PrintUI.class);
opener.setFeatures("height=200,width=400,resizable");
    
// A button to open the printer-friendly page.
Button print = new Button("Click to Print");
opener.extend(print);
----

How the browser opens the window, as an actual (popup) window or just a tab,
depends on the browser. After printing, we automatically close the window with
JavaScript [methodname]#close()# call.

(((range="endofrange", startref="term.advanced.printing.print")))
(((range="endofrange", startref="term.advanced.printing.JavaScript.print")))

[[advanced.printing.pdf]]
== Printing PDF

((("PDF")))
To print content as PDF, you need to provide the downloadable content as a
static or a dynamic resource, such as a [classname]#StreamResource#.

You can let the user open the resource using a [classname]#Link# component, or
some other component with a [classname]#BrowserWindowOpener# extension. When such
a link or opener is clicked, the browser opens the PDF in the browser, in an
external viewer (such as Adobe Reader), or lets the user save the document.

It is crucial to notice that clicking a [classname]#Link# or a
[classname]#BrowserWindowOpener# is a client-side operation. If you get the
content of the dynamic PDF from the same UI state, you can not have the link or
opener enabled, as then clicking it would not get the current UI content.
Instead, you have to create the resource object before the link or opener are
clicked. This usually requires a two-step operation, or having the print
operation available in another view.


[source, java]
----
// A user interface for a (trivial) data model from which
// the PDF is generated.
final TextField name = new TextField("Name");
name.setValue("Slartibartfast");

// This has to be clicked first to create the stream resource
final Button ok = new Button("OK");

// This actually opens the stream resource
final Button print = new Button("Open PDF");
print.setEnabled(false);

ok.addClickListener(new ClickListener() {
    @Override
    public void buttonClick(ClickEvent event) {
        // Create the PDF source and pass the data model to it
        StreamSource source =
            new MyPdfSource((String) name.getValue());
        
        // Create the stream resource and give it a file name
        String filename = "pdf_printing_example.pdf";
        StreamResource resource =
                new StreamResource(source, filename);
        
        // These settings are not usually necessary. MIME type
        // is detected automatically from the file name, but
        // setting it explicitly may be necessary if the file
        // suffix is not ".pdf".
        resource.setMIMEType("application/pdf");
        resource.getStream().setParameter(
                "Content-Disposition",
                "attachment; filename="+filename);

        // Extend the print button with an opener
        // for the PDF resource
        BrowserWindowOpener opener =
                new BrowserWindowOpener(resource);
        opener.extend(print);
      
        name.setEnabled(false);
        ok.setEnabled(false);
        print.setEnabled(true);
    }
});

layout.addComponent(name);
layout.addComponent(ok);
layout.addComponent(print);
----


(((range="endofrange", startref="term.advanced.printing")))