• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hazendaz / displaytag / 1753

12 Feb 2026 03:17AM UTC coverage: 77.321% (-0.01%) from 77.334%
1753

push

github

web-flow
Merge pull request #1102 from hazendaz/renovate/javax-support-logback-monorepo

Update dependency ch.qos.logback:logback-classic to v1.5.29 (javax-support)

1438 of 2003 branches covered (71.79%)

Branch coverage included in aggregate %.

4034 of 5074 relevant lines covered (79.5%)

0.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/displaytag/src/main/java/org/displaytag/export/PdfView.java
1
/*
2
 * SPDX-License-Identifier: MIT
3
 * See LICENSE file for details.
4
 *
5
 * Copyright 2002-2026 Fabrizio Giustina, the Displaytag team
6
 */
7
package org.displaytag.export;
8

9
import com.itextpdf.text.BaseColor;
10
import com.itextpdf.text.Chunk;
11
import com.itextpdf.text.Document;
12
import com.itextpdf.text.Element;
13
import com.itextpdf.text.Font;
14
import com.itextpdf.text.FontFactory;
15
import com.itextpdf.text.PageSize;
16
import com.itextpdf.text.Phrase;
17
import com.itextpdf.text.pdf.ColumnText;
18
import com.itextpdf.text.pdf.PdfPCell;
19
import com.itextpdf.text.pdf.PdfPTable;
20
import com.itextpdf.text.pdf.PdfPageEventHelper;
21
import com.itextpdf.text.pdf.PdfWriter;
22

23
import java.io.OutputStream;
24
import java.util.Iterator;
25

26
import javax.servlet.jsp.JspException;
27

28
import org.apache.commons.lang3.StringUtils;
29
import org.displaytag.Messages;
30
import org.displaytag.exception.BaseNestableJspTagException;
31
import org.displaytag.exception.SeverityEnum;
32
import org.displaytag.model.Column;
33
import org.displaytag.model.ColumnIterator;
34
import org.displaytag.model.HeaderCell;
35
import org.displaytag.model.Row;
36
import org.displaytag.model.RowIterator;
37
import org.displaytag.model.TableModel;
38
import org.displaytag.util.TagConstants;
39

40
/**
41
 * PDF exporter using IText. This class is provided more as an example than as a "production ready" class: users
42
 * probably will need to write a custom export class with a specific layout.
43
 */
44
public class PdfView implements BinaryExportView {
×
45

46
    /**
47
     * TableModel to render.
48
     */
49
    private TableModel model;
50

51
    /** export full list?. */
52
    private boolean exportFull;
53

54
    /** include header in export?. */
55
    private boolean header;
56

57
    /** decorate export?. */
58
    private boolean decorated;
59

60
    /**
61
     * This is the table, added as an Element to the PDF document. It contains all the data, needed to represent the
62
     * visible table into the PDF
63
     */
64
    private PdfPTable tablePDF;
65

66
    /**
67
     * The default font used in the document.
68
     */
69
    private Font smallFont;
70

71
    /**
72
     * Sets the parameters.
73
     *
74
     * @param tableModel
75
     *            the table model
76
     * @param exportFullList
77
     *            the export full list
78
     * @param includeHeader
79
     *            the include header
80
     * @param decorateValues
81
     *            the decorate values
82
     *
83
     * @see org.displaytag.export.ExportView#setParameters(TableModel, boolean, boolean, boolean)
84
     */
85
    @Override
86
    public void setParameters(final TableModel tableModel, final boolean exportFullList, final boolean includeHeader,
87
            final boolean decorateValues) {
88
        this.model = tableModel;
×
89
        this.exportFull = exportFullList;
×
90
        this.header = includeHeader;
×
91
        this.decorated = decorateValues;
×
92
    }
×
93

94
    /**
95
     * Initialize the main info holder table.
96
     */
97
    protected void initTable() {
98
        this.tablePDF = new PdfPTable(this.model.getNumberOfColumns());
×
99
        this.tablePDF.getDefaultCell().setVerticalAlignment(Element.ALIGN_TOP);
×
100
        this.tablePDF.setWidthPercentage(100);
×
101

102
        this.smallFont = FontFactory.getFont(FontFactory.HELVETICA, 7, Font.NORMAL, new BaseColor(0, 0, 0));
×
103

104
    }
×
105

106
    /**
107
     * Gets the mime type.
108
     *
109
     * @return "application/pdf"
110
     *
111
     * @see org.displaytag.export.BaseExportView#getMimeType()
112
     */
113
    @Override
114
    public String getMimeType() {
115
        return "application/pdf"; //$NON-NLS-1$
×
116
    }
117

118
    /**
119
     * The overall PDF table generator.
120
     *
121
     * @throws JspException
122
     *             for errors during value retrieving from the table model
123
     */
124
    protected void generatePDFTable() throws JspException {
125
        if (this.header) {
×
126
            this.generateHeaders();
×
127
        }
128
        this.generateRows();
×
129
    }
×
130

131
    /**
132
     * Do export.
133
     *
134
     * @param out
135
     *            the out
136
     *
137
     * @throws JspException
138
     *             the jsp exception
139
     *
140
     * @see org.displaytag.export.BinaryExportView#doExport(OutputStream)
141
     */
142
    @Override
143
    public void doExport(final OutputStream out) throws JspException {
144
        try {
145
            // Initialize the table with the appropriate number of columns
146
            this.initTable();
×
147

148
            // Initialize the Document and register it with PdfWriter listener and the OutputStream
149
            final Document document = new Document(PageSize.A4.rotate(), 60, 60, 40, 40);
×
150
            document.addCreationDate();
×
151

152
            final PdfWriter writer = PdfWriter.getInstance(document, out);
×
153
            writer.setPageEvent(new PdfPageEventHelper() {
×
154

155
                @Override
156
                public void onEndPage(final PdfWriter writer, final Document document) {
157

158
                    ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER,
×
159
                            new Phrase(TagConstants.EMPTY_STRING, PdfView.this.smallFont),
160
                            (document.left() + document.right()) / 2, document.bottom() - 18, 0);
×
161
                }
×
162

163
            });
164

165
            // Fill the virtual PDF table with the necessary data
166
            this.generatePDFTable();
×
167

168
            document.open();
×
169
            document.add(this.tablePDF);
×
170
            document.close();
×
171

172
        } catch (final Exception e) {
×
173
            throw new PdfGenerationException(e);
×
174
        }
×
175
    }
×
176

177
    /**
178
     * Generates the header cells, which persist on every page of the PDF document.
179
     */
180
    protected void generateHeaders() {
181
        final Iterator<HeaderCell> iterator = this.model.getHeaderCellList().iterator();
×
182

183
        while (iterator.hasNext()) {
×
184
            final HeaderCell headerCell = iterator.next();
×
185

186
            String columnHeader = headerCell.getTitle();
×
187

188
            if (columnHeader == null) {
×
189
                columnHeader = StringUtils.capitalize(headerCell.getBeanPropertyName());
×
190
            }
191

192
            final PdfPCell hdrCell = this.getCell(columnHeader);
×
193
            hdrCell.setGrayFill(0.9f);
×
194
            this.tablePDF.addCell(hdrCell);
×
195

196
        }
×
197
        this.tablePDF.setHeaderRows(1);
×
198
    }
×
199

200
    /**
201
     * Generates all the row cells.
202
     *
203
     * @throws JspException
204
     *             for errors during value retrieving from the table model
205
     */
206
    protected void generateRows() throws JspException {
207
        // get the correct iterator (full or partial list according to the exportFull field)
208
        final RowIterator rowIterator = this.model.getRowIterator(this.exportFull);
×
209
        // iterator on rows
210
        while (rowIterator.hasNext()) {
×
211
            final Row row = rowIterator.next();
×
212

213
            // iterator on columns
214
            final ColumnIterator columnIterator = row.getColumnIterator(this.model.getHeaderCellList());
×
215

216
            while (columnIterator.hasNext()) {
×
217
                final Column column = columnIterator.nextColumn();
×
218

219
                // Get the value to be displayed for the column
220
                final Object value = column.getValue(this.decorated);
×
221

222
                final PdfPCell cell = this.getCell(value != null ? value.toString() : StringUtils.EMPTY);
×
223
                this.tablePDF.addCell(cell);
×
224
            }
×
225
        }
×
226
    }
×
227

228
    /**
229
     * Returns a formatted cell for the given value.
230
     *
231
     * @param value
232
     *            cell value
233
     *
234
     * @return Cell
235
     */
236
    private PdfPCell getCell(final String value) {
237
        final PdfPCell cell = new PdfPCell(new Phrase(new Chunk(StringUtils.trimToEmpty(value), this.smallFont)));
×
238
        cell.setVerticalAlignment(Element.ALIGN_TOP);
×
239
        cell.setLeading(8, 0);
×
240
        cell.setPadding(2);
×
241
        return cell;
×
242
    }
243

244
    /**
245
     * Wraps IText-generated exceptions.
246
     */
247
    static class PdfGenerationException extends BaseNestableJspTagException {
248

249
        /**
250
         * Serial ID.
251
         */
252
        private static final long serialVersionUID = 899149338534L;
253

254
        /**
255
         * Instantiate a new PdfGenerationException with a fixed message and the given cause.
256
         *
257
         * @param cause
258
         *            Previous exception
259
         */
260
        public PdfGenerationException(final Throwable cause) {
261
            super(PdfView.class, Messages.getString("PdfView.errorexporting"), cause); //$NON-NLS-1$
×
262
        }
×
263

264
        /**
265
         * Gets the severity.
266
         *
267
         * @return the severity
268
         *
269
         * @see org.displaytag.exception.BaseNestableJspTagException#getSeverity()
270
         */
271
        @Override
272
        public SeverityEnum getSeverity() {
273
            return SeverityEnum.ERROR;
×
274
        }
275
    }
276
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc