Index: project.xml =================================================================== RCS file: /cvsroot/displaytag/displaytag-examples/project.xml,v retrieving revision 1.11 diff -u -r1.11 project.xml --- project.xml 17 Sep 2005 08:01:11 -0000 1.11 +++ project.xml 20 Oct 2005 03:51:46 -0000 @@ -61,6 +61,15 @@ + poi + poi + 2.0-final-20040126 + jar + + true + + + commons-beanutils commons-beanutils 1.7.0 @@ -119,7 +128,7 @@ itext itext - 0.99 + 1.3 jar http://prdownloads.sourceforge.net/itext/ @@ -146,7 +155,7 @@ - src/java + src/main/java src/resources Index: src/main/webapp/example-export.jsp =================================================================== RCS file: /cvsroot/displaytag/displaytag-examples/src/main/webapp/example-export.jsp,v retrieving revision 1.2 diff -u -r1.2 example-export.jsp --- src/main/webapp/example-export.jsp 11 Sep 2005 16:13:43 -0000 1.2 +++ src/main/webapp/example-export.jsp 20 Oct 2005 03:51:46 -0000 @@ -1,4 +1,4 @@ - + @@ -10,15 +10,16 @@ + - -- n.b. that this could be done via the autolink attribute, but that rather defeats the purpose :) -- + String url = ((ListObject)pageContext.findAttribute("currentRowObject")).getUrl(); - =url + Index: src/main/webapp/index.jsp =================================================================== RCS file: /cvsroot/displaytag/displaytag-examples/src/main/webapp/index.jsp,v retrieving revision 1.2 diff -u -r1.2 index.jsp --- src/main/webapp/index.jsp 11 Sep 2005 16:13:43 -0000 1.2 +++ src/main/webapp/index.jsp 20 Oct 2005 03:51:46 -0000 @@ -28,6 +28,7 @@
  • Nested tables
  • Caption and footer
  • Misc, odds and ends
  • +
  • WYSIWYG data exporting (alpha)
  • Index: src/main/webapp/css/displaytag.css =================================================================== RCS file: /cvsroot/displaytag/displaytag-examples/src/main/webapp/css/displaytag.css,v retrieving revision 1.1 diff -u -r1.1 displaytag.css --- src/main/webapp/css/displaytag.css 11 Sep 2005 16:13:43 -0000 1.1 +++ src/main/webapp/css/displaytag.css 20 Oct 2005 03:51:46 -0000 @@ -57,7 +57,7 @@ background-color: #eee; border: 1px dotted #999; padding: 2px 4px 2px 4px; - margin: -10px 0 10px 0; + margin: 2px 0 10px 0; width: 79%; } @@ -84,6 +84,10 @@ background-image: url(../img/ico_file_pdf.png); } +span.rtf { + background-image: url(../img/ico_file_rtf.png); +} + span.pagebanner { background-color: #eee; border: 1px dotted #999; Index: src/main/java/org/displaytag/sample/HssfTotalWrapper.java =================================================================== RCS file: src/main/java/org/displaytag/sample/HssfTotalWrapper.java diff -N src/main/java/org/displaytag/sample/HssfTotalWrapper.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/main/java/org/displaytag/sample/HssfTotalWrapper.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,83 @@ +/** + * Licensed under the Artistic License; you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://displaytag.sourceforge.net/license.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +package org.displaytag.sample; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.displaytag.decorator.hssf.DecoratesHssf; + +/** + * Same idea implemented in HssfTableWriter applied to decorators. + * + * @see org.displaytag.render.HssfTableWriter + * @author Jorge L. Barroso + * @version $Revision: $ ($Author: jbarroso $) + */ +public class HssfTotalWrapper extends TotalWrapperTemplate implements DecoratesHssf +{ + private HSSFSheet sheet; + private HSSFCell currentCell; + private HSSFRow currentRow; + private int colNum; + + protected void writeCityTotal(String city, double total) + { + this.writeTotal(city, total); + } + + private void writeTotal(String value, double total) + { + if (this.assertRequiredState()) + { + int rowNum = this.sheet.getLastRowNum(); + this.currentRow = this.sheet.createRow(++rowNum); + this.colNum = 0; + prepareCell();prepareCell();prepareCell(); + this.currentCell.setCellValue("------------"); + + this.currentRow = this.sheet.createRow(++rowNum); + this.colNum = 0; + prepareCell();prepareCell(); + this.currentCell.setCellValue(value + " Total:"); + prepareCell(); + this.currentCell.setCellValue(total); + } + } + + private void prepareCell() + { + this.currentCell = this.currentRow.createCell((short) this.colNum++); + this.currentCell.setEncoding(HSSFCell.ENCODING_UTF_16); + } + + protected void writeGrandTotal(double total) + { + this.writeTotal("Grand", total); + } + + public void setSheet(HSSFSheet sheet) + { + this.sheet = sheet; + } + + /** + * Asserts that the sheet property needed have been set by the client. + * + * @return true if the required properties are not null; false otherwise. + */ + private boolean assertRequiredState() + { + return this.sheet != null; + } +} Index: src/main/java/org/displaytag/sample/HtmlTotalWrapper.java =================================================================== RCS file: src/main/java/org/displaytag/sample/HtmlTotalWrapper.java diff -N src/main/java/org/displaytag/sample/HtmlTotalWrapper.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/main/java/org/displaytag/sample/HtmlTotalWrapper.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,55 @@ +/** + * Licensed under the Artistic License; you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://displaytag.sourceforge.net/license.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +package org.displaytag.sample; + +/** + * Same idea implemented in HtmlTableWriter applied to decorators. + * + * @see org.displaytag.render.HtmlTableWriter + * @author Jorge L. Barroso + * @version $Revision: $ ($Author: jbarroso $) + */ +public class HtmlTotalWrapper extends TotalWrapperTemplate +{ + /** + * Write the city in HTML. + * @param city City name. + * @param total City total. + */ + protected void writeCityTotal(String city, double total) + { + StringBuffer buffer = this.getStringBuffer(); + buffer.append("\n\n  
    "); //$NON-NLS-1$ + buffer.append("\n "); //$NON-NLS-1$ + buffer.append("\n "); //$NON-NLS-1$ + buffer.append("\n" //$NON-NLS-1$ + + city + " Total:\n"); //$NON-NLS-1$ + buffer.append(total); + buffer.append("\n \n"); //$NON-NLS-1$ + buffer.append("\n\n \n\n"); //$NON-NLS-1$ + } + + /** + * Write the table grand total in HTML. + * @param total The table grand total. + */ + protected void writeGrandTotal(double total) + { + StringBuffer buffer = this.getStringBuffer(); + buffer.append("
    "); //$NON-NLS-1$ + buffer.append(" "); //$NON-NLS-1$ + buffer.append("Grand Total:"); //$NON-NLS-1$ + buffer.append(total); + buffer.append(" "); //$NON-NLS-1$ + } +} Index: src/main/java/org/displaytag/sample/ItextTotalWrapper.java =================================================================== RCS file: src/main/java/org/displaytag/sample/ItextTotalWrapper.java diff -N src/main/java/org/displaytag/sample/ItextTotalWrapper.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/main/java/org/displaytag/sample/ItextTotalWrapper.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,144 @@ +/** + * Licensed under the Artistic License; you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://displaytag.sourceforge.net/license.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +package org.displaytag.sample; + +import org.displaytag.decorator.itext.DecoratesItext; + +import com.lowagie.text.BadElementException; +import com.lowagie.text.Cell; +import com.lowagie.text.Chunk; +import com.lowagie.text.Element; +import com.lowagie.text.Font; +import com.lowagie.text.FontFactory; +import com.lowagie.text.Table; + +/** + * Same idea implemented in ItextTableWriter applied to decorators. + * + * @see org.displaytag.render.ItextTableWriter + * @author Jorge L. Barroso + * @version $Revision: $ ($Author: jbarroso $) + */ +public class ItextTotalWrapper extends TotalWrapperTemplate implements DecoratesItext +{ + /** + * The iText table in which the totals are rendered. + */ + private Table table; + + /** + * The iText font used to render the totals. + */ + private Font font; + + /** + * Set the table required to render the totals line. + * @param table The table required to render the totals line. + * @see org.displaytag.decorator.itext.DecoratesItext#setTable(com.lowagie.text.Table) + */ + public void setTable(Table table) + { + this.table = table; + } + + /** + * Set the font required to render the totals line. + * @param font The font required to render the totals line. + * @see org.displaytag.decorator.itext.DecoratesItext#setFont(com.lowagie.text.Font) + */ + public void setFont(Font font) + { + this.font = font; + } + + /** + * Writes cell border at bottom of cell. + */ + public String startRow() + { + this.table.setDefaultCellBorder(Cell.BOTTOM); + return null; + } + + /** + * Writes the city total line. + * @param city City name. + * @param total City total. + */ + protected void writeCityTotal(String city, double total) + { + this.writeTotal(city, total); + } + + /** + * Writes the table grand total + * @param total Table grand total + */ + protected void writeGrandTotal(double total) + { + this.writeTotal("Grand", total); + } + + /** + * Writes a total line. + * @param value Total message. + * @param total Total number. + */ + private void writeTotal(String value, double total) + { + if (assertRequiredState()) + { + try + { + this.font = FontFactory.getFont(this.font.getFamilyname(), + this.font.size(), Font.BOLD, this.font.color()); + table.addCell(this.getCell("")); + table.addCell(this.getCell("")); + table.addCell(this.getCell("-------------")); + table.addCell(this.getCell("")); + //new row + table.addCell(this.getCell("")); + table.addCell(this.getCell(value + " Total:")); + table.addCell(this.getCell(total+"")); + table.addCell(this.getCell("")); + } + catch (BadElementException e) + { + } + } + } + + /** + * Obtain a cell with the given value. + * @param value Value to display in the cell. + * @return A cell with the given value. + * @throws BadElementException if an error occurs while generating the cell. + */ + private Cell getCell(String value) throws BadElementException + { + Cell cell = new Cell(new Chunk(value, this.font)); + cell.setLeading(8); + cell.setHorizontalAlignment(Element.ALIGN_LEFT); + return cell; + } + + /** + * Asserts that the table and font properties needed have been set by the client. + * + * @return true if the required properties are not null; false otherwise. + */ + private boolean assertRequiredState() + { + return this.table != null && this.font != null; + } +} Index: src/main/java/org/displaytag/sample/TotalWrapperTemplate.java =================================================================== RCS file: src/main/java/org/displaytag/sample/TotalWrapperTemplate.java diff -N src/main/java/org/displaytag/sample/TotalWrapperTemplate.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/main/java/org/displaytag/sample/TotalWrapperTemplate.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,105 @@ +/** + * Licensed under the Artistic License; you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://displaytag.sourceforge.net/license.html + * + * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ +package org.displaytag.sample; + +import java.util.List; + +import org.displaytag.decorator.TableDecorator; + +/** + * Same idea implemented in TableWriterTemplate applied to decorators. + * + * @see org.displaytag.render.TableWriterTemplate + * @author Jorge L. Barroso + * @version $Revision: $ ($Author: jbarroso $) + */ +public abstract class TotalWrapperTemplate extends TableDecorator +{ + /** + * total amount. + */ + private double grandTotal; + + /** + * total amount for city. + */ + private double cityTotal; + + /** + * Obtain the StringBuffer used to build the totals line. + */ + private StringBuffer buffer; + + /** + * After every row completes we evaluate to see if we should be drawing a new total line and summing the results + * from the previous group. + * @return String + */ + public final String finishRow() + { + int listindex = ((List) getDecoratedObject()).indexOf(this.getCurrentRowObject()); + ReportableListObject reportableObject = (ReportableListObject) this.getCurrentRowObject(); + String nextCity; + + this.cityTotal += reportableObject.getAmount(); + this.grandTotal += reportableObject.getAmount(); + + + if (listindex == ((List) getDecoratedObject()).size() - 1) + { + nextCity = "XXXXXX"; // Last row hack, it's only a demo folks... //$NON-NLS-1$ + } + else + { + nextCity = ((ReportableListObject) ((List) getDecoratedObject()).get(listindex + 1)).getCity(); + } + + this.buffer = new StringBuffer(1000); + + // City subtotals... + if (!nextCity.equals(reportableObject.getCity())) + { + writeCityTotal(reportableObject.getCity(), this.cityTotal); + this.cityTotal = 0; + } + + // Grand totals... + if (getViewIndex() == ((List) getDecoratedObject()).size() - 1) + { + writeGrandTotal(this.grandTotal); + } + + return buffer.toString(); + } + + /** + * Render the city total in the appropriate format. + * @param city The city name to render. + * @param total The city total to render. + */ + abstract protected void writeCityTotal(String city, double total); + + /** + * Render the grand total in the appropriate format. + * @param total The grand total to render. + */ + abstract protected void writeGrandTotal(double total); + + /** + * Obtain the StringBuffer used to build the totals line. + * @return The StringBuffer used to build the totals line. + */ + protected StringBuffer getStringBuffer() + { + return this.buffer; + } +} Index: src/main/webapp/example-new-export.jsp =================================================================== RCS file: src/main/webapp/example-new-export.jsp diff -N src/main/webapp/example-new-export.jsp --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/main/webapp/example-new-export.jsp 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,116 @@ + + + + + + request.setAttribute( "test", new ReportList(10) ); + +

    Examples >"What You See Is What You Get" Exports

    + + + + + + + + + + + A Caption + A Caption + + + Sample footer + + + Sample footer + + + + + + +

    +The purpose of this example is two-fold: 1) to demonstrate exports that mimic the HTML data presentation. What you +see rendered in the Excel, PDF, and RTF formats is what you see rendered as HTML, 2) to demonstrate how easy it is +to implement this by applying the template method pattern to render the main table and decorate it. Refer to the following source listings. +

    +

    +

    +Why would one want to do this? When typical business users are presented with the + displaytag export facility, they usually expect the exported Excel or PDF to + look just like the HTML in their browser; they expect a WYSIWYG rendering. Yes, even + when exporting to Excel, users tend to expect the same look, feel, and structure + of the rendered HTML, instead of raw data. +

    +

    +(Note: the model state in this example changes with every view request, such that the data shown will change +with every request, but the report's structure remains the same in all formats.) +

    +

    + What this table shows: You have a List who's objects are sorted and grouped by column A, column B and + column C, so instead of repeating columns A, B over and over again, it does a + grouping of those columns, and only shows data in those columns when it changes. + Think of reports... We use the this display tag as a key part of our + reporting framework. +

    +

    + Grouping is straight-forward, simply make sure that your list that you are + providing is sorted appropriately, then indicate the grouping + order via the group attribute of the column tags. +

    + +

    +Potential and upcoming enhancements (Exit-Alpha Features): +

      +
    1. Use css table styles as style configuration for Excel, PDF, and RTF exports. + If not practical, provide export style config properties.
    2. +
    3. Specify Excel formats for columns, e.g., ##.##.
    4. +
    5. Include smart linking in Excel, PDF, and RTF exports.
    6. +
    7. Export just the current page, a page range, or all data, especially if
    8. +
      +   paging is used.
      +   The ui may look like this:
      +
      +   Export options: Excel | PDF | RTF | From: [1] To: [1] (default to this page)
      +   Export options: Excel | PDF | RTF | From: [1] To: [max] (default to all)
      +
      +   Defaults to exporting what's on the page currently.  Default would be
      +   configurable through property.
      +
      +
    9. Set the column width to the max column string value width.
    10. +
    11. Exporters should support nested tables, at least the iText versions should, since iText supports nested tables.
    12. +
    13. Implement font styles in RTF export, e.g., bold face.
    14. +
    15. Export in MS Word format using POI
    16. +
    +

    + + + +
    Index: src/main/webapp/example-new-export.txt =================================================================== RCS file: src/main/webapp/example-new-export.txt diff -N src/main/webapp/example-new-export.txt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/main/webapp/example-new-export.txt 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,116 @@ + + + + + + request.setAttribute( "test", new ReportList(10) ); + +

    Examples >"What You See Is What You Get" Exports

    + + + + + + + + + + + A Caption + A Caption + + + Sample footer + + + Sample footer + + + + + + +

    +The purpose of this example is two-fold: 1) to demonstrate exports that mimic the HTML data presentation. What you +see rendered in the Excel, PDF, and RTF formats is what you see rendered as HTML, 2) to demonstrate how easy it is +to implement this by applying the template method pattern to render the main table and decorate it. Refer to the following source listings. +

    +

    +

    +Why would one want to do this? When typical business users are presented with the + displaytag export facility, they usually expect the exported Excel or PDF to + look just like the HTML in their browser; they expect a WYSIWYG rendering. Yes, even + when exporting to Excel, users tend to expect the same look, feel, and structure + of the rendered HTML, instead of raw data. +

    +

    +(Note: the model state in this example changes with every view request, such that the data shown will change +with every request, but the report's structure remains the same in all formats.) +

    +

    + What this table shows: You have a List who's objects are sorted and grouped by column A, column B and + column C, so instead of repeating columns A, B over and over again, it does a + grouping of those columns, and only shows data in those columns when it changes. + Think of reports... We use the this display tag as a key part of our + reporting framework. +

    +

    + Grouping is straight-forward, simply make sure that your list that you are + providing is sorted appropriately, then indicate the grouping + order via the group attribute of the column tags. +

    + +

    +Potential and upcoming enhancements (Exit-Alpha Features): +

      +
    1. Use css table styles as style configuration for Excel, PDF, and RTF exports. + If not practical, provide export style config properties.
    2. +
    3. Specify Excel formats for columns, e.g., ##.##.
    4. +
    5. Include smart linking in Excel, PDF, and RTF exports.
    6. +
    7. Export just the current page, a page range, or all data, especially if
    8. +
      +   paging is used.
      +   The ui may look like this:
      +
      +   Export options: Excel | PDF | RTF | From: [1] To: [1] (default to this page)
      +   Export options: Excel | PDF | RTF | From: [1] To: [max] (default to all)
      +
      +   Defaults to exporting what's on the page currently.  Default would be
      +   configurable through property.
      +
      +
    9. Set the column width to the max column string value width.
    10. +
    11. Exporters should support nested tables, at least the iText versions should, since iText supports nested tables.
    12. +
    13. Implement font styles in RTF export, e.g., bold face.
    14. +
    15. Export in MS Word format using POI
    16. +
    +

    + + + +
    Index: src/resources/displaytag.properties =================================================================== RCS file: src/resources/displaytag.properties diff -N src/resources/displaytag.properties --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/resources/displaytag.properties 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,17 @@ +#sort.behavior=list +#sort.amount=list +#basic.empty.showtable=true +#basic.msg.empty_list=No results matched your criteria. +#paging.banner.placement=top +#paging.banner.onepage= +export.types=csv excel xml pdf rtf +export.excel=true +export.csv=true +export.xml=true +export.pdf=true +export.rtf=true +export.excel.class=org.displaytag.export.excel.DefaultHssfExportView +export.pdf.class=org.displaytag.export.DefaultPdfExportView +export.rtf.class=org.displaytag.export.DefaultRtfExportView +# if set, file is downloaded instead of opened in the browser window +#export.[mymedia].filename=