View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.commons.exporter.util;
20  
21  import java.io.ByteArrayOutputStream;
22  import java.io.IOException;
23  import java.util.List;
24  
25  import javax.faces.component.UIColumn;
26  import javax.faces.component.UIComponent;
27  import javax.faces.component.ValueHolder;
28  import javax.faces.component.html.HtmlDataTable;
29  import javax.faces.context.FacesContext;
30  import javax.servlet.ServletOutputStream;
31  import javax.servlet.http.HttpServletResponse;
32  
33  import com.lowagie.text.Document;
34  import com.lowagie.text.pdf.PdfPTable;
35  import com.lowagie.text.pdf.PdfWriter;
36  
37  /**
38   * This class is a utility class for serving PDF exporting.
39   */
40  public class PDFExporterUtil
41  {
42  
43      /*
44       * This method is used for setting the response headers of the pdf.
45       */
46      private static void setPDFResponseHeaders(HttpServletResponse response,
47              ByteArrayOutputStream byteArrayStream, String fileName)
48              throws IOException
49      {
50  
51          // setting response headers.
52          response.setHeader("Expires", "0");
53          response.setHeader("Cache-Control",
54                  "must-revalidate, post-check=0, pre-check=0");
55          response.setHeader("Pragma", "public");
56          response.setHeader("Content-disposition", "attachment;filename="
57                  + fileName + ".pdf");
58  
59          // setting the content type.
60          response.setContentType("application/pdf");
61  
62          // the contentlength is needed for MSIE.
63          response.setContentLength(byteArrayStream.size());
64  
65          // write ByteArrayOutputStream to the ServletOutputStream.
66          ServletOutputStream outputStream = response.getOutputStream();
67  
68          byteArrayStream.writeTo(outputStream);
69          outputStream.flush();
70      }
71  
72      /*
73       * This method is used for adding the columns headers to the pdfTable.
74       */
75      private static void generateTableHeader(PdfPTable pdfTable, List columns)
76      {
77          for (int i = 0; i < columns.size(); i++)
78          {
79              UIColumn column = (UIColumn) columns.get(i);
80              UIComponent columnHeaderCell = column.getHeader();
81              if (columnHeaderCell instanceof ValueHolder)
82              {
83                  String cellValue = ComponentUtils.getStringValue(FacesContext
84                          .getCurrentInstance(), columnHeaderCell);
85                  pdfTable.addCell(cellValue);
86              }
87          }
88      }
89  
90      /*
91       * This method is used for adding the columns values to the pdfTable.
92       */
93      private static void generateTableContent(FacesContext facesContext,
94              PdfPTable pdfTable, List columns, HtmlDataTable dataTable)
95      {
96          int numberOfColumns = columns.size();
97          int numberOfRows = dataTable.getRowCount();
98          int startFrom = 0;
99          int endAt = numberOfRows;
100 
101         /* fill the table with the data. */
102         for (int i = startFrom; i < endAt; ++i)
103         {
104             dataTable.setRowIndex(i);
105             for (int j = 0; j < numberOfColumns; ++j)
106             {
107                 String cellValue = "";
108                 UIColumn currentColumn = (UIColumn) columns.get(j);
109 
110                 for (int k = 0; k < currentColumn.getChildren().size(); ++k)
111                 {
112                     if (currentColumn.getChildren().get(k) instanceof ValueHolder)
113                     {
114                         cellValue += ((ValueHolder) currentColumn.getChildren()
115                                 .get(k)).getValue();
116                     }
117                 }
118 
119                 pdfTable.addCell(cellValue);
120             }
121         }
122     }
123 
124     /*
125      * This method is used for creating the PDFTable model.
126      */
127     public static PdfPTable generatePDFTableModel(FacesContext facesContext,
128             HtmlDataTable dataTable)
129     {
130         int numberOfColumns;
131         List columns = null;
132         PdfPTable pdfTable = null;
133 
134         /* getting the HTMLDataTable Columns */
135         columns = ComponentUtils.getHTMLDataTableColumns(dataTable);
136 
137         if (columns.size() == 0)
138         {
139             return null;
140         }
141         else
142         {
143             numberOfColumns = columns.size();
144         }
145 
146         /* creating the PDF Table */
147         pdfTable = new PdfPTable(numberOfColumns);
148 
149         generateTableHeader(pdfTable, columns);
150 
151         generateTableContent(facesContext, pdfTable, columns, dataTable);
152 
153         return pdfTable;
154     }
155 
156     /**
157      * This method is responsible for writing the PDF to the response stream.
158      * 
159      * @param facesContext
160      * @param response
161      * @param fileName
162      * @param dataTable
163      */
164     public static void generatePDF(FacesContext facesContext,
165             HttpServletResponse response, String fileName,
166             HtmlDataTable dataTable) throws Exception
167     {
168         int currentRowIndex;
169         Document document = new Document();
170         ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
171         PdfWriter.getInstance(document, byteArrayStream);
172         PdfPTable pdfTable = null;
173 
174         /*
175          * By default if the fileName is not specified, then use the table id.
176          */
177         if (fileName == null)
178         {
179             fileName = dataTable.getId();
180         }
181 
182         currentRowIndex = dataTable.getRowIndex();
183 
184         // generate the PDF table model.
185         pdfTable = generatePDFTableModel(facesContext, dataTable);
186 
187         // open the document and write the generated PDF.
188         document.open();
189         document.add(pdfTable);
190         document.close();
191 
192         // write the response headers.
193         setPDFResponseHeaders(response, byteArrayStream, fileName);
194 
195         dataTable.setRowIndex(currentRowIndex);
196 
197     }
198 }